1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // renderer_utils:
7*8975f5c5SAndroid Build Coastguard Worker // Helper methods pertaining to most or all back-ends.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/renderer_utils.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "common/base/anglebase/numerics/checked_math.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "image_util/copyimage.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "image_util/imageformats.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/AttributeMap.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.inl.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ContextImpl.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/Format.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "platform/Feature.h"
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
28*8975f5c5SAndroid Build Coastguard Worker #include <cctype>
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Worker namespace angle
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker namespace
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker // For the sake of feature name matching, underscore is ignored, and the names are matched
35*8975f5c5SAndroid Build Coastguard Worker // case-insensitive. This allows feature names to be overriden both in snake_case (previously used
36*8975f5c5SAndroid Build Coastguard Worker // by ANGLE) and camelCase. The second string (user-provided name) can end in `*` for wildcard
37*8975f5c5SAndroid Build Coastguard Worker // matching.
FeatureNameMatch(const std::string & a,const std::string & b)38*8975f5c5SAndroid Build Coastguard Worker bool FeatureNameMatch(const std::string &a, const std::string &b)
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker size_t ai = 0;
41*8975f5c5SAndroid Build Coastguard Worker size_t bi = 0;
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker while (ai < a.size() && bi < b.size())
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker if (a[ai] == '_')
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker ++ai;
48*8975f5c5SAndroid Build Coastguard Worker }
49*8975f5c5SAndroid Build Coastguard Worker if (b[bi] == '_')
50*8975f5c5SAndroid Build Coastguard Worker {
51*8975f5c5SAndroid Build Coastguard Worker ++bi;
52*8975f5c5SAndroid Build Coastguard Worker }
53*8975f5c5SAndroid Build Coastguard Worker if (b[bi] == '*' && bi + 1 == b.size())
54*8975f5c5SAndroid Build Coastguard Worker {
55*8975f5c5SAndroid Build Coastguard Worker // If selected feature name ends in wildcard, match it.
56*8975f5c5SAndroid Build Coastguard Worker return true;
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker if (std::tolower(a[ai++]) != std::tolower(b[bi++]))
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker return false;
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker
64*8975f5c5SAndroid Build Coastguard Worker return ai == a.size() && bi == b.size();
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
67*8975f5c5SAndroid Build Coastguard Worker
applyOverride(bool state)68*8975f5c5SAndroid Build Coastguard Worker void FeatureInfo::applyOverride(bool state)
69*8975f5c5SAndroid Build Coastguard Worker {
70*8975f5c5SAndroid Build Coastguard Worker enabled = state;
71*8975f5c5SAndroid Build Coastguard Worker hasOverride = true;
72*8975f5c5SAndroid Build Coastguard Worker }
73*8975f5c5SAndroid Build Coastguard Worker
74*8975f5c5SAndroid Build Coastguard Worker // FeatureSetBase implementation
reset()75*8975f5c5SAndroid Build Coastguard Worker void FeatureSetBase::reset()
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker for (auto iter : members)
78*8975f5c5SAndroid Build Coastguard Worker {
79*8975f5c5SAndroid Build Coastguard Worker FeatureInfo *feature = iter.second;
80*8975f5c5SAndroid Build Coastguard Worker feature->enabled = false;
81*8975f5c5SAndroid Build Coastguard Worker feature->hasOverride = false;
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker
overrideFeatures(const std::vector<std::string> & featureNames,bool enabled)85*8975f5c5SAndroid Build Coastguard Worker void FeatureSetBase::overrideFeatures(const std::vector<std::string> &featureNames, bool enabled)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker for (const std::string &name : featureNames)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker const bool hasWildcard = name.back() == '*';
90*8975f5c5SAndroid Build Coastguard Worker for (auto iter : members)
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker const std::string &featureName = iter.first;
93*8975f5c5SAndroid Build Coastguard Worker FeatureInfo *feature = iter.second;
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker if (!FeatureNameMatch(featureName, name))
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker continue;
98*8975f5c5SAndroid Build Coastguard Worker }
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker feature->applyOverride(enabled);
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker // If name has a wildcard, try to match it with all features. Otherwise, bail on first
103*8975f5c5SAndroid Build Coastguard Worker // match, as names are unique.
104*8975f5c5SAndroid Build Coastguard Worker if (!hasWildcard)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker break;
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker
populateFeatureList(FeatureList * features) const112*8975f5c5SAndroid Build Coastguard Worker void FeatureSetBase::populateFeatureList(FeatureList *features) const
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
115*8975f5c5SAndroid Build Coastguard Worker {
116*8975f5c5SAndroid Build Coastguard Worker features->push_back(it->second);
117*8975f5c5SAndroid Build Coastguard Worker }
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker } // namespace angle
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker namespace rx
122*8975f5c5SAndroid Build Coastguard Worker {
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker namespace
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker // Both D3D and Vulkan support the same set of standard sample positions for 1, 2, 4, 8, and 16
127*8975f5c5SAndroid Build Coastguard Worker // samples. See:
128*8975f5c5SAndroid Build Coastguard Worker //
129*8975f5c5SAndroid Build Coastguard Worker // - https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218.aspx
130*8975f5c5SAndroid Build Coastguard Worker //
131*8975f5c5SAndroid Build Coastguard Worker // -
132*8975f5c5SAndroid Build Coastguard Worker // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#primsrast-multisampling
133*8975f5c5SAndroid Build Coastguard Worker using SamplePositionsArray = std::array<float, 32>;
134*8975f5c5SAndroid Build Coastguard Worker constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
135*8975f5c5SAndroid Build Coastguard Worker {{{0.5f, 0.5f}},
136*8975f5c5SAndroid Build Coastguard Worker {{0.75f, 0.75f, 0.25f, 0.25f}},
137*8975f5c5SAndroid Build Coastguard Worker {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
138*8975f5c5SAndroid Build Coastguard Worker {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
139*8975f5c5SAndroid Build Coastguard Worker 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
140*8975f5c5SAndroid Build Coastguard Worker {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f,
141*8975f5c5SAndroid Build Coastguard Worker 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
142*8975f5c5SAndroid Build Coastguard Worker 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
143*8975f5c5SAndroid Build Coastguard Worker 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker struct IncompleteTextureParameters
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker GLenum sizedInternalFormat;
148*8975f5c5SAndroid Build Coastguard Worker GLenum format;
149*8975f5c5SAndroid Build Coastguard Worker GLenum type;
150*8975f5c5SAndroid Build Coastguard Worker GLubyte clearColor[4];
151*8975f5c5SAndroid Build Coastguard Worker };
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker // Note that for gl::SamplerFormat::Shadow, the clearColor datatype needs to be GLushort and as such
154*8975f5c5SAndroid Build Coastguard Worker // we will reinterpret GLubyte[4] as GLushort[2].
155*8975f5c5SAndroid Build Coastguard Worker constexpr angle::PackedEnumMap<gl::SamplerFormat, IncompleteTextureParameters>
156*8975f5c5SAndroid Build Coastguard Worker kIncompleteTextureParameters = {
157*8975f5c5SAndroid Build Coastguard Worker {gl::SamplerFormat::Float, {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
158*8975f5c5SAndroid Build Coastguard Worker {gl::SamplerFormat::Unsigned,
159*8975f5c5SAndroid Build Coastguard Worker {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
160*8975f5c5SAndroid Build Coastguard Worker {gl::SamplerFormat::Signed, {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, {0, 0, 0, 127}}},
161*8975f5c5SAndroid Build Coastguard Worker {gl::SamplerFormat::Shadow,
162*8975f5c5SAndroid Build Coastguard Worker {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, {0, 0, 0, 0}}}};
163*8975f5c5SAndroid Build Coastguard Worker
CopyColor(gl::ColorF * color)164*8975f5c5SAndroid Build Coastguard Worker void CopyColor(gl::ColorF *color)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker // No-op
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker
PremultiplyAlpha(gl::ColorF * color)169*8975f5c5SAndroid Build Coastguard Worker void PremultiplyAlpha(gl::ColorF *color)
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker color->red *= color->alpha;
172*8975f5c5SAndroid Build Coastguard Worker color->green *= color->alpha;
173*8975f5c5SAndroid Build Coastguard Worker color->blue *= color->alpha;
174*8975f5c5SAndroid Build Coastguard Worker }
175*8975f5c5SAndroid Build Coastguard Worker
UnmultiplyAlpha(gl::ColorF * color)176*8975f5c5SAndroid Build Coastguard Worker void UnmultiplyAlpha(gl::ColorF *color)
177*8975f5c5SAndroid Build Coastguard Worker {
178*8975f5c5SAndroid Build Coastguard Worker if (color->alpha != 0.0f)
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker float invAlpha = 1.0f / color->alpha;
181*8975f5c5SAndroid Build Coastguard Worker color->red *= invAlpha;
182*8975f5c5SAndroid Build Coastguard Worker color->green *= invAlpha;
183*8975f5c5SAndroid Build Coastguard Worker color->blue *= invAlpha;
184*8975f5c5SAndroid Build Coastguard Worker }
185*8975f5c5SAndroid Build Coastguard Worker }
186*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsR(gl::ColorF * color)187*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsR(gl::ColorF *color)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker color->green = 0.0f;
190*8975f5c5SAndroid Build Coastguard Worker color->blue = 0.0f;
191*8975f5c5SAndroid Build Coastguard Worker color->alpha = 1.0f;
192*8975f5c5SAndroid Build Coastguard Worker }
193*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsRG(gl::ColorF * color)194*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsRG(gl::ColorF *color)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker color->blue = 0.0f;
197*8975f5c5SAndroid Build Coastguard Worker color->alpha = 1.0f;
198*8975f5c5SAndroid Build Coastguard Worker }
199*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsRGB(gl::ColorF * color)200*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsRGB(gl::ColorF *color)
201*8975f5c5SAndroid Build Coastguard Worker {
202*8975f5c5SAndroid Build Coastguard Worker color->alpha = 1.0f;
203*8975f5c5SAndroid Build Coastguard Worker }
204*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsLuminance(gl::ColorF * color)205*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsLuminance(gl::ColorF *color)
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker color->alpha = 1.0f;
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsAlpha(gl::ColorF * color)210*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsAlpha(gl::ColorF *color)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker color->red = 0.0f;
213*8975f5c5SAndroid Build Coastguard Worker color->green = 0.0f;
214*8975f5c5SAndroid Build Coastguard Worker color->blue = 0.0f;
215*8975f5c5SAndroid Build Coastguard Worker }
216*8975f5c5SAndroid Build Coastguard Worker
ClipChannelsNoOp(gl::ColorF * color)217*8975f5c5SAndroid Build Coastguard Worker void ClipChannelsNoOp(gl::ColorF *color) {}
218*8975f5c5SAndroid Build Coastguard Worker
WriteUintColor(const gl::ColorF & color,PixelWriteFunction colorWriteFunction,uint8_t * destPixelData)219*8975f5c5SAndroid Build Coastguard Worker void WriteUintColor(const gl::ColorF &color,
220*8975f5c5SAndroid Build Coastguard Worker PixelWriteFunction colorWriteFunction,
221*8975f5c5SAndroid Build Coastguard Worker uint8_t *destPixelData)
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker gl::ColorUI destColor(
224*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(color.red * 255), static_cast<unsigned int>(color.green * 255),
225*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(color.blue * 255), static_cast<unsigned int>(color.alpha * 255));
226*8975f5c5SAndroid Build Coastguard Worker colorWriteFunction(reinterpret_cast<const uint8_t *>(&destColor), destPixelData);
227*8975f5c5SAndroid Build Coastguard Worker }
228*8975f5c5SAndroid Build Coastguard Worker
WriteFloatColor(const gl::ColorF & color,PixelWriteFunction colorWriteFunction,uint8_t * destPixelData)229*8975f5c5SAndroid Build Coastguard Worker void WriteFloatColor(const gl::ColorF &color,
230*8975f5c5SAndroid Build Coastguard Worker PixelWriteFunction colorWriteFunction,
231*8975f5c5SAndroid Build Coastguard Worker uint8_t *destPixelData)
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker colorWriteFunction(reinterpret_cast<const uint8_t *>(&color), destPixelData);
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker
236*8975f5c5SAndroid Build Coastguard Worker template <int cols, int rows, bool IsColumnMajor>
GetFlattenedIndex(int col,int row)237*8975f5c5SAndroid Build Coastguard Worker constexpr inline int GetFlattenedIndex(int col, int row)
238*8975f5c5SAndroid Build Coastguard Worker {
239*8975f5c5SAndroid Build Coastguard Worker if (IsColumnMajor)
240*8975f5c5SAndroid Build Coastguard Worker {
241*8975f5c5SAndroid Build Coastguard Worker return col * rows + row;
242*8975f5c5SAndroid Build Coastguard Worker }
243*8975f5c5SAndroid Build Coastguard Worker else
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker return row * cols + col;
246*8975f5c5SAndroid Build Coastguard Worker }
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker
249*8975f5c5SAndroid Build Coastguard Worker template <typename T,
250*8975f5c5SAndroid Build Coastguard Worker bool IsSrcColumnMajor,
251*8975f5c5SAndroid Build Coastguard Worker int colsSrc,
252*8975f5c5SAndroid Build Coastguard Worker int rowsSrc,
253*8975f5c5SAndroid Build Coastguard Worker bool IsDstColumnMajor,
254*8975f5c5SAndroid Build Coastguard Worker int colsDst,
255*8975f5c5SAndroid Build Coastguard Worker int rowsDst>
ExpandMatrix(T * target,const GLfloat * value)256*8975f5c5SAndroid Build Coastguard Worker void ExpandMatrix(T *target, const GLfloat *value)
257*8975f5c5SAndroid Build Coastguard Worker {
258*8975f5c5SAndroid Build Coastguard Worker static_assert(colsSrc <= colsDst && rowsSrc <= rowsDst, "Can only expand!");
259*8975f5c5SAndroid Build Coastguard Worker
260*8975f5c5SAndroid Build Coastguard Worker // Clamp the staging data's size to the last written value so that data packed just after this
261*8975f5c5SAndroid Build Coastguard Worker // matrix is not overwritten.
262*8975f5c5SAndroid Build Coastguard Worker constexpr int kDstFlatSize =
263*8975f5c5SAndroid Build Coastguard Worker GetFlattenedIndex<colsDst, rowsDst, IsDstColumnMajor>(colsSrc - 1, rowsSrc - 1) + 1;
264*8975f5c5SAndroid Build Coastguard Worker T staging[kDstFlatSize] = {0};
265*8975f5c5SAndroid Build Coastguard Worker
266*8975f5c5SAndroid Build Coastguard Worker for (int r = 0; r < rowsSrc; r++)
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker for (int c = 0; c < colsSrc; c++)
269*8975f5c5SAndroid Build Coastguard Worker {
270*8975f5c5SAndroid Build Coastguard Worker int srcIndex = GetFlattenedIndex<colsSrc, rowsSrc, IsSrcColumnMajor>(c, r);
271*8975f5c5SAndroid Build Coastguard Worker int dstIndex = GetFlattenedIndex<colsDst, rowsDst, IsDstColumnMajor>(c, r);
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker staging[dstIndex] = static_cast<T>(value[srcIndex]);
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker }
276*8975f5c5SAndroid Build Coastguard Worker
277*8975f5c5SAndroid Build Coastguard Worker memcpy(target, staging, kDstFlatSize * sizeof(T));
278*8975f5c5SAndroid Build Coastguard Worker }
279*8975f5c5SAndroid Build Coastguard Worker
280*8975f5c5SAndroid Build Coastguard Worker template <bool IsSrcColumMajor,
281*8975f5c5SAndroid Build Coastguard Worker int colsSrc,
282*8975f5c5SAndroid Build Coastguard Worker int rowsSrc,
283*8975f5c5SAndroid Build Coastguard Worker bool IsDstColumnMajor,
284*8975f5c5SAndroid Build Coastguard Worker int colsDst,
285*8975f5c5SAndroid Build Coastguard Worker int rowsDst>
SetFloatUniformMatrix(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,const GLfloat * value,uint8_t * targetData)286*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrix(unsigned int arrayElementOffset,
287*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
288*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
289*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
290*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
291*8975f5c5SAndroid Build Coastguard Worker {
292*8975f5c5SAndroid Build Coastguard Worker unsigned int count =
293*8975f5c5SAndroid Build Coastguard Worker std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
294*8975f5c5SAndroid Build Coastguard Worker
295*8975f5c5SAndroid Build Coastguard Worker const unsigned int targetMatrixStride = colsDst * rowsDst;
296*8975f5c5SAndroid Build Coastguard Worker GLfloat *target = reinterpret_cast<GLfloat *>(
297*8975f5c5SAndroid Build Coastguard Worker targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride);
298*8975f5c5SAndroid Build Coastguard Worker
299*8975f5c5SAndroid Build Coastguard Worker for (unsigned int i = 0; i < count; i++)
300*8975f5c5SAndroid Build Coastguard Worker {
301*8975f5c5SAndroid Build Coastguard Worker ExpandMatrix<GLfloat, IsSrcColumMajor, colsSrc, rowsSrc, IsDstColumnMajor, colsDst,
302*8975f5c5SAndroid Build Coastguard Worker rowsDst>(target, value);
303*8975f5c5SAndroid Build Coastguard Worker
304*8975f5c5SAndroid Build Coastguard Worker target += targetMatrixStride;
305*8975f5c5SAndroid Build Coastguard Worker value += colsSrc * rowsSrc;
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker }
308*8975f5c5SAndroid Build Coastguard Worker
SetFloatUniformMatrixFast(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,size_t matrixSize,const GLfloat * value,uint8_t * targetData)309*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrixFast(unsigned int arrayElementOffset,
310*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
311*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
312*8975f5c5SAndroid Build Coastguard Worker size_t matrixSize,
313*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
314*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
315*8975f5c5SAndroid Build Coastguard Worker {
316*8975f5c5SAndroid Build Coastguard Worker const unsigned int count =
317*8975f5c5SAndroid Build Coastguard Worker std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
318*8975f5c5SAndroid Build Coastguard Worker
319*8975f5c5SAndroid Build Coastguard Worker const uint8_t *valueData = reinterpret_cast<const uint8_t *>(value);
320*8975f5c5SAndroid Build Coastguard Worker targetData = targetData + arrayElementOffset * matrixSize;
321*8975f5c5SAndroid Build Coastguard Worker
322*8975f5c5SAndroid Build Coastguard Worker memcpy(targetData, valueData, matrixSize * count);
323*8975f5c5SAndroid Build Coastguard Worker }
324*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
325*8975f5c5SAndroid Build Coastguard Worker
IsRotatedAspectRatio(SurfaceRotation rotation)326*8975f5c5SAndroid Build Coastguard Worker bool IsRotatedAspectRatio(SurfaceRotation rotation)
327*8975f5c5SAndroid Build Coastguard Worker {
328*8975f5c5SAndroid Build Coastguard Worker switch (rotation)
329*8975f5c5SAndroid Build Coastguard Worker {
330*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
331*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
332*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::FlippedRotated90Degrees:
333*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::FlippedRotated270Degrees:
334*8975f5c5SAndroid Build Coastguard Worker return true;
335*8975f5c5SAndroid Build Coastguard Worker default:
336*8975f5c5SAndroid Build Coastguard Worker return false;
337*8975f5c5SAndroid Build Coastguard Worker }
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker
RotateRectangle(const SurfaceRotation rotation,const bool flipY,const int framebufferWidth,const int framebufferHeight,const gl::Rectangle & incoming,gl::Rectangle * outgoing)340*8975f5c5SAndroid Build Coastguard Worker void RotateRectangle(const SurfaceRotation rotation,
341*8975f5c5SAndroid Build Coastguard Worker const bool flipY,
342*8975f5c5SAndroid Build Coastguard Worker const int framebufferWidth,
343*8975f5c5SAndroid Build Coastguard Worker const int framebufferHeight,
344*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &incoming,
345*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle *outgoing)
346*8975f5c5SAndroid Build Coastguard Worker {
347*8975f5c5SAndroid Build Coastguard Worker // GLES's y-axis points up; Vulkan's points down.
348*8975f5c5SAndroid Build Coastguard Worker switch (rotation)
349*8975f5c5SAndroid Build Coastguard Worker {
350*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Identity:
351*8975f5c5SAndroid Build Coastguard Worker // Do not rotate gl_Position (surface matches the device's orientation):
352*8975f5c5SAndroid Build Coastguard Worker outgoing->x = incoming.x;
353*8975f5c5SAndroid Build Coastguard Worker outgoing->y = flipY ? framebufferHeight - incoming.y - incoming.height : incoming.y;
354*8975f5c5SAndroid Build Coastguard Worker outgoing->width = incoming.width;
355*8975f5c5SAndroid Build Coastguard Worker outgoing->height = incoming.height;
356*8975f5c5SAndroid Build Coastguard Worker break;
357*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
358*8975f5c5SAndroid Build Coastguard Worker // Rotate gl_Position 90 degrees:
359*8975f5c5SAndroid Build Coastguard Worker outgoing->x = incoming.y;
360*8975f5c5SAndroid Build Coastguard Worker outgoing->y = flipY ? incoming.x : framebufferWidth - incoming.x - incoming.width;
361*8975f5c5SAndroid Build Coastguard Worker outgoing->width = incoming.height;
362*8975f5c5SAndroid Build Coastguard Worker outgoing->height = incoming.width;
363*8975f5c5SAndroid Build Coastguard Worker break;
364*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated180Degrees:
365*8975f5c5SAndroid Build Coastguard Worker // Rotate gl_Position 180 degrees:
366*8975f5c5SAndroid Build Coastguard Worker outgoing->x = framebufferWidth - incoming.x - incoming.width;
367*8975f5c5SAndroid Build Coastguard Worker outgoing->y = flipY ? incoming.y : framebufferHeight - incoming.y - incoming.height;
368*8975f5c5SAndroid Build Coastguard Worker outgoing->width = incoming.width;
369*8975f5c5SAndroid Build Coastguard Worker outgoing->height = incoming.height;
370*8975f5c5SAndroid Build Coastguard Worker break;
371*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
372*8975f5c5SAndroid Build Coastguard Worker // Rotate gl_Position 270 degrees:
373*8975f5c5SAndroid Build Coastguard Worker outgoing->x = framebufferHeight - incoming.y - incoming.height;
374*8975f5c5SAndroid Build Coastguard Worker outgoing->y = flipY ? framebufferWidth - incoming.x - incoming.width : incoming.x;
375*8975f5c5SAndroid Build Coastguard Worker outgoing->width = incoming.height;
376*8975f5c5SAndroid Build Coastguard Worker outgoing->height = incoming.width;
377*8975f5c5SAndroid Build Coastguard Worker break;
378*8975f5c5SAndroid Build Coastguard Worker default:
379*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
380*8975f5c5SAndroid Build Coastguard Worker break;
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker }
383*8975f5c5SAndroid Build Coastguard Worker
PackPixelsParams()384*8975f5c5SAndroid Build Coastguard Worker PackPixelsParams::PackPixelsParams()
385*8975f5c5SAndroid Build Coastguard Worker : destFormat(nullptr),
386*8975f5c5SAndroid Build Coastguard Worker outputPitch(0),
387*8975f5c5SAndroid Build Coastguard Worker packBuffer(nullptr),
388*8975f5c5SAndroid Build Coastguard Worker offset(0),
389*8975f5c5SAndroid Build Coastguard Worker rotation(SurfaceRotation::Identity)
390*8975f5c5SAndroid Build Coastguard Worker {}
391*8975f5c5SAndroid Build Coastguard Worker
PackPixelsParams(const gl::Rectangle & areaIn,const angle::Format & destFormat,GLuint outputPitchIn,bool reverseRowOrderIn,gl::Buffer * packBufferIn,ptrdiff_t offsetIn)392*8975f5c5SAndroid Build Coastguard Worker PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
393*8975f5c5SAndroid Build Coastguard Worker const angle::Format &destFormat,
394*8975f5c5SAndroid Build Coastguard Worker GLuint outputPitchIn,
395*8975f5c5SAndroid Build Coastguard Worker bool reverseRowOrderIn,
396*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *packBufferIn,
397*8975f5c5SAndroid Build Coastguard Worker ptrdiff_t offsetIn)
398*8975f5c5SAndroid Build Coastguard Worker : area(areaIn),
399*8975f5c5SAndroid Build Coastguard Worker destFormat(&destFormat),
400*8975f5c5SAndroid Build Coastguard Worker outputPitch(outputPitchIn),
401*8975f5c5SAndroid Build Coastguard Worker packBuffer(packBufferIn),
402*8975f5c5SAndroid Build Coastguard Worker reverseRowOrder(reverseRowOrderIn),
403*8975f5c5SAndroid Build Coastguard Worker offset(offsetIn),
404*8975f5c5SAndroid Build Coastguard Worker rotation(SurfaceRotation::Identity)
405*8975f5c5SAndroid Build Coastguard Worker {}
406*8975f5c5SAndroid Build Coastguard Worker
PackPixels(const PackPixelsParams & params,const angle::Format & sourceFormat,int inputPitchIn,const uint8_t * sourceIn,uint8_t * destWithoutOffset)407*8975f5c5SAndroid Build Coastguard Worker void PackPixels(const PackPixelsParams ¶ms,
408*8975f5c5SAndroid Build Coastguard Worker const angle::Format &sourceFormat,
409*8975f5c5SAndroid Build Coastguard Worker int inputPitchIn,
410*8975f5c5SAndroid Build Coastguard Worker const uint8_t *sourceIn,
411*8975f5c5SAndroid Build Coastguard Worker uint8_t *destWithoutOffset)
412*8975f5c5SAndroid Build Coastguard Worker {
413*8975f5c5SAndroid Build Coastguard Worker uint8_t *destWithOffset = destWithoutOffset + params.offset;
414*8975f5c5SAndroid Build Coastguard Worker
415*8975f5c5SAndroid Build Coastguard Worker const uint8_t *source = sourceIn;
416*8975f5c5SAndroid Build Coastguard Worker int inputPitch = inputPitchIn;
417*8975f5c5SAndroid Build Coastguard Worker int destWidth = params.area.width;
418*8975f5c5SAndroid Build Coastguard Worker int destHeight = params.area.height;
419*8975f5c5SAndroid Build Coastguard Worker int xAxisPitch = 0;
420*8975f5c5SAndroid Build Coastguard Worker int yAxisPitch = 0;
421*8975f5c5SAndroid Build Coastguard Worker switch (params.rotation)
422*8975f5c5SAndroid Build Coastguard Worker {
423*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Identity:
424*8975f5c5SAndroid Build Coastguard Worker // The source image is not rotated (i.e. matches the device's orientation), and may or
425*8975f5c5SAndroid Build Coastguard Worker // may not be y-flipped. The image is row-major. Each source row (one step along the
426*8975f5c5SAndroid Build Coastguard Worker // y-axis for each step in the dest y-axis) is inputPitch past the previous row. Along
427*8975f5c5SAndroid Build Coastguard Worker // a row, each source pixel (one step along the x-axis for each step in the dest
428*8975f5c5SAndroid Build Coastguard Worker // x-axis) is sourceFormat.pixelBytes past the previous pixel.
429*8975f5c5SAndroid Build Coastguard Worker xAxisPitch = sourceFormat.pixelBytes;
430*8975f5c5SAndroid Build Coastguard Worker if (params.reverseRowOrder)
431*8975f5c5SAndroid Build Coastguard Worker {
432*8975f5c5SAndroid Build Coastguard Worker // The source image is y-flipped, which means we start at the last row, and each
433*8975f5c5SAndroid Build Coastguard Worker // source row is BEFORE the previous row.
434*8975f5c5SAndroid Build Coastguard Worker source += inputPitchIn * (params.area.height - 1);
435*8975f5c5SAndroid Build Coastguard Worker inputPitch = -inputPitch;
436*8975f5c5SAndroid Build Coastguard Worker yAxisPitch = -inputPitchIn;
437*8975f5c5SAndroid Build Coastguard Worker }
438*8975f5c5SAndroid Build Coastguard Worker else
439*8975f5c5SAndroid Build Coastguard Worker {
440*8975f5c5SAndroid Build Coastguard Worker yAxisPitch = inputPitchIn;
441*8975f5c5SAndroid Build Coastguard Worker }
442*8975f5c5SAndroid Build Coastguard Worker break;
443*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated90Degrees:
444*8975f5c5SAndroid Build Coastguard Worker // The source image is rotated 90 degrees counter-clockwise. Y-flip is always applied
445*8975f5c5SAndroid Build Coastguard Worker // to rotated images. The image is column-major. Each source column (one step along
446*8975f5c5SAndroid Build Coastguard Worker // the source x-axis for each step in the dest y-axis) is inputPitch past the previous
447*8975f5c5SAndroid Build Coastguard Worker // column. Along a column, each source pixel (one step along the y-axis for each step
448*8975f5c5SAndroid Build Coastguard Worker // in the dest x-axis) is sourceFormat.pixelBytes past the previous pixel.
449*8975f5c5SAndroid Build Coastguard Worker xAxisPitch = inputPitchIn;
450*8975f5c5SAndroid Build Coastguard Worker yAxisPitch = sourceFormat.pixelBytes;
451*8975f5c5SAndroid Build Coastguard Worker destWidth = params.area.height;
452*8975f5c5SAndroid Build Coastguard Worker destHeight = params.area.width;
453*8975f5c5SAndroid Build Coastguard Worker break;
454*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated180Degrees:
455*8975f5c5SAndroid Build Coastguard Worker // The source image is rotated 180 degrees. Y-flip is always applied to rotated
456*8975f5c5SAndroid Build Coastguard Worker // images. The image is row-major, but upside down. Each source row (one step along
457*8975f5c5SAndroid Build Coastguard Worker // the y-axis for each step in the dest y-axis) is inputPitch after the previous row.
458*8975f5c5SAndroid Build Coastguard Worker // Along a row, each source pixel (one step along the x-axis for each step in the dest
459*8975f5c5SAndroid Build Coastguard Worker // x-axis) is sourceFormat.pixelBytes BEFORE the previous pixel.
460*8975f5c5SAndroid Build Coastguard Worker xAxisPitch = -static_cast<int>(sourceFormat.pixelBytes);
461*8975f5c5SAndroid Build Coastguard Worker yAxisPitch = inputPitchIn;
462*8975f5c5SAndroid Build Coastguard Worker source += sourceFormat.pixelBytes * (params.area.width - 1);
463*8975f5c5SAndroid Build Coastguard Worker break;
464*8975f5c5SAndroid Build Coastguard Worker case SurfaceRotation::Rotated270Degrees:
465*8975f5c5SAndroid Build Coastguard Worker // The source image is rotated 270 degrees counter-clockwise (or 90 degrees clockwise).
466*8975f5c5SAndroid Build Coastguard Worker // Y-flip is always applied to rotated images. The image is column-major, where each
467*8975f5c5SAndroid Build Coastguard Worker // column (one step in the source x-axis for one step in the dest y-axis) is inputPitch
468*8975f5c5SAndroid Build Coastguard Worker // BEFORE the previous column. Along a column, each source pixel (one step along the
469*8975f5c5SAndroid Build Coastguard Worker // y-axis for each step in the dest x-axis) is sourceFormat.pixelBytes BEFORE the
470*8975f5c5SAndroid Build Coastguard Worker // previous pixel. The first pixel is at the end of the source.
471*8975f5c5SAndroid Build Coastguard Worker xAxisPitch = -inputPitchIn;
472*8975f5c5SAndroid Build Coastguard Worker yAxisPitch = -static_cast<int>(sourceFormat.pixelBytes);
473*8975f5c5SAndroid Build Coastguard Worker destWidth = params.area.height;
474*8975f5c5SAndroid Build Coastguard Worker destHeight = params.area.width;
475*8975f5c5SAndroid Build Coastguard Worker source += inputPitch * (params.area.height - 1) +
476*8975f5c5SAndroid Build Coastguard Worker sourceFormat.pixelBytes * (params.area.width - 1);
477*8975f5c5SAndroid Build Coastguard Worker break;
478*8975f5c5SAndroid Build Coastguard Worker default:
479*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
480*8975f5c5SAndroid Build Coastguard Worker break;
481*8975f5c5SAndroid Build Coastguard Worker }
482*8975f5c5SAndroid Build Coastguard Worker
483*8975f5c5SAndroid Build Coastguard Worker if (params.rotation == SurfaceRotation::Identity && sourceFormat == *params.destFormat)
484*8975f5c5SAndroid Build Coastguard Worker {
485*8975f5c5SAndroid Build Coastguard Worker // Direct copy possible
486*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < params.area.height; ++y)
487*8975f5c5SAndroid Build Coastguard Worker {
488*8975f5c5SAndroid Build Coastguard Worker memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch,
489*8975f5c5SAndroid Build Coastguard Worker params.area.width * sourceFormat.pixelBytes);
490*8975f5c5SAndroid Build Coastguard Worker }
491*8975f5c5SAndroid Build Coastguard Worker return;
492*8975f5c5SAndroid Build Coastguard Worker }
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker FastCopyFunction fastCopyFunc = sourceFormat.fastCopyFunctions.get(params.destFormat->id);
495*8975f5c5SAndroid Build Coastguard Worker
496*8975f5c5SAndroid Build Coastguard Worker if (fastCopyFunc)
497*8975f5c5SAndroid Build Coastguard Worker {
498*8975f5c5SAndroid Build Coastguard Worker // Fast copy is possible through some special function
499*8975f5c5SAndroid Build Coastguard Worker fastCopyFunc(source, xAxisPitch, yAxisPitch, destWithOffset, params.destFormat->pixelBytes,
500*8975f5c5SAndroid Build Coastguard Worker params.outputPitch, destWidth, destHeight);
501*8975f5c5SAndroid Build Coastguard Worker return;
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker
504*8975f5c5SAndroid Build Coastguard Worker PixelWriteFunction pixelWriteFunction = params.destFormat->pixelWriteFunction;
505*8975f5c5SAndroid Build Coastguard Worker ASSERT(pixelWriteFunction != nullptr);
506*8975f5c5SAndroid Build Coastguard Worker
507*8975f5c5SAndroid Build Coastguard Worker // Maximum size of any Color<T> type used.
508*8975f5c5SAndroid Build Coastguard Worker uint8_t temp[16];
509*8975f5c5SAndroid Build Coastguard Worker static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) &&
510*8975f5c5SAndroid Build Coastguard Worker sizeof(temp) >= sizeof(gl::ColorI) &&
511*8975f5c5SAndroid Build Coastguard Worker sizeof(temp) >= sizeof(angle::DepthStencil),
512*8975f5c5SAndroid Build Coastguard Worker "Unexpected size of pixel struct.");
513*8975f5c5SAndroid Build Coastguard Worker
514*8975f5c5SAndroid Build Coastguard Worker PixelReadFunction pixelReadFunction = sourceFormat.pixelReadFunction;
515*8975f5c5SAndroid Build Coastguard Worker ASSERT(pixelReadFunction != nullptr);
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker for (int y = 0; y < destHeight; ++y)
518*8975f5c5SAndroid Build Coastguard Worker {
519*8975f5c5SAndroid Build Coastguard Worker for (int x = 0; x < destWidth; ++x)
520*8975f5c5SAndroid Build Coastguard Worker {
521*8975f5c5SAndroid Build Coastguard Worker uint8_t *dest =
522*8975f5c5SAndroid Build Coastguard Worker destWithOffset + y * params.outputPitch + x * params.destFormat->pixelBytes;
523*8975f5c5SAndroid Build Coastguard Worker const uint8_t *src = source + y * yAxisPitch + x * xAxisPitch;
524*8975f5c5SAndroid Build Coastguard Worker
525*8975f5c5SAndroid Build Coastguard Worker // readFunc and writeFunc will be using the same type of color, CopyTexImage
526*8975f5c5SAndroid Build Coastguard Worker // will not allow the copy otherwise.
527*8975f5c5SAndroid Build Coastguard Worker pixelReadFunction(src, temp);
528*8975f5c5SAndroid Build Coastguard Worker pixelWriteFunction(temp, dest);
529*8975f5c5SAndroid Build Coastguard Worker }
530*8975f5c5SAndroid Build Coastguard Worker }
531*8975f5c5SAndroid Build Coastguard Worker }
532*8975f5c5SAndroid Build Coastguard Worker
GetPackPixelsParams(const gl::InternalFormat & sizedFormatInfo,GLuint outputPitch,const gl::PixelPackState & packState,gl::Buffer * packBuffer,const gl::Rectangle & area,const gl::Rectangle & clippedArea,rx::PackPixelsParams * paramsOut,GLuint * skipBytesOut)533*8975f5c5SAndroid Build Coastguard Worker angle::Result GetPackPixelsParams(const gl::InternalFormat &sizedFormatInfo,
534*8975f5c5SAndroid Build Coastguard Worker GLuint outputPitch,
535*8975f5c5SAndroid Build Coastguard Worker const gl::PixelPackState &packState,
536*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *packBuffer,
537*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &area,
538*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &clippedArea,
539*8975f5c5SAndroid Build Coastguard Worker rx::PackPixelsParams *paramsOut,
540*8975f5c5SAndroid Build Coastguard Worker GLuint *skipBytesOut)
541*8975f5c5SAndroid Build Coastguard Worker {
542*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<GLuint> checkedSkipBytes = *skipBytesOut;
543*8975f5c5SAndroid Build Coastguard Worker checkedSkipBytes += (clippedArea.x - area.x) * sizedFormatInfo.pixelBytes +
544*8975f5c5SAndroid Build Coastguard Worker (clippedArea.y - area.y) * outputPitch;
545*8975f5c5SAndroid Build Coastguard Worker if (!checkedSkipBytes.AssignIfValid(skipBytesOut))
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker
550*8975f5c5SAndroid Build Coastguard Worker angle::FormatID angleFormatID =
551*8975f5c5SAndroid Build Coastguard Worker angle::Format::InternalFormatToID(sizedFormatInfo.sizedInternalFormat);
552*8975f5c5SAndroid Build Coastguard Worker const angle::Format &angleFormat = angle::Format::Get(angleFormatID);
553*8975f5c5SAndroid Build Coastguard Worker
554*8975f5c5SAndroid Build Coastguard Worker *paramsOut = rx::PackPixelsParams(clippedArea, angleFormat, outputPitch,
555*8975f5c5SAndroid Build Coastguard Worker packState.reverseRowOrder, packBuffer, 0);
556*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
557*8975f5c5SAndroid Build Coastguard Worker }
558*8975f5c5SAndroid Build Coastguard Worker
has(angle::FormatID formatID) const559*8975f5c5SAndroid Build Coastguard Worker bool FastCopyFunctionMap::has(angle::FormatID formatID) const
560*8975f5c5SAndroid Build Coastguard Worker {
561*8975f5c5SAndroid Build Coastguard Worker return (get(formatID) != nullptr);
562*8975f5c5SAndroid Build Coastguard Worker }
563*8975f5c5SAndroid Build Coastguard Worker
564*8975f5c5SAndroid Build Coastguard Worker namespace
565*8975f5c5SAndroid Build Coastguard Worker {
566*8975f5c5SAndroid Build Coastguard Worker
getEntry(const FastCopyFunctionMap::Entry * entry,size_t numEntries,angle::FormatID formatID)567*8975f5c5SAndroid Build Coastguard Worker const FastCopyFunctionMap::Entry *getEntry(const FastCopyFunctionMap::Entry *entry,
568*8975f5c5SAndroid Build Coastguard Worker size_t numEntries,
569*8975f5c5SAndroid Build Coastguard Worker angle::FormatID formatID)
570*8975f5c5SAndroid Build Coastguard Worker {
571*8975f5c5SAndroid Build Coastguard Worker const FastCopyFunctionMap::Entry *end = entry + numEntries;
572*8975f5c5SAndroid Build Coastguard Worker while (entry != end)
573*8975f5c5SAndroid Build Coastguard Worker {
574*8975f5c5SAndroid Build Coastguard Worker if (entry->formatID == formatID)
575*8975f5c5SAndroid Build Coastguard Worker {
576*8975f5c5SAndroid Build Coastguard Worker return entry;
577*8975f5c5SAndroid Build Coastguard Worker }
578*8975f5c5SAndroid Build Coastguard Worker ++entry;
579*8975f5c5SAndroid Build Coastguard Worker }
580*8975f5c5SAndroid Build Coastguard Worker
581*8975f5c5SAndroid Build Coastguard Worker return nullptr;
582*8975f5c5SAndroid Build Coastguard Worker }
583*8975f5c5SAndroid Build Coastguard Worker
584*8975f5c5SAndroid Build Coastguard Worker } // namespace
585*8975f5c5SAndroid Build Coastguard Worker
get(angle::FormatID formatID) const586*8975f5c5SAndroid Build Coastguard Worker FastCopyFunction FastCopyFunctionMap::get(angle::FormatID formatID) const
587*8975f5c5SAndroid Build Coastguard Worker {
588*8975f5c5SAndroid Build Coastguard Worker const FastCopyFunctionMap::Entry *entry = getEntry(mData, mSize, formatID);
589*8975f5c5SAndroid Build Coastguard Worker return entry ? entry->func : nullptr;
590*8975f5c5SAndroid Build Coastguard Worker }
591*8975f5c5SAndroid Build Coastguard Worker
ShouldUseDebugLayers(const egl::AttributeMap & attribs)592*8975f5c5SAndroid Build Coastguard Worker bool ShouldUseDebugLayers(const egl::AttributeMap &attribs)
593*8975f5c5SAndroid Build Coastguard Worker {
594*8975f5c5SAndroid Build Coastguard Worker EGLAttrib debugSetting =
595*8975f5c5SAndroid Build Coastguard Worker attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE);
596*8975f5c5SAndroid Build Coastguard Worker
597*8975f5c5SAndroid Build Coastguard Worker // Prefer to enable debug layers when available.
598*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
599*8975f5c5SAndroid Build Coastguard Worker return (debugSetting != EGL_FALSE);
600*8975f5c5SAndroid Build Coastguard Worker #else
601*8975f5c5SAndroid Build Coastguard Worker return (debugSetting == EGL_TRUE);
602*8975f5c5SAndroid Build Coastguard Worker #endif // defined(ANGLE_ENABLE_ASSERTS)
603*8975f5c5SAndroid Build Coastguard Worker }
604*8975f5c5SAndroid Build Coastguard Worker
CopyImageCHROMIUM(const uint8_t * sourceData,size_t sourceRowPitch,size_t sourcePixelBytes,size_t sourceDepthPitch,PixelReadFunction pixelReadFunction,uint8_t * destData,size_t destRowPitch,size_t destPixelBytes,size_t destDepthPitch,PixelWriteFunction pixelWriteFunction,GLenum destUnsizedFormat,GLenum destComponentType,size_t width,size_t height,size_t depth,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha)605*8975f5c5SAndroid Build Coastguard Worker void CopyImageCHROMIUM(const uint8_t *sourceData,
606*8975f5c5SAndroid Build Coastguard Worker size_t sourceRowPitch,
607*8975f5c5SAndroid Build Coastguard Worker size_t sourcePixelBytes,
608*8975f5c5SAndroid Build Coastguard Worker size_t sourceDepthPitch,
609*8975f5c5SAndroid Build Coastguard Worker PixelReadFunction pixelReadFunction,
610*8975f5c5SAndroid Build Coastguard Worker uint8_t *destData,
611*8975f5c5SAndroid Build Coastguard Worker size_t destRowPitch,
612*8975f5c5SAndroid Build Coastguard Worker size_t destPixelBytes,
613*8975f5c5SAndroid Build Coastguard Worker size_t destDepthPitch,
614*8975f5c5SAndroid Build Coastguard Worker PixelWriteFunction pixelWriteFunction,
615*8975f5c5SAndroid Build Coastguard Worker GLenum destUnsizedFormat,
616*8975f5c5SAndroid Build Coastguard Worker GLenum destComponentType,
617*8975f5c5SAndroid Build Coastguard Worker size_t width,
618*8975f5c5SAndroid Build Coastguard Worker size_t height,
619*8975f5c5SAndroid Build Coastguard Worker size_t depth,
620*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
621*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
622*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha)
623*8975f5c5SAndroid Build Coastguard Worker {
624*8975f5c5SAndroid Build Coastguard Worker using ConversionFunction = void (*)(gl::ColorF *);
625*8975f5c5SAndroid Build Coastguard Worker ConversionFunction conversionFunction = CopyColor;
626*8975f5c5SAndroid Build Coastguard Worker if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha)
627*8975f5c5SAndroid Build Coastguard Worker {
628*8975f5c5SAndroid Build Coastguard Worker if (unpackPremultiplyAlpha)
629*8975f5c5SAndroid Build Coastguard Worker {
630*8975f5c5SAndroid Build Coastguard Worker conversionFunction = PremultiplyAlpha;
631*8975f5c5SAndroid Build Coastguard Worker }
632*8975f5c5SAndroid Build Coastguard Worker else
633*8975f5c5SAndroid Build Coastguard Worker {
634*8975f5c5SAndroid Build Coastguard Worker conversionFunction = UnmultiplyAlpha;
635*8975f5c5SAndroid Build Coastguard Worker }
636*8975f5c5SAndroid Build Coastguard Worker }
637*8975f5c5SAndroid Build Coastguard Worker
638*8975f5c5SAndroid Build Coastguard Worker auto clipChannelsFunction = ClipChannelsNoOp;
639*8975f5c5SAndroid Build Coastguard Worker switch (destUnsizedFormat)
640*8975f5c5SAndroid Build Coastguard Worker {
641*8975f5c5SAndroid Build Coastguard Worker case GL_RED:
642*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction = ClipChannelsR;
643*8975f5c5SAndroid Build Coastguard Worker break;
644*8975f5c5SAndroid Build Coastguard Worker case GL_RG:
645*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction = ClipChannelsRG;
646*8975f5c5SAndroid Build Coastguard Worker break;
647*8975f5c5SAndroid Build Coastguard Worker case GL_RGB:
648*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction = ClipChannelsRGB;
649*8975f5c5SAndroid Build Coastguard Worker break;
650*8975f5c5SAndroid Build Coastguard Worker case GL_LUMINANCE:
651*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction = ClipChannelsLuminance;
652*8975f5c5SAndroid Build Coastguard Worker break;
653*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
654*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction = ClipChannelsAlpha;
655*8975f5c5SAndroid Build Coastguard Worker break;
656*8975f5c5SAndroid Build Coastguard Worker }
657*8975f5c5SAndroid Build Coastguard Worker
658*8975f5c5SAndroid Build Coastguard Worker auto writeFunction = (destComponentType == GL_UNSIGNED_INT) ? WriteUintColor : WriteFloatColor;
659*8975f5c5SAndroid Build Coastguard Worker
660*8975f5c5SAndroid Build Coastguard Worker for (size_t z = 0; z < depth; z++)
661*8975f5c5SAndroid Build Coastguard Worker {
662*8975f5c5SAndroid Build Coastguard Worker for (size_t y = 0; y < height; y++)
663*8975f5c5SAndroid Build Coastguard Worker {
664*8975f5c5SAndroid Build Coastguard Worker for (size_t x = 0; x < width; x++)
665*8975f5c5SAndroid Build Coastguard Worker {
666*8975f5c5SAndroid Build Coastguard Worker const uint8_t *sourcePixelData =
667*8975f5c5SAndroid Build Coastguard Worker sourceData + y * sourceRowPitch + x * sourcePixelBytes + z * sourceDepthPitch;
668*8975f5c5SAndroid Build Coastguard Worker
669*8975f5c5SAndroid Build Coastguard Worker gl::ColorF sourceColor;
670*8975f5c5SAndroid Build Coastguard Worker pixelReadFunction(sourcePixelData, reinterpret_cast<uint8_t *>(&sourceColor));
671*8975f5c5SAndroid Build Coastguard Worker
672*8975f5c5SAndroid Build Coastguard Worker conversionFunction(&sourceColor);
673*8975f5c5SAndroid Build Coastguard Worker clipChannelsFunction(&sourceColor);
674*8975f5c5SAndroid Build Coastguard Worker
675*8975f5c5SAndroid Build Coastguard Worker size_t destY = 0;
676*8975f5c5SAndroid Build Coastguard Worker if (unpackFlipY)
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker destY += (height - 1);
679*8975f5c5SAndroid Build Coastguard Worker destY -= y;
680*8975f5c5SAndroid Build Coastguard Worker }
681*8975f5c5SAndroid Build Coastguard Worker else
682*8975f5c5SAndroid Build Coastguard Worker {
683*8975f5c5SAndroid Build Coastguard Worker destY += y;
684*8975f5c5SAndroid Build Coastguard Worker }
685*8975f5c5SAndroid Build Coastguard Worker
686*8975f5c5SAndroid Build Coastguard Worker uint8_t *destPixelData =
687*8975f5c5SAndroid Build Coastguard Worker destData + destY * destRowPitch + x * destPixelBytes + z * destDepthPitch;
688*8975f5c5SAndroid Build Coastguard Worker writeFunction(sourceColor, pixelWriteFunction, destPixelData);
689*8975f5c5SAndroid Build Coastguard Worker }
690*8975f5c5SAndroid Build Coastguard Worker }
691*8975f5c5SAndroid Build Coastguard Worker }
692*8975f5c5SAndroid Build Coastguard Worker }
693*8975f5c5SAndroid Build Coastguard Worker
694*8975f5c5SAndroid Build Coastguard Worker // IncompleteTextureSet implementation.
IncompleteTextureSet()695*8975f5c5SAndroid Build Coastguard Worker IncompleteTextureSet::IncompleteTextureSet() {}
696*8975f5c5SAndroid Build Coastguard Worker
~IncompleteTextureSet()697*8975f5c5SAndroid Build Coastguard Worker IncompleteTextureSet::~IncompleteTextureSet() {}
698*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)699*8975f5c5SAndroid Build Coastguard Worker void IncompleteTextureSet::onDestroy(const gl::Context *context)
700*8975f5c5SAndroid Build Coastguard Worker {
701*8975f5c5SAndroid Build Coastguard Worker // Clear incomplete textures.
702*8975f5c5SAndroid Build Coastguard Worker for (auto &incompleteTextures : mIncompleteTextures)
703*8975f5c5SAndroid Build Coastguard Worker {
704*8975f5c5SAndroid Build Coastguard Worker for (auto &incompleteTexture : incompleteTextures)
705*8975f5c5SAndroid Build Coastguard Worker {
706*8975f5c5SAndroid Build Coastguard Worker if (incompleteTexture.get() != nullptr)
707*8975f5c5SAndroid Build Coastguard Worker {
708*8975f5c5SAndroid Build Coastguard Worker incompleteTexture->onDestroy(context);
709*8975f5c5SAndroid Build Coastguard Worker incompleteTexture.set(context, nullptr);
710*8975f5c5SAndroid Build Coastguard Worker }
711*8975f5c5SAndroid Build Coastguard Worker }
712*8975f5c5SAndroid Build Coastguard Worker }
713*8975f5c5SAndroid Build Coastguard Worker }
714*8975f5c5SAndroid Build Coastguard Worker
getIncompleteTexture(const gl::Context * context,gl::TextureType type,gl::SamplerFormat format,MultisampleTextureInitializer * multisampleInitializer,gl::Texture ** textureOut)715*8975f5c5SAndroid Build Coastguard Worker angle::Result IncompleteTextureSet::getIncompleteTexture(
716*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
717*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
718*8975f5c5SAndroid Build Coastguard Worker gl::SamplerFormat format,
719*8975f5c5SAndroid Build Coastguard Worker MultisampleTextureInitializer *multisampleInitializer,
720*8975f5c5SAndroid Build Coastguard Worker gl::Texture **textureOut)
721*8975f5c5SAndroid Build Coastguard Worker {
722*8975f5c5SAndroid Build Coastguard Worker *textureOut = mIncompleteTextures[format][type].get();
723*8975f5c5SAndroid Build Coastguard Worker if (*textureOut != nullptr)
724*8975f5c5SAndroid Build Coastguard Worker {
725*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
726*8975f5c5SAndroid Build Coastguard Worker }
727*8975f5c5SAndroid Build Coastguard Worker
728*8975f5c5SAndroid Build Coastguard Worker ContextImpl *implFactory = context->getImplementation();
729*8975f5c5SAndroid Build Coastguard Worker
730*8975f5c5SAndroid Build Coastguard Worker gl::Extents colorSize(1, 1, 1);
731*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState unpack;
732*8975f5c5SAndroid Build Coastguard Worker unpack.alignment = 1;
733*8975f5c5SAndroid Build Coastguard Worker gl::Box area(0, 0, 0, 1, 1, 1);
734*8975f5c5SAndroid Build Coastguard Worker const IncompleteTextureParameters &incompleteTextureParam =
735*8975f5c5SAndroid Build Coastguard Worker kIncompleteTextureParameters[format];
736*8975f5c5SAndroid Build Coastguard Worker
737*8975f5c5SAndroid Build Coastguard Worker // Cube map arrays are expected to have layer counts that are multiples of 6
738*8975f5c5SAndroid Build Coastguard Worker constexpr int kCubeMapArraySize = 6;
739*8975f5c5SAndroid Build Coastguard Worker if (type == gl::TextureType::CubeMapArray)
740*8975f5c5SAndroid Build Coastguard Worker {
741*8975f5c5SAndroid Build Coastguard Worker // From the GLES 3.2 spec:
742*8975f5c5SAndroid Build Coastguard Worker // 8.18. IMMUTABLE-FORMAT TEXTURE IMAGES
743*8975f5c5SAndroid Build Coastguard Worker // TexStorage3D Errors
744*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated if any of the following conditions hold:
745*8975f5c5SAndroid Build Coastguard Worker // * target is TEXTURE_CUBE_MAP_ARRAY and depth is not a multiple of 6
746*8975f5c5SAndroid Build Coastguard Worker // Since ANGLE treats incomplete textures as immutable, respect that here.
747*8975f5c5SAndroid Build Coastguard Worker colorSize.depth = kCubeMapArraySize;
748*8975f5c5SAndroid Build Coastguard Worker area.depth = kCubeMapArraySize;
749*8975f5c5SAndroid Build Coastguard Worker }
750*8975f5c5SAndroid Build Coastguard Worker
751*8975f5c5SAndroid Build Coastguard Worker // If a texture is external use a 2D texture for the incomplete texture
752*8975f5c5SAndroid Build Coastguard Worker gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type;
753*8975f5c5SAndroid Build Coastguard Worker
754*8975f5c5SAndroid Build Coastguard Worker gl::Texture *tex =
755*8975f5c5SAndroid Build Coastguard Worker new gl::Texture(implFactory, {std::numeric_limits<GLuint>::max()}, createType);
756*8975f5c5SAndroid Build Coastguard Worker angle::UniqueObjectPointer<gl::Texture, gl::Context> t(tex, context);
757*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *incompleteTextureBufferAttachment = nullptr;
758*8975f5c5SAndroid Build Coastguard Worker
759*8975f5c5SAndroid Build Coastguard Worker // This is a bit of a kludge but is necessary to consume the error.
760*8975f5c5SAndroid Build Coastguard Worker gl::Context *mutableContext = const_cast<gl::Context *>(context);
761*8975f5c5SAndroid Build Coastguard Worker
762*8975f5c5SAndroid Build Coastguard Worker if (createType == gl::TextureType::Buffer)
763*8975f5c5SAndroid Build Coastguard Worker {
764*8975f5c5SAndroid Build Coastguard Worker constexpr uint32_t kBufferInitData = 0;
765*8975f5c5SAndroid Build Coastguard Worker incompleteTextureBufferAttachment =
766*8975f5c5SAndroid Build Coastguard Worker new gl::Buffer(implFactory, {std::numeric_limits<GLuint>::max()});
767*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(incompleteTextureBufferAttachment->bufferData(
768*8975f5c5SAndroid Build Coastguard Worker mutableContext, gl::BufferBinding::Texture, &kBufferInitData, sizeof(kBufferInitData),
769*8975f5c5SAndroid Build Coastguard Worker gl::BufferUsage::StaticDraw));
770*8975f5c5SAndroid Build Coastguard Worker }
771*8975f5c5SAndroid Build Coastguard Worker else if (createType == gl::TextureType::_2DMultisample)
772*8975f5c5SAndroid Build Coastguard Worker {
773*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setStorageMultisample(mutableContext, createType, 1,
774*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.sizedInternalFormat, colorSize,
775*8975f5c5SAndroid Build Coastguard Worker true));
776*8975f5c5SAndroid Build Coastguard Worker }
777*8975f5c5SAndroid Build Coastguard Worker else
778*8975f5c5SAndroid Build Coastguard Worker {
779*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setStorage(mutableContext, createType, 1,
780*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.sizedInternalFormat, colorSize));
781*8975f5c5SAndroid Build Coastguard Worker }
782*8975f5c5SAndroid Build Coastguard Worker t->markInternalIncompleteTexture();
783*8975f5c5SAndroid Build Coastguard Worker
784*8975f5c5SAndroid Build Coastguard Worker if (type == gl::TextureType::CubeMap)
785*8975f5c5SAndroid Build Coastguard Worker {
786*8975f5c5SAndroid Build Coastguard Worker for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
787*8975f5c5SAndroid Build Coastguard Worker {
788*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area,
789*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.format, incompleteTextureParam.type,
790*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.clearColor));
791*8975f5c5SAndroid Build Coastguard Worker }
792*8975f5c5SAndroid Build Coastguard Worker }
793*8975f5c5SAndroid Build Coastguard Worker else if (type == gl::TextureType::CubeMapArray)
794*8975f5c5SAndroid Build Coastguard Worker {
795*8975f5c5SAndroid Build Coastguard Worker // We need to provide enough pixel data to fill the array of six faces
796*8975f5c5SAndroid Build Coastguard Worker GLubyte incompleteCubeArrayPixels[kCubeMapArraySize][4];
797*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < kCubeMapArraySize; ++i)
798*8975f5c5SAndroid Build Coastguard Worker {
799*8975f5c5SAndroid Build Coastguard Worker incompleteCubeArrayPixels[i][0] = incompleteTextureParam.clearColor[0];
800*8975f5c5SAndroid Build Coastguard Worker incompleteCubeArrayPixels[i][1] = incompleteTextureParam.clearColor[1];
801*8975f5c5SAndroid Build Coastguard Worker incompleteCubeArrayPixels[i][2] = incompleteTextureParam.clearColor[2];
802*8975f5c5SAndroid Build Coastguard Worker incompleteCubeArrayPixels[i][3] = incompleteTextureParam.clearColor[3];
803*8975f5c5SAndroid Build Coastguard Worker }
804*8975f5c5SAndroid Build Coastguard Worker
805*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
806*8975f5c5SAndroid Build Coastguard Worker gl::NonCubeTextureTypeToTarget(createType), 0, area,
807*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.format, incompleteTextureParam.type,
808*8975f5c5SAndroid Build Coastguard Worker *incompleteCubeArrayPixels));
809*8975f5c5SAndroid Build Coastguard Worker }
810*8975f5c5SAndroid Build Coastguard Worker else if (type == gl::TextureType::_2DMultisample)
811*8975f5c5SAndroid Build Coastguard Worker {
812*8975f5c5SAndroid Build Coastguard Worker // Call a specialized clear function to init a multisample texture.
813*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(multisampleInitializer->initializeMultisampleTextureToBlack(context, t.get()));
814*8975f5c5SAndroid Build Coastguard Worker }
815*8975f5c5SAndroid Build Coastguard Worker else if (type == gl::TextureType::Buffer)
816*8975f5c5SAndroid Build Coastguard Worker {
817*8975f5c5SAndroid Build Coastguard Worker ASSERT(incompleteTextureBufferAttachment != nullptr);
818*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setBuffer(context, incompleteTextureBufferAttachment,
819*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.sizedInternalFormat));
820*8975f5c5SAndroid Build Coastguard Worker }
821*8975f5c5SAndroid Build Coastguard Worker else
822*8975f5c5SAndroid Build Coastguard Worker {
823*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
824*8975f5c5SAndroid Build Coastguard Worker gl::NonCubeTextureTypeToTarget(createType), 0, area,
825*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.format, incompleteTextureParam.type,
826*8975f5c5SAndroid Build Coastguard Worker incompleteTextureParam.clearColor));
827*8975f5c5SAndroid Build Coastguard Worker }
828*8975f5c5SAndroid Build Coastguard Worker
829*8975f5c5SAndroid Build Coastguard Worker if (format == gl::SamplerFormat::Shadow)
830*8975f5c5SAndroid Build Coastguard Worker {
831*8975f5c5SAndroid Build Coastguard Worker // To avoid the undefined spec behavior for shadow samplers with a depth texture, we set the
832*8975f5c5SAndroid Build Coastguard Worker // compare mode to GL_COMPARE_REF_TO_TEXTURE
833*8975f5c5SAndroid Build Coastguard Worker ASSERT(!t->hasObservers());
834*8975f5c5SAndroid Build Coastguard Worker t->setCompareMode(context, GL_COMPARE_REF_TO_TEXTURE);
835*8975f5c5SAndroid Build Coastguard Worker }
836*8975f5c5SAndroid Build Coastguard Worker
837*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(t->syncState(context, gl::Command::Other));
838*8975f5c5SAndroid Build Coastguard Worker
839*8975f5c5SAndroid Build Coastguard Worker mIncompleteTextures[format][type].set(context, t.release());
840*8975f5c5SAndroid Build Coastguard Worker *textureOut = mIncompleteTextures[format][type].get();
841*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
842*8975f5c5SAndroid Build Coastguard Worker }
843*8975f5c5SAndroid Build Coastguard Worker
844*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
845*8975f5c5SAndroid Build Coastguard Worker template void SetFloatUniformMatrix##api<cols, rows>::Run( \
846*8975f5c5SAndroid Build Coastguard Worker unsigned int, unsigned int, GLsizei, GLboolean, const GLfloat *, uint8_t *)
847*8975f5c5SAndroid Build Coastguard Worker
848*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 2);
849*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 3);
850*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 3);
851*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 2);
852*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 2);
853*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 3);
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 2);
856*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 3);
857*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 3);
858*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 2);
859*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 4);
860*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 4);
861*8975f5c5SAndroid Build Coastguard Worker
862*8975f5c5SAndroid Build Coastguard Worker #undef ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC
863*8975f5c5SAndroid Build Coastguard Worker
864*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
865*8975f5c5SAndroid Build Coastguard Worker template void SetFloatUniformMatrix##api<cols, 4>::Run(unsigned int, unsigned int, GLsizei, \
866*8975f5c5SAndroid Build Coastguard Worker GLboolean, const GLfloat *, uint8_t *)
867*8975f5c5SAndroid Build Coastguard Worker
868*8975f5c5SAndroid Build Coastguard Worker template <int cols>
869*8975f5c5SAndroid Build Coastguard Worker struct SetFloatUniformMatrixGLSL<cols, 4>
870*8975f5c5SAndroid Build Coastguard Worker {
871*8975f5c5SAndroid Build Coastguard Worker static void Run(unsigned int arrayElementOffset,
872*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
873*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
874*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
875*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
876*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData);
877*8975f5c5SAndroid Build Coastguard Worker };
878*8975f5c5SAndroid Build Coastguard Worker
879*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 4);
880*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 4);
881*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 4);
882*8975f5c5SAndroid Build Coastguard Worker
883*8975f5c5SAndroid Build Coastguard Worker #undef ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC
884*8975f5c5SAndroid Build Coastguard Worker
885*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
886*8975f5c5SAndroid Build Coastguard Worker template void SetFloatUniformMatrix##api<4, rows>::Run(unsigned int, unsigned int, GLsizei, \
887*8975f5c5SAndroid Build Coastguard Worker GLboolean, const GLfloat *, uint8_t *)
888*8975f5c5SAndroid Build Coastguard Worker
889*8975f5c5SAndroid Build Coastguard Worker template <int rows>
890*8975f5c5SAndroid Build Coastguard Worker struct SetFloatUniformMatrixHLSL<4, rows>
891*8975f5c5SAndroid Build Coastguard Worker {
892*8975f5c5SAndroid Build Coastguard Worker static void Run(unsigned int arrayElementOffset,
893*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
894*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
895*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
896*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
897*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData);
898*8975f5c5SAndroid Build Coastguard Worker };
899*8975f5c5SAndroid Build Coastguard Worker
900*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 2);
901*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 3);
902*8975f5c5SAndroid Build Coastguard Worker ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 4);
903*8975f5c5SAndroid Build Coastguard Worker
904*8975f5c5SAndroid Build Coastguard Worker #undef ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC
905*8975f5c5SAndroid Build Coastguard Worker
906*8975f5c5SAndroid Build Coastguard Worker template <int cols>
Run(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,GLboolean transpose,const GLfloat * value,uint8_t * targetData)907*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrixGLSL<cols, 4>::Run(unsigned int arrayElementOffset,
908*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
909*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
910*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
911*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
912*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
913*8975f5c5SAndroid Build Coastguard Worker {
914*8975f5c5SAndroid Build Coastguard Worker const bool isSrcColumnMajor = !transpose;
915*8975f5c5SAndroid Build Coastguard Worker if (isSrcColumnMajor)
916*8975f5c5SAndroid Build Coastguard Worker {
917*8975f5c5SAndroid Build Coastguard Worker // Both src and dst matrixs are has same layout,
918*8975f5c5SAndroid Build Coastguard Worker // a single memcpy updates all the matrices
919*8975f5c5SAndroid Build Coastguard Worker constexpr size_t srcMatrixSize = sizeof(GLfloat) * cols * 4;
920*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value,
921*8975f5c5SAndroid Build Coastguard Worker targetData);
922*8975f5c5SAndroid Build Coastguard Worker }
923*8975f5c5SAndroid Build Coastguard Worker else
924*8975f5c5SAndroid Build Coastguard Worker {
925*8975f5c5SAndroid Build Coastguard Worker // fallback to general cases
926*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<false, cols, 4, true, cols, 4>(arrayElementOffset, elementCount,
927*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
928*8975f5c5SAndroid Build Coastguard Worker }
929*8975f5c5SAndroid Build Coastguard Worker }
930*8975f5c5SAndroid Build Coastguard Worker
931*8975f5c5SAndroid Build Coastguard Worker template <int cols, int rows>
Run(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,GLboolean transpose,const GLfloat * value,uint8_t * targetData)932*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrixGLSL<cols, rows>::Run(unsigned int arrayElementOffset,
933*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
934*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
935*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
936*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
937*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
938*8975f5c5SAndroid Build Coastguard Worker {
939*8975f5c5SAndroid Build Coastguard Worker const bool isSrcColumnMajor = !transpose;
940*8975f5c5SAndroid Build Coastguard Worker // GLSL expects matrix uniforms to be column-major, and each column is padded to 4 rows.
941*8975f5c5SAndroid Build Coastguard Worker if (isSrcColumnMajor)
942*8975f5c5SAndroid Build Coastguard Worker {
943*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<true, cols, rows, true, cols, 4>(arrayElementOffset, elementCount,
944*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
945*8975f5c5SAndroid Build Coastguard Worker }
946*8975f5c5SAndroid Build Coastguard Worker else
947*8975f5c5SAndroid Build Coastguard Worker {
948*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<false, cols, rows, true, cols, 4>(arrayElementOffset, elementCount,
949*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
950*8975f5c5SAndroid Build Coastguard Worker }
951*8975f5c5SAndroid Build Coastguard Worker }
952*8975f5c5SAndroid Build Coastguard Worker
953*8975f5c5SAndroid Build Coastguard Worker template <int rows>
Run(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,GLboolean transpose,const GLfloat * value,uint8_t * targetData)954*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrixHLSL<4, rows>::Run(unsigned int arrayElementOffset,
955*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
956*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
957*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
958*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
959*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
960*8975f5c5SAndroid Build Coastguard Worker {
961*8975f5c5SAndroid Build Coastguard Worker const bool isSrcColumnMajor = !transpose;
962*8975f5c5SAndroid Build Coastguard Worker if (!isSrcColumnMajor)
963*8975f5c5SAndroid Build Coastguard Worker {
964*8975f5c5SAndroid Build Coastguard Worker // Both src and dst matrixs are has same layout,
965*8975f5c5SAndroid Build Coastguard Worker // a single memcpy updates all the matrices
966*8975f5c5SAndroid Build Coastguard Worker constexpr size_t srcMatrixSize = sizeof(GLfloat) * 4 * rows;
967*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value,
968*8975f5c5SAndroid Build Coastguard Worker targetData);
969*8975f5c5SAndroid Build Coastguard Worker }
970*8975f5c5SAndroid Build Coastguard Worker else
971*8975f5c5SAndroid Build Coastguard Worker {
972*8975f5c5SAndroid Build Coastguard Worker // fallback to general cases
973*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<true, 4, rows, false, 4, rows>(arrayElementOffset, elementCount,
974*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
975*8975f5c5SAndroid Build Coastguard Worker }
976*8975f5c5SAndroid Build Coastguard Worker }
977*8975f5c5SAndroid Build Coastguard Worker
978*8975f5c5SAndroid Build Coastguard Worker template <int cols, int rows>
Run(unsigned int arrayElementOffset,unsigned int elementCount,GLsizei countIn,GLboolean transpose,const GLfloat * value,uint8_t * targetData)979*8975f5c5SAndroid Build Coastguard Worker void SetFloatUniformMatrixHLSL<cols, rows>::Run(unsigned int arrayElementOffset,
980*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount,
981*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
982*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
983*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
984*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetData)
985*8975f5c5SAndroid Build Coastguard Worker {
986*8975f5c5SAndroid Build Coastguard Worker const bool isSrcColumnMajor = !transpose;
987*8975f5c5SAndroid Build Coastguard Worker // Internally store matrices as row-major to accomodate HLSL matrix indexing. Each row is
988*8975f5c5SAndroid Build Coastguard Worker // padded to 4 columns.
989*8975f5c5SAndroid Build Coastguard Worker if (!isSrcColumnMajor)
990*8975f5c5SAndroid Build Coastguard Worker {
991*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<false, cols, rows, false, 4, rows>(arrayElementOffset, elementCount,
992*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
993*8975f5c5SAndroid Build Coastguard Worker }
994*8975f5c5SAndroid Build Coastguard Worker else
995*8975f5c5SAndroid Build Coastguard Worker {
996*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrix<true, cols, rows, false, 4, rows>(arrayElementOffset, elementCount,
997*8975f5c5SAndroid Build Coastguard Worker countIn, value, targetData);
998*8975f5c5SAndroid Build Coastguard Worker }
999*8975f5c5SAndroid Build Coastguard Worker }
1000*8975f5c5SAndroid Build Coastguard Worker
1001*8975f5c5SAndroid Build Coastguard Worker template void GetMatrixUniform<GLint>(GLenum, GLint *, const GLint *, bool);
1002*8975f5c5SAndroid Build Coastguard Worker template void GetMatrixUniform<GLuint>(GLenum, GLuint *, const GLuint *, bool);
1003*8975f5c5SAndroid Build Coastguard Worker
GetMatrixUniform(GLenum type,GLfloat * dataOut,const GLfloat * source,bool transpose)1004*8975f5c5SAndroid Build Coastguard Worker void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose)
1005*8975f5c5SAndroid Build Coastguard Worker {
1006*8975f5c5SAndroid Build Coastguard Worker int columns = gl::VariableColumnCount(type);
1007*8975f5c5SAndroid Build Coastguard Worker int rows = gl::VariableRowCount(type);
1008*8975f5c5SAndroid Build Coastguard Worker for (GLint col = 0; col < columns; ++col)
1009*8975f5c5SAndroid Build Coastguard Worker {
1010*8975f5c5SAndroid Build Coastguard Worker for (GLint row = 0; row < rows; ++row)
1011*8975f5c5SAndroid Build Coastguard Worker {
1012*8975f5c5SAndroid Build Coastguard Worker GLfloat *outptr = dataOut + ((col * rows) + row);
1013*8975f5c5SAndroid Build Coastguard Worker const GLfloat *inptr =
1014*8975f5c5SAndroid Build Coastguard Worker transpose ? source + ((row * 4) + col) : source + ((col * 4) + row);
1015*8975f5c5SAndroid Build Coastguard Worker *outptr = *inptr;
1016*8975f5c5SAndroid Build Coastguard Worker }
1017*8975f5c5SAndroid Build Coastguard Worker }
1018*8975f5c5SAndroid Build Coastguard Worker }
1019*8975f5c5SAndroid Build Coastguard Worker
1020*8975f5c5SAndroid Build Coastguard Worker template <typename NonFloatT>
GetMatrixUniform(GLenum type,NonFloatT * dataOut,const NonFloatT * source,bool transpose)1021*8975f5c5SAndroid Build Coastguard Worker void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose)
1022*8975f5c5SAndroid Build Coastguard Worker {
1023*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1024*8975f5c5SAndroid Build Coastguard Worker }
1025*8975f5c5SAndroid Build Coastguard Worker
1026*8975f5c5SAndroid Build Coastguard Worker BufferAndLayout::BufferAndLayout() = default;
1027*8975f5c5SAndroid Build Coastguard Worker
1028*8975f5c5SAndroid Build Coastguard Worker BufferAndLayout::~BufferAndLayout() = default;
1029*8975f5c5SAndroid Build Coastguard Worker
1030*8975f5c5SAndroid Build Coastguard Worker template <typename T>
UpdateBufferWithLayout(GLsizei count,uint32_t arrayIndex,int componentCount,const T * v,const sh::BlockMemberInfo & layoutInfo,angle::MemoryBuffer * uniformData)1031*8975f5c5SAndroid Build Coastguard Worker void UpdateBufferWithLayout(GLsizei count,
1032*8975f5c5SAndroid Build Coastguard Worker uint32_t arrayIndex,
1033*8975f5c5SAndroid Build Coastguard Worker int componentCount,
1034*8975f5c5SAndroid Build Coastguard Worker const T *v,
1035*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo,
1036*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *uniformData)
1037*8975f5c5SAndroid Build Coastguard Worker {
1038*8975f5c5SAndroid Build Coastguard Worker const int elementSize = sizeof(T) * componentCount;
1039*8975f5c5SAndroid Build Coastguard Worker
1040*8975f5c5SAndroid Build Coastguard Worker uint8_t *dst = uniformData->data() + layoutInfo.offset;
1041*8975f5c5SAndroid Build Coastguard Worker if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
1042*8975f5c5SAndroid Build Coastguard Worker {
1043*8975f5c5SAndroid Build Coastguard Worker uint32_t arrayOffset = arrayIndex * layoutInfo.arrayStride;
1044*8975f5c5SAndroid Build Coastguard Worker uint8_t *writePtr = dst + arrayOffset;
1045*8975f5c5SAndroid Build Coastguard Worker ASSERT(writePtr + (elementSize * count) <= uniformData->data() + uniformData->size());
1046*8975f5c5SAndroid Build Coastguard Worker memcpy(writePtr, v, elementSize * count);
1047*8975f5c5SAndroid Build Coastguard Worker }
1048*8975f5c5SAndroid Build Coastguard Worker else
1049*8975f5c5SAndroid Build Coastguard Worker {
1050*8975f5c5SAndroid Build Coastguard Worker // Have to respect the arrayStride between each element of the array.
1051*8975f5c5SAndroid Build Coastguard Worker int maxIndex = arrayIndex + count;
1052*8975f5c5SAndroid Build Coastguard Worker for (int writeIndex = arrayIndex, readIndex = 0; writeIndex < maxIndex;
1053*8975f5c5SAndroid Build Coastguard Worker writeIndex++, readIndex++)
1054*8975f5c5SAndroid Build Coastguard Worker {
1055*8975f5c5SAndroid Build Coastguard Worker const int arrayOffset = writeIndex * layoutInfo.arrayStride;
1056*8975f5c5SAndroid Build Coastguard Worker uint8_t *writePtr = dst + arrayOffset;
1057*8975f5c5SAndroid Build Coastguard Worker const T *readPtr = v + (readIndex * componentCount);
1058*8975f5c5SAndroid Build Coastguard Worker ASSERT(writePtr + elementSize <= uniformData->data() + uniformData->size());
1059*8975f5c5SAndroid Build Coastguard Worker memcpy(writePtr, readPtr, elementSize);
1060*8975f5c5SAndroid Build Coastguard Worker }
1061*8975f5c5SAndroid Build Coastguard Worker }
1062*8975f5c5SAndroid Build Coastguard Worker }
1063*8975f5c5SAndroid Build Coastguard Worker
1064*8975f5c5SAndroid Build Coastguard Worker template <typename T>
ReadFromBufferWithLayout(int componentCount,uint32_t arrayIndex,T * dst,const sh::BlockMemberInfo & layoutInfo,const angle::MemoryBuffer * uniformData)1065*8975f5c5SAndroid Build Coastguard Worker void ReadFromBufferWithLayout(int componentCount,
1066*8975f5c5SAndroid Build Coastguard Worker uint32_t arrayIndex,
1067*8975f5c5SAndroid Build Coastguard Worker T *dst,
1068*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo,
1069*8975f5c5SAndroid Build Coastguard Worker const angle::MemoryBuffer *uniformData)
1070*8975f5c5SAndroid Build Coastguard Worker {
1071*8975f5c5SAndroid Build Coastguard Worker ASSERT(layoutInfo.offset != -1);
1072*8975f5c5SAndroid Build Coastguard Worker
1073*8975f5c5SAndroid Build Coastguard Worker const int elementSize = sizeof(T) * componentCount;
1074*8975f5c5SAndroid Build Coastguard Worker const uint8_t *source = uniformData->data() + layoutInfo.offset;
1075*8975f5c5SAndroid Build Coastguard Worker
1076*8975f5c5SAndroid Build Coastguard Worker if (layoutInfo.arrayStride == 0 || layoutInfo.arrayStride == elementSize)
1077*8975f5c5SAndroid Build Coastguard Worker {
1078*8975f5c5SAndroid Build Coastguard Worker const uint8_t *readPtr = source + arrayIndex * layoutInfo.arrayStride;
1079*8975f5c5SAndroid Build Coastguard Worker memcpy(dst, readPtr, elementSize);
1080*8975f5c5SAndroid Build Coastguard Worker }
1081*8975f5c5SAndroid Build Coastguard Worker else
1082*8975f5c5SAndroid Build Coastguard Worker {
1083*8975f5c5SAndroid Build Coastguard Worker // Have to respect the arrayStride between each element of the array.
1084*8975f5c5SAndroid Build Coastguard Worker const int arrayOffset = arrayIndex * layoutInfo.arrayStride;
1085*8975f5c5SAndroid Build Coastguard Worker const uint8_t *readPtr = source + arrayOffset;
1086*8975f5c5SAndroid Build Coastguard Worker memcpy(dst, readPtr, elementSize);
1087*8975f5c5SAndroid Build Coastguard Worker }
1088*8975f5c5SAndroid Build Coastguard Worker }
1089*8975f5c5SAndroid Build Coastguard Worker
1090*8975f5c5SAndroid Build Coastguard Worker template <typename T>
SetUniform(const gl::ProgramExecutable * executable,GLint location,GLsizei count,const T * v,GLenum entryPointType,DefaultUniformBlockMap * defaultUniformBlocks,gl::ShaderBitSet * defaultUniformBlocksDirty)1091*8975f5c5SAndroid Build Coastguard Worker void SetUniform(const gl::ProgramExecutable *executable,
1092*8975f5c5SAndroid Build Coastguard Worker GLint location,
1093*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
1094*8975f5c5SAndroid Build Coastguard Worker const T *v,
1095*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1096*8975f5c5SAndroid Build Coastguard Worker DefaultUniformBlockMap *defaultUniformBlocks,
1097*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty)
1098*8975f5c5SAndroid Build Coastguard Worker {
1099*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = executable->getUniformLocations()[location];
1100*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &linkedUniform = executable->getUniforms()[locationInfo.index];
1101*8975f5c5SAndroid Build Coastguard Worker
1102*8975f5c5SAndroid Build Coastguard Worker ASSERT(!linkedUniform.isSampler());
1103*8975f5c5SAndroid Build Coastguard Worker
1104*8975f5c5SAndroid Build Coastguard Worker if (linkedUniform.getType() == entryPointType)
1105*8975f5c5SAndroid Build Coastguard Worker {
1106*8975f5c5SAndroid Build Coastguard Worker for (const gl::ShaderType shaderType : executable->getLinkedShaderStages())
1107*8975f5c5SAndroid Build Coastguard Worker {
1108*8975f5c5SAndroid Build Coastguard Worker BufferAndLayout &uniformBlock = *(*defaultUniformBlocks)[shaderType];
1109*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
1110*8975f5c5SAndroid Build Coastguard Worker
1111*8975f5c5SAndroid Build Coastguard Worker // Assume an offset of -1 means the block is unused.
1112*8975f5c5SAndroid Build Coastguard Worker if (layoutInfo.offset == -1)
1113*8975f5c5SAndroid Build Coastguard Worker {
1114*8975f5c5SAndroid Build Coastguard Worker continue;
1115*8975f5c5SAndroid Build Coastguard Worker }
1116*8975f5c5SAndroid Build Coastguard Worker
1117*8975f5c5SAndroid Build Coastguard Worker const GLint componentCount = linkedUniform.getElementComponents();
1118*8975f5c5SAndroid Build Coastguard Worker UpdateBufferWithLayout(count, locationInfo.arrayIndex, componentCount, v, layoutInfo,
1119*8975f5c5SAndroid Build Coastguard Worker &uniformBlock.uniformData);
1120*8975f5c5SAndroid Build Coastguard Worker defaultUniformBlocksDirty->set(shaderType);
1121*8975f5c5SAndroid Build Coastguard Worker }
1122*8975f5c5SAndroid Build Coastguard Worker }
1123*8975f5c5SAndroid Build Coastguard Worker else
1124*8975f5c5SAndroid Build Coastguard Worker {
1125*8975f5c5SAndroid Build Coastguard Worker for (const gl::ShaderType shaderType : executable->getLinkedShaderStages())
1126*8975f5c5SAndroid Build Coastguard Worker {
1127*8975f5c5SAndroid Build Coastguard Worker BufferAndLayout &uniformBlock = *(*defaultUniformBlocks)[shaderType];
1128*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
1129*8975f5c5SAndroid Build Coastguard Worker
1130*8975f5c5SAndroid Build Coastguard Worker // Assume an offset of -1 means the block is unused.
1131*8975f5c5SAndroid Build Coastguard Worker if (layoutInfo.offset == -1)
1132*8975f5c5SAndroid Build Coastguard Worker {
1133*8975f5c5SAndroid Build Coastguard Worker continue;
1134*8975f5c5SAndroid Build Coastguard Worker }
1135*8975f5c5SAndroid Build Coastguard Worker
1136*8975f5c5SAndroid Build Coastguard Worker const GLint componentCount = linkedUniform.getElementComponents();
1137*8975f5c5SAndroid Build Coastguard Worker
1138*8975f5c5SAndroid Build Coastguard Worker ASSERT(linkedUniform.getType() == gl::VariableBoolVectorType(entryPointType));
1139*8975f5c5SAndroid Build Coastguard Worker
1140*8975f5c5SAndroid Build Coastguard Worker GLint initialArrayOffset =
1141*8975f5c5SAndroid Build Coastguard Worker locationInfo.arrayIndex * layoutInfo.arrayStride + layoutInfo.offset;
1142*8975f5c5SAndroid Build Coastguard Worker for (GLint i = 0; i < count; i++)
1143*8975f5c5SAndroid Build Coastguard Worker {
1144*8975f5c5SAndroid Build Coastguard Worker GLint elementOffset = i * layoutInfo.arrayStride + initialArrayOffset;
1145*8975f5c5SAndroid Build Coastguard Worker GLint *dst =
1146*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<GLint *>(uniformBlock.uniformData.data() + elementOffset);
1147*8975f5c5SAndroid Build Coastguard Worker const T *source = v + i * componentCount;
1148*8975f5c5SAndroid Build Coastguard Worker
1149*8975f5c5SAndroid Build Coastguard Worker for (int c = 0; c < componentCount; c++)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker dst[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
1152*8975f5c5SAndroid Build Coastguard Worker }
1153*8975f5c5SAndroid Build Coastguard Worker }
1154*8975f5c5SAndroid Build Coastguard Worker
1155*8975f5c5SAndroid Build Coastguard Worker defaultUniformBlocksDirty->set(shaderType);
1156*8975f5c5SAndroid Build Coastguard Worker }
1157*8975f5c5SAndroid Build Coastguard Worker }
1158*8975f5c5SAndroid Build Coastguard Worker }
1159*8975f5c5SAndroid Build Coastguard Worker template void SetUniform<GLint>(const gl::ProgramExecutable *executable,
1160*8975f5c5SAndroid Build Coastguard Worker GLint location,
1161*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
1162*8975f5c5SAndroid Build Coastguard Worker const GLint *v,
1163*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1164*8975f5c5SAndroid Build Coastguard Worker DefaultUniformBlockMap *defaultUniformBlocks,
1165*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty);
1166*8975f5c5SAndroid Build Coastguard Worker template void SetUniform<GLuint>(const gl::ProgramExecutable *executable,
1167*8975f5c5SAndroid Build Coastguard Worker GLint location,
1168*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
1169*8975f5c5SAndroid Build Coastguard Worker const GLuint *v,
1170*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1171*8975f5c5SAndroid Build Coastguard Worker DefaultUniformBlockMap *defaultUniformBlocks,
1172*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty);
1173*8975f5c5SAndroid Build Coastguard Worker template void SetUniform<GLfloat>(const gl::ProgramExecutable *executable,
1174*8975f5c5SAndroid Build Coastguard Worker GLint location,
1175*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
1176*8975f5c5SAndroid Build Coastguard Worker const GLfloat *v,
1177*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1178*8975f5c5SAndroid Build Coastguard Worker DefaultUniformBlockMap *defaultUniformBlocks,
1179*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty);
1180*8975f5c5SAndroid Build Coastguard Worker
1181*8975f5c5SAndroid Build Coastguard Worker template <int cols, int rows>
SetUniformMatrixfv(const gl::ProgramExecutable * executable,GLint location,GLsizei count,GLboolean transpose,const GLfloat * value,DefaultUniformBlockMap * defaultUniformBlocks,gl::ShaderBitSet * defaultUniformBlocksDirty)1182*8975f5c5SAndroid Build Coastguard Worker void SetUniformMatrixfv(const gl::ProgramExecutable *executable,
1183*8975f5c5SAndroid Build Coastguard Worker GLint location,
1184*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
1185*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
1186*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value,
1187*8975f5c5SAndroid Build Coastguard Worker DefaultUniformBlockMap *defaultUniformBlocks,
1188*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty)
1189*8975f5c5SAndroid Build Coastguard Worker {
1190*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = executable->getUniformLocations()[location];
1191*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &linkedUniform = executable->getUniforms()[locationInfo.index];
1192*8975f5c5SAndroid Build Coastguard Worker
1193*8975f5c5SAndroid Build Coastguard Worker for (const gl::ShaderType shaderType : executable->getLinkedShaderStages())
1194*8975f5c5SAndroid Build Coastguard Worker {
1195*8975f5c5SAndroid Build Coastguard Worker BufferAndLayout &uniformBlock = *(*defaultUniformBlocks)[shaderType];
1196*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
1197*8975f5c5SAndroid Build Coastguard Worker
1198*8975f5c5SAndroid Build Coastguard Worker // Assume an offset of -1 means the block is unused.
1199*8975f5c5SAndroid Build Coastguard Worker if (layoutInfo.offset == -1)
1200*8975f5c5SAndroid Build Coastguard Worker {
1201*8975f5c5SAndroid Build Coastguard Worker continue;
1202*8975f5c5SAndroid Build Coastguard Worker }
1203*8975f5c5SAndroid Build Coastguard Worker
1204*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrixGLSL<cols, rows>::Run(
1205*8975f5c5SAndroid Build Coastguard Worker locationInfo.arrayIndex, linkedUniform.getBasicTypeElementCount(), count, transpose,
1206*8975f5c5SAndroid Build Coastguard Worker value, uniformBlock.uniformData.data() + layoutInfo.offset);
1207*8975f5c5SAndroid Build Coastguard Worker
1208*8975f5c5SAndroid Build Coastguard Worker defaultUniformBlocksDirty->set(shaderType);
1209*8975f5c5SAndroid Build Coastguard Worker }
1210*8975f5c5SAndroid Build Coastguard Worker }
1211*8975f5c5SAndroid Build Coastguard Worker
1212*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(cols, rows) \
1213*8975f5c5SAndroid Build Coastguard Worker template void SetUniformMatrixfv<cols, rows>( \
1214*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramExecutable *executable, GLint location, GLsizei count, \
1215*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose, const GLfloat *value, DefaultUniformBlockMap *defaultUniformBlocks, \
1216*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet *defaultUniformBlocksDirty)
1217*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(2, 2);
1218*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(2, 3);
1219*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(2, 4);
1220*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(3, 2);
1221*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(3, 3);
1222*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(3, 4);
1223*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(4, 2);
1224*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(4, 3);
1225*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_UNIFORM_MATRIX_FV_SPECIALIZATION(4, 4);
1226*8975f5c5SAndroid Build Coastguard Worker
1227*8975f5c5SAndroid Build Coastguard Worker template <typename T>
GetUniform(const gl::ProgramExecutable * executable,GLint location,T * v,GLenum entryPointType,const DefaultUniformBlockMap * defaultUniformBlocks)1228*8975f5c5SAndroid Build Coastguard Worker void GetUniform(const gl::ProgramExecutable *executable,
1229*8975f5c5SAndroid Build Coastguard Worker GLint location,
1230*8975f5c5SAndroid Build Coastguard Worker T *v,
1231*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1232*8975f5c5SAndroid Build Coastguard Worker const DefaultUniformBlockMap *defaultUniformBlocks)
1233*8975f5c5SAndroid Build Coastguard Worker {
1234*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = executable->getUniformLocations()[location];
1235*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &linkedUniform = executable->getUniforms()[locationInfo.index];
1236*8975f5c5SAndroid Build Coastguard Worker
1237*8975f5c5SAndroid Build Coastguard Worker ASSERT(!linkedUniform.isSampler() && !linkedUniform.isImage());
1238*8975f5c5SAndroid Build Coastguard Worker
1239*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType shaderType = linkedUniform.getFirstActiveShaderType();
1240*8975f5c5SAndroid Build Coastguard Worker ASSERT(shaderType != gl::ShaderType::InvalidEnum);
1241*8975f5c5SAndroid Build Coastguard Worker
1242*8975f5c5SAndroid Build Coastguard Worker const BufferAndLayout &uniformBlock = *(*defaultUniformBlocks)[shaderType];
1243*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &layoutInfo = uniformBlock.uniformLayout[location];
1244*8975f5c5SAndroid Build Coastguard Worker
1245*8975f5c5SAndroid Build Coastguard Worker ASSERT(linkedUniform.getUniformTypeInfo().componentType == entryPointType ||
1246*8975f5c5SAndroid Build Coastguard Worker linkedUniform.getUniformTypeInfo().componentType ==
1247*8975f5c5SAndroid Build Coastguard Worker gl::VariableBoolVectorType(entryPointType));
1248*8975f5c5SAndroid Build Coastguard Worker
1249*8975f5c5SAndroid Build Coastguard Worker if (gl::IsMatrixType(linkedUniform.getType()))
1250*8975f5c5SAndroid Build Coastguard Worker {
1251*8975f5c5SAndroid Build Coastguard Worker const uint8_t *ptrToElement = uniformBlock.uniformData.data() + layoutInfo.offset +
1252*8975f5c5SAndroid Build Coastguard Worker (locationInfo.arrayIndex * layoutInfo.arrayStride);
1253*8975f5c5SAndroid Build Coastguard Worker GetMatrixUniform(linkedUniform.getType(), v, reinterpret_cast<const T *>(ptrToElement),
1254*8975f5c5SAndroid Build Coastguard Worker false);
1255*8975f5c5SAndroid Build Coastguard Worker }
1256*8975f5c5SAndroid Build Coastguard Worker else
1257*8975f5c5SAndroid Build Coastguard Worker {
1258*8975f5c5SAndroid Build Coastguard Worker ReadFromBufferWithLayout(linkedUniform.getElementComponents(), locationInfo.arrayIndex, v,
1259*8975f5c5SAndroid Build Coastguard Worker layoutInfo, &uniformBlock.uniformData);
1260*8975f5c5SAndroid Build Coastguard Worker }
1261*8975f5c5SAndroid Build Coastguard Worker }
1262*8975f5c5SAndroid Build Coastguard Worker
1263*8975f5c5SAndroid Build Coastguard Worker template void GetUniform<GLint>(const gl::ProgramExecutable *executable,
1264*8975f5c5SAndroid Build Coastguard Worker GLint location,
1265*8975f5c5SAndroid Build Coastguard Worker GLint *v,
1266*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1267*8975f5c5SAndroid Build Coastguard Worker const DefaultUniformBlockMap *defaultUniformBlocks);
1268*8975f5c5SAndroid Build Coastguard Worker template void GetUniform<GLuint>(const gl::ProgramExecutable *executable,
1269*8975f5c5SAndroid Build Coastguard Worker GLint location,
1270*8975f5c5SAndroid Build Coastguard Worker GLuint *v,
1271*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1272*8975f5c5SAndroid Build Coastguard Worker const DefaultUniformBlockMap *defaultUniformBlocks);
1273*8975f5c5SAndroid Build Coastguard Worker template void GetUniform<GLfloat>(const gl::ProgramExecutable *executable,
1274*8975f5c5SAndroid Build Coastguard Worker GLint location,
1275*8975f5c5SAndroid Build Coastguard Worker GLfloat *v,
1276*8975f5c5SAndroid Build Coastguard Worker GLenum entryPointType,
1277*8975f5c5SAndroid Build Coastguard Worker const DefaultUniformBlockMap *defaultUniformBlocks);
1278*8975f5c5SAndroid Build Coastguard Worker
GetFormatFromFormatType(GLenum format,GLenum type)1279*8975f5c5SAndroid Build Coastguard Worker const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type)
1280*8975f5c5SAndroid Build Coastguard Worker {
1281*8975f5c5SAndroid Build Coastguard Worker GLenum sizedInternalFormat = gl::GetInternalFormatInfo(format, type).sizedInternalFormat;
1282*8975f5c5SAndroid Build Coastguard Worker angle::FormatID angleFormatID = angle::Format::InternalFormatToID(sizedInternalFormat);
1283*8975f5c5SAndroid Build Coastguard Worker return angle::Format::Get(angleFormatID);
1284*8975f5c5SAndroid Build Coastguard Worker }
1285*8975f5c5SAndroid Build Coastguard Worker
ComputeStartVertex(ContextImpl * contextImpl,const gl::IndexRange & indexRange,GLint baseVertex,GLint * firstVertexOut)1286*8975f5c5SAndroid Build Coastguard Worker angle::Result ComputeStartVertex(ContextImpl *contextImpl,
1287*8975f5c5SAndroid Build Coastguard Worker const gl::IndexRange &indexRange,
1288*8975f5c5SAndroid Build Coastguard Worker GLint baseVertex,
1289*8975f5c5SAndroid Build Coastguard Worker GLint *firstVertexOut)
1290*8975f5c5SAndroid Build Coastguard Worker {
1291*8975f5c5SAndroid Build Coastguard Worker // The entire index range should be within the limits of a 32-bit uint because the largest
1292*8975f5c5SAndroid Build Coastguard Worker // GL index type is GL_UNSIGNED_INT.
1293*8975f5c5SAndroid Build Coastguard Worker ASSERT(indexRange.start <= std::numeric_limits<uint32_t>::max() &&
1294*8975f5c5SAndroid Build Coastguard Worker indexRange.end <= std::numeric_limits<uint32_t>::max());
1295*8975f5c5SAndroid Build Coastguard Worker
1296*8975f5c5SAndroid Build Coastguard Worker // The base vertex is only used in DrawElementsIndirect. Given the assertion above and the
1297*8975f5c5SAndroid Build Coastguard Worker // type of mBaseVertex (GLint), adding them both as 64-bit ints is safe.
1298*8975f5c5SAndroid Build Coastguard Worker int64_t startVertexInt64 =
1299*8975f5c5SAndroid Build Coastguard Worker static_cast<int64_t>(baseVertex) + static_cast<int64_t>(indexRange.start);
1300*8975f5c5SAndroid Build Coastguard Worker
1301*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.2 spec section 10.5: "Behavior of DrawElementsOneInstance is undefined if the
1302*8975f5c5SAndroid Build Coastguard Worker // vertex ID is negative for any element"
1303*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 >= 0);
1304*8975f5c5SAndroid Build Coastguard Worker
1305*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.2 spec section 10.5: "If the vertex ID is larger than the maximum value
1306*8975f5c5SAndroid Build Coastguard Worker // representable by type, it should behave as if the calculation were upconverted to 32-bit
1307*8975f5c5SAndroid Build Coastguard Worker // unsigned integers(with wrapping on overflow conditions)." ANGLE does not fully handle
1308*8975f5c5SAndroid Build Coastguard Worker // these rules, an overflow error is returned if the start vertex cannot be stored in a
1309*8975f5c5SAndroid Build Coastguard Worker // 32-bit signed integer.
1310*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 <= std::numeric_limits<GLint>::max());
1311*8975f5c5SAndroid Build Coastguard Worker
1312*8975f5c5SAndroid Build Coastguard Worker *firstVertexOut = static_cast<GLint>(startVertexInt64);
1313*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1314*8975f5c5SAndroid Build Coastguard Worker }
1315*8975f5c5SAndroid Build Coastguard Worker
GetVertexRangeInfo(const gl::Context * context,GLint firstVertex,GLsizei vertexOrIndexCount,gl::DrawElementsType indexTypeOrInvalid,const void * indices,GLint baseVertex,GLint * startVertexOut,size_t * vertexCountOut)1316*8975f5c5SAndroid Build Coastguard Worker angle::Result GetVertexRangeInfo(const gl::Context *context,
1317*8975f5c5SAndroid Build Coastguard Worker GLint firstVertex,
1318*8975f5c5SAndroid Build Coastguard Worker GLsizei vertexOrIndexCount,
1319*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType indexTypeOrInvalid,
1320*8975f5c5SAndroid Build Coastguard Worker const void *indices,
1321*8975f5c5SAndroid Build Coastguard Worker GLint baseVertex,
1322*8975f5c5SAndroid Build Coastguard Worker GLint *startVertexOut,
1323*8975f5c5SAndroid Build Coastguard Worker size_t *vertexCountOut)
1324*8975f5c5SAndroid Build Coastguard Worker {
1325*8975f5c5SAndroid Build Coastguard Worker if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
1326*8975f5c5SAndroid Build Coastguard Worker {
1327*8975f5c5SAndroid Build Coastguard Worker gl::IndexRange indexRange;
1328*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(
1329*8975f5c5SAndroid Build Coastguard Worker context, indexTypeOrInvalid, vertexOrIndexCount, indices, &indexRange));
1330*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ComputeStartVertex(context->getImplementation(), indexRange, baseVertex,
1331*8975f5c5SAndroid Build Coastguard Worker startVertexOut));
1332*8975f5c5SAndroid Build Coastguard Worker *vertexCountOut = indexRange.vertexCount();
1333*8975f5c5SAndroid Build Coastguard Worker }
1334*8975f5c5SAndroid Build Coastguard Worker else
1335*8975f5c5SAndroid Build Coastguard Worker {
1336*8975f5c5SAndroid Build Coastguard Worker *startVertexOut = firstVertex;
1337*8975f5c5SAndroid Build Coastguard Worker *vertexCountOut = vertexOrIndexCount;
1338*8975f5c5SAndroid Build Coastguard Worker }
1339*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1340*8975f5c5SAndroid Build Coastguard Worker }
1341*8975f5c5SAndroid Build Coastguard Worker
ClipRectToScissor(const gl::State & glState,const gl::Rectangle & rect,bool invertY)1342*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY)
1343*8975f5c5SAndroid Build Coastguard Worker {
1344*8975f5c5SAndroid Build Coastguard Worker // If the scissor test isn't enabled, assume it has infinite size. Its intersection with the
1345*8975f5c5SAndroid Build Coastguard Worker // rect would be the rect itself.
1346*8975f5c5SAndroid Build Coastguard Worker //
1347*8975f5c5SAndroid Build Coastguard Worker // Note that on Vulkan, returning this (as opposed to a fixed max-int-sized rect) could lead to
1348*8975f5c5SAndroid Build Coastguard Worker // unnecessary pipeline creations if two otherwise identical pipelines are used on framebuffers
1349*8975f5c5SAndroid Build Coastguard Worker // with different sizes. If such usage is observed in an application, we should investigate
1350*8975f5c5SAndroid Build Coastguard Worker // possible optimizations.
1351*8975f5c5SAndroid Build Coastguard Worker if (!glState.isScissorTestEnabled())
1352*8975f5c5SAndroid Build Coastguard Worker {
1353*8975f5c5SAndroid Build Coastguard Worker return rect;
1354*8975f5c5SAndroid Build Coastguard Worker }
1355*8975f5c5SAndroid Build Coastguard Worker
1356*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedRect;
1357*8975f5c5SAndroid Build Coastguard Worker if (!gl::ClipRectangle(glState.getScissor(), rect, &clippedRect))
1358*8975f5c5SAndroid Build Coastguard Worker {
1359*8975f5c5SAndroid Build Coastguard Worker return gl::Rectangle();
1360*8975f5c5SAndroid Build Coastguard Worker }
1361*8975f5c5SAndroid Build Coastguard Worker
1362*8975f5c5SAndroid Build Coastguard Worker if (invertY)
1363*8975f5c5SAndroid Build Coastguard Worker {
1364*8975f5c5SAndroid Build Coastguard Worker clippedRect.y = rect.height - clippedRect.y - clippedRect.height;
1365*8975f5c5SAndroid Build Coastguard Worker }
1366*8975f5c5SAndroid Build Coastguard Worker
1367*8975f5c5SAndroid Build Coastguard Worker return clippedRect;
1368*8975f5c5SAndroid Build Coastguard Worker }
1369*8975f5c5SAndroid Build Coastguard Worker
LogFeatureStatus(const angle::FeatureSetBase & features,const std::vector<std::string> & featureNames,bool enabled)1370*8975f5c5SAndroid Build Coastguard Worker void LogFeatureStatus(const angle::FeatureSetBase &features,
1371*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::string> &featureNames,
1372*8975f5c5SAndroid Build Coastguard Worker bool enabled)
1373*8975f5c5SAndroid Build Coastguard Worker {
1374*8975f5c5SAndroid Build Coastguard Worker for (const std::string &name : featureNames)
1375*8975f5c5SAndroid Build Coastguard Worker {
1376*8975f5c5SAndroid Build Coastguard Worker const bool hasWildcard = name.back() == '*';
1377*8975f5c5SAndroid Build Coastguard Worker for (auto iter : features.getFeatures())
1378*8975f5c5SAndroid Build Coastguard Worker {
1379*8975f5c5SAndroid Build Coastguard Worker const std::string &featureName = iter.first;
1380*8975f5c5SAndroid Build Coastguard Worker
1381*8975f5c5SAndroid Build Coastguard Worker if (!angle::FeatureNameMatch(featureName, name))
1382*8975f5c5SAndroid Build Coastguard Worker {
1383*8975f5c5SAndroid Build Coastguard Worker continue;
1384*8975f5c5SAndroid Build Coastguard Worker }
1385*8975f5c5SAndroid Build Coastguard Worker
1386*8975f5c5SAndroid Build Coastguard Worker INFO() << "Feature: " << featureName << (enabled ? " enabled" : " disabled");
1387*8975f5c5SAndroid Build Coastguard Worker
1388*8975f5c5SAndroid Build Coastguard Worker if (!hasWildcard)
1389*8975f5c5SAndroid Build Coastguard Worker {
1390*8975f5c5SAndroid Build Coastguard Worker break;
1391*8975f5c5SAndroid Build Coastguard Worker }
1392*8975f5c5SAndroid Build Coastguard Worker }
1393*8975f5c5SAndroid Build Coastguard Worker }
1394*8975f5c5SAndroid Build Coastguard Worker }
1395*8975f5c5SAndroid Build Coastguard Worker
ApplyFeatureOverrides(angle::FeatureSetBase * features,const angle::FeatureOverrides & overrides)1396*8975f5c5SAndroid Build Coastguard Worker void ApplyFeatureOverrides(angle::FeatureSetBase *features,
1397*8975f5c5SAndroid Build Coastguard Worker const angle::FeatureOverrides &overrides)
1398*8975f5c5SAndroid Build Coastguard Worker {
1399*8975f5c5SAndroid Build Coastguard Worker features->overrideFeatures(overrides.enabled, true);
1400*8975f5c5SAndroid Build Coastguard Worker features->overrideFeatures(overrides.disabled, false);
1401*8975f5c5SAndroid Build Coastguard Worker
1402*8975f5c5SAndroid Build Coastguard Worker // Override with environment as well.
1403*8975f5c5SAndroid Build Coastguard Worker constexpr char kAngleFeatureOverridesEnabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_ENABLED";
1404*8975f5c5SAndroid Build Coastguard Worker constexpr char kAngleFeatureOverridesDisabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_DISABLED";
1405*8975f5c5SAndroid Build Coastguard Worker constexpr char kAngleFeatureOverridesEnabledPropertyName[] =
1406*8975f5c5SAndroid Build Coastguard Worker "debug.angle.feature_overrides_enabled";
1407*8975f5c5SAndroid Build Coastguard Worker constexpr char kAngleFeatureOverridesDisabledPropertyName[] =
1408*8975f5c5SAndroid Build Coastguard Worker "debug.angle.feature_overrides_disabled";
1409*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> overridesEnabled =
1410*8975f5c5SAndroid Build Coastguard Worker angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty(
1411*8975f5c5SAndroid Build Coastguard Worker kAngleFeatureOverridesEnabledEnvName, kAngleFeatureOverridesEnabledPropertyName, ":");
1412*8975f5c5SAndroid Build Coastguard Worker std::vector<std::string> overridesDisabled =
1413*8975f5c5SAndroid Build Coastguard Worker angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty(
1414*8975f5c5SAndroid Build Coastguard Worker kAngleFeatureOverridesDisabledEnvName, kAngleFeatureOverridesDisabledPropertyName, ":");
1415*8975f5c5SAndroid Build Coastguard Worker
1416*8975f5c5SAndroid Build Coastguard Worker features->overrideFeatures(overridesEnabled, true);
1417*8975f5c5SAndroid Build Coastguard Worker LogFeatureStatus(*features, overridesEnabled, true);
1418*8975f5c5SAndroid Build Coastguard Worker
1419*8975f5c5SAndroid Build Coastguard Worker features->overrideFeatures(overridesDisabled, false);
1420*8975f5c5SAndroid Build Coastguard Worker LogFeatureStatus(*features, overridesDisabled, false);
1421*8975f5c5SAndroid Build Coastguard Worker }
1422*8975f5c5SAndroid Build Coastguard Worker
GetSamplePosition(GLsizei sampleCount,size_t index,GLfloat * xy)1423*8975f5c5SAndroid Build Coastguard Worker void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy)
1424*8975f5c5SAndroid Build Coastguard Worker {
1425*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::isPow2(sampleCount));
1426*8975f5c5SAndroid Build Coastguard Worker if (sampleCount > 16)
1427*8975f5c5SAndroid Build Coastguard Worker {
1428*8975f5c5SAndroid Build Coastguard Worker // Vulkan (and D3D11) doesn't have standard sample positions for 32 and 64 samples (and no
1429*8975f5c5SAndroid Build Coastguard Worker // drivers are known to support that many samples)
1430*8975f5c5SAndroid Build Coastguard Worker xy[0] = 0.5f;
1431*8975f5c5SAndroid Build Coastguard Worker xy[1] = 0.5f;
1432*8975f5c5SAndroid Build Coastguard Worker }
1433*8975f5c5SAndroid Build Coastguard Worker else
1434*8975f5c5SAndroid Build Coastguard Worker {
1435*8975f5c5SAndroid Build Coastguard Worker size_t indexKey = static_cast<size_t>(gl::log2(sampleCount));
1436*8975f5c5SAndroid Build Coastguard Worker ASSERT(indexKey < kSamplePositions.size() &&
1437*8975f5c5SAndroid Build Coastguard Worker (2 * index + 1) < kSamplePositions[indexKey].size());
1438*8975f5c5SAndroid Build Coastguard Worker
1439*8975f5c5SAndroid Build Coastguard Worker xy[0] = kSamplePositions[indexKey][2 * index];
1440*8975f5c5SAndroid Build Coastguard Worker xy[1] = kSamplePositions[indexKey][2 * index + 1];
1441*8975f5c5SAndroid Build Coastguard Worker }
1442*8975f5c5SAndroid Build Coastguard Worker }
1443*8975f5c5SAndroid Build Coastguard Worker
1444*8975f5c5SAndroid Build Coastguard Worker // These macros are to avoid code too much duplication for variations of multi draw types
1445*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ARRAYS__ contextImpl->drawArrays(context, mode, firsts[drawID], counts[drawID])
1446*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ARRAYS_INSTANCED_ \
1447*8975f5c5SAndroid Build Coastguard Worker contextImpl->drawArraysInstanced(context, mode, firsts[drawID], counts[drawID], \
1448*8975f5c5SAndroid Build Coastguard Worker instanceCounts[drawID])
1449*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ELEMENTS__ \
1450*8975f5c5SAndroid Build Coastguard Worker contextImpl->drawElements(context, mode, counts[drawID], type, indices[drawID])
1451*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ELEMENTS_INSTANCED_ \
1452*8975f5c5SAndroid Build Coastguard Worker contextImpl->drawElementsInstanced(context, mode, counts[drawID], type, indices[drawID], \
1453*8975f5c5SAndroid Build Coastguard Worker instanceCounts[drawID])
1454*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \
1455*8975f5c5SAndroid Build Coastguard Worker contextImpl->drawArraysInstancedBaseInstance(context, mode, firsts[drawID], counts[drawID], \
1456*8975f5c5SAndroid Build Coastguard Worker instanceCounts[drawID], baseInstances[drawID])
1457*8975f5c5SAndroid Build Coastguard Worker #define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \
1458*8975f5c5SAndroid Build Coastguard Worker contextImpl->drawElementsInstancedBaseVertexBaseInstance( \
1459*8975f5c5SAndroid Build Coastguard Worker context, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
1460*8975f5c5SAndroid Build Coastguard Worker baseVertices[drawID], baseInstances[drawID])
1461*8975f5c5SAndroid Build Coastguard Worker #define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi
1462*8975f5c5SAndroid Build Coastguard Worker
1463*8975f5c5SAndroid Build Coastguard Worker #define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \
1464*8975f5c5SAndroid Build Coastguard Worker do \
1465*8975f5c5SAndroid Build Coastguard Worker { \
1466*8975f5c5SAndroid Build Coastguard Worker for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
1467*8975f5c5SAndroid Build Coastguard Worker { \
1468*8975f5c5SAndroid Build Coastguard Worker if (ANGLE_NOOP_DRAW(instanced)) \
1469*8975f5c5SAndroid Build Coastguard Worker { \
1470*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextImpl->handleNoopDrawEvent()); \
1471*8975f5c5SAndroid Build Coastguard Worker continue; \
1472*8975f5c5SAndroid Build Coastguard Worker } \
1473*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
1474*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
1475*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
1476*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(DRAW_CALL(drawType, instanced, bvbi)); \
1477*8975f5c5SAndroid Build Coastguard Worker ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \
1478*8975f5c5SAndroid Build Coastguard Worker gl::MarkShaderStorageUsage(context); \
1479*8975f5c5SAndroid Build Coastguard Worker } \
1480*8975f5c5SAndroid Build Coastguard Worker /* reset the uniform to zero for non-multi-draw uses of the program */ \
1481*8975f5c5SAndroid Build Coastguard Worker ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(0); \
1482*8975f5c5SAndroid Build Coastguard Worker } while (0)
1483*8975f5c5SAndroid Build Coastguard Worker
MultiDrawArraysGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)1484*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
1485*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1486*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1487*8975f5c5SAndroid Build Coastguard Worker const GLint *firsts,
1488*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1489*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1490*8975f5c5SAndroid Build Coastguard Worker {
1491*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1492*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1493*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID)
1494*8975f5c5SAndroid Build Coastguard Worker {
1495*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0);
1496*8975f5c5SAndroid Build Coastguard Worker }
1497*8975f5c5SAndroid Build Coastguard Worker else
1498*8975f5c5SAndroid Build Coastguard Worker {
1499*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0);
1500*8975f5c5SAndroid Build Coastguard Worker }
1501*8975f5c5SAndroid Build Coastguard Worker
1502*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1503*8975f5c5SAndroid Build Coastguard Worker }
1504*8975f5c5SAndroid Build Coastguard Worker
MultiDrawArraysIndirectGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const void * indirect,GLsizei drawcount,GLsizei stride)1505*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
1506*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1507*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1508*8975f5c5SAndroid Build Coastguard Worker const void *indirect,
1509*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount,
1510*8975f5c5SAndroid Build Coastguard Worker GLsizei stride)
1511*8975f5c5SAndroid Build Coastguard Worker {
1512*8975f5c5SAndroid Build Coastguard Worker const GLubyte *indirectPtr = static_cast<const GLubyte *>(indirect);
1513*8975f5c5SAndroid Build Coastguard Worker
1514*8975f5c5SAndroid Build Coastguard Worker for (auto count = 0; count < drawcount; count++)
1515*8975f5c5SAndroid Build Coastguard Worker {
1516*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextImpl->drawArraysIndirect(
1517*8975f5c5SAndroid Build Coastguard Worker context, mode, reinterpret_cast<const gl::DrawArraysIndirectCommand *>(indirectPtr)));
1518*8975f5c5SAndroid Build Coastguard Worker if (stride == 0)
1519*8975f5c5SAndroid Build Coastguard Worker {
1520*8975f5c5SAndroid Build Coastguard Worker indirectPtr += sizeof(gl::DrawArraysIndirectCommand);
1521*8975f5c5SAndroid Build Coastguard Worker }
1522*8975f5c5SAndroid Build Coastguard Worker else
1523*8975f5c5SAndroid Build Coastguard Worker {
1524*8975f5c5SAndroid Build Coastguard Worker indirectPtr += stride;
1525*8975f5c5SAndroid Build Coastguard Worker }
1526*8975f5c5SAndroid Build Coastguard Worker }
1527*8975f5c5SAndroid Build Coastguard Worker
1528*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1529*8975f5c5SAndroid Build Coastguard Worker }
1530*8975f5c5SAndroid Build Coastguard Worker
MultiDrawArraysInstancedGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)1531*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
1532*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1533*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1534*8975f5c5SAndroid Build Coastguard Worker const GLint *firsts,
1535*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1536*8975f5c5SAndroid Build Coastguard Worker const GLsizei *instanceCounts,
1537*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1538*8975f5c5SAndroid Build Coastguard Worker {
1539*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1540*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1541*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID)
1542*8975f5c5SAndroid Build Coastguard Worker {
1543*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0);
1544*8975f5c5SAndroid Build Coastguard Worker }
1545*8975f5c5SAndroid Build Coastguard Worker else
1546*8975f5c5SAndroid Build Coastguard Worker {
1547*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0);
1548*8975f5c5SAndroid Build Coastguard Worker }
1549*8975f5c5SAndroid Build Coastguard Worker
1550*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1551*8975f5c5SAndroid Build Coastguard Worker }
1552*8975f5c5SAndroid Build Coastguard Worker
MultiDrawElementsGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)1553*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
1554*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1555*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1556*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1557*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType type,
1558*8975f5c5SAndroid Build Coastguard Worker const GLvoid *const *indices,
1559*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1560*8975f5c5SAndroid Build Coastguard Worker {
1561*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1562*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1563*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID)
1564*8975f5c5SAndroid Build Coastguard Worker {
1565*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0);
1566*8975f5c5SAndroid Build Coastguard Worker }
1567*8975f5c5SAndroid Build Coastguard Worker else
1568*8975f5c5SAndroid Build Coastguard Worker {
1569*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0);
1570*8975f5c5SAndroid Build Coastguard Worker }
1571*8975f5c5SAndroid Build Coastguard Worker
1572*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1573*8975f5c5SAndroid Build Coastguard Worker }
1574*8975f5c5SAndroid Build Coastguard Worker
MultiDrawElementsIndirectGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,gl::DrawElementsType type,const void * indirect,GLsizei drawcount,GLsizei stride)1575*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
1576*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1577*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1578*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType type,
1579*8975f5c5SAndroid Build Coastguard Worker const void *indirect,
1580*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount,
1581*8975f5c5SAndroid Build Coastguard Worker GLsizei stride)
1582*8975f5c5SAndroid Build Coastguard Worker {
1583*8975f5c5SAndroid Build Coastguard Worker const GLubyte *indirectPtr = static_cast<const GLubyte *>(indirect);
1584*8975f5c5SAndroid Build Coastguard Worker
1585*8975f5c5SAndroid Build Coastguard Worker for (auto count = 0; count < drawcount; count++)
1586*8975f5c5SAndroid Build Coastguard Worker {
1587*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(contextImpl->drawElementsIndirect(
1588*8975f5c5SAndroid Build Coastguard Worker context, mode, type,
1589*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<const gl::DrawElementsIndirectCommand *>(indirectPtr)));
1590*8975f5c5SAndroid Build Coastguard Worker if (stride == 0)
1591*8975f5c5SAndroid Build Coastguard Worker {
1592*8975f5c5SAndroid Build Coastguard Worker indirectPtr += sizeof(gl::DrawElementsIndirectCommand);
1593*8975f5c5SAndroid Build Coastguard Worker }
1594*8975f5c5SAndroid Build Coastguard Worker else
1595*8975f5c5SAndroid Build Coastguard Worker {
1596*8975f5c5SAndroid Build Coastguard Worker indirectPtr += stride;
1597*8975f5c5SAndroid Build Coastguard Worker }
1598*8975f5c5SAndroid Build Coastguard Worker }
1599*8975f5c5SAndroid Build Coastguard Worker
1600*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1601*8975f5c5SAndroid Build Coastguard Worker }
1602*8975f5c5SAndroid Build Coastguard Worker
MultiDrawElementsInstancedGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)1603*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
1604*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1605*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1606*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1607*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType type,
1608*8975f5c5SAndroid Build Coastguard Worker const GLvoid *const *indices,
1609*8975f5c5SAndroid Build Coastguard Worker const GLsizei *instanceCounts,
1610*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1611*8975f5c5SAndroid Build Coastguard Worker {
1612*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1613*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1614*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID)
1615*8975f5c5SAndroid Build Coastguard Worker {
1616*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0);
1617*8975f5c5SAndroid Build Coastguard Worker }
1618*8975f5c5SAndroid Build Coastguard Worker else
1619*8975f5c5SAndroid Build Coastguard Worker {
1620*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0);
1621*8975f5c5SAndroid Build Coastguard Worker }
1622*8975f5c5SAndroid Build Coastguard Worker
1623*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1624*8975f5c5SAndroid Build Coastguard Worker }
1625*8975f5c5SAndroid Build Coastguard Worker
MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)1626*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
1627*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1628*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1629*8975f5c5SAndroid Build Coastguard Worker const GLint *firsts,
1630*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1631*8975f5c5SAndroid Build Coastguard Worker const GLsizei *instanceCounts,
1632*8975f5c5SAndroid Build Coastguard Worker const GLuint *baseInstances,
1633*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1634*8975f5c5SAndroid Build Coastguard Worker {
1635*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1636*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1637*8975f5c5SAndroid Build Coastguard Worker const bool hasBaseInstance = executable->hasBaseInstanceUniform();
1638*8975f5c5SAndroid Build Coastguard Worker ResetBaseVertexBaseInstance resetUniforms(executable, false, hasBaseInstance);
1639*8975f5c5SAndroid Build Coastguard Worker
1640*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID && hasBaseInstance)
1641*8975f5c5SAndroid Build Coastguard Worker {
1642*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1);
1643*8975f5c5SAndroid Build Coastguard Worker }
1644*8975f5c5SAndroid Build Coastguard Worker else if (hasDrawID)
1645*8975f5c5SAndroid Build Coastguard Worker {
1646*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0);
1647*8975f5c5SAndroid Build Coastguard Worker }
1648*8975f5c5SAndroid Build Coastguard Worker else if (hasBaseInstance)
1649*8975f5c5SAndroid Build Coastguard Worker {
1650*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1);
1651*8975f5c5SAndroid Build Coastguard Worker }
1652*8975f5c5SAndroid Build Coastguard Worker else
1653*8975f5c5SAndroid Build Coastguard Worker {
1654*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0);
1655*8975f5c5SAndroid Build Coastguard Worker }
1656*8975f5c5SAndroid Build Coastguard Worker
1657*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1658*8975f5c5SAndroid Build Coastguard Worker }
1659*8975f5c5SAndroid Build Coastguard Worker
MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl * contextImpl,const gl::Context * context,gl::PrimitiveMode mode,const GLsizei * counts,gl::DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)1660*8975f5c5SAndroid Build Coastguard Worker angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
1661*8975f5c5SAndroid Build Coastguard Worker const gl::Context *context,
1662*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode mode,
1663*8975f5c5SAndroid Build Coastguard Worker const GLsizei *counts,
1664*8975f5c5SAndroid Build Coastguard Worker gl::DrawElementsType type,
1665*8975f5c5SAndroid Build Coastguard Worker const GLvoid *const *indices,
1666*8975f5c5SAndroid Build Coastguard Worker const GLsizei *instanceCounts,
1667*8975f5c5SAndroid Build Coastguard Worker const GLint *baseVertices,
1668*8975f5c5SAndroid Build Coastguard Worker const GLuint *baseInstances,
1669*8975f5c5SAndroid Build Coastguard Worker GLsizei drawcount)
1670*8975f5c5SAndroid Build Coastguard Worker {
1671*8975f5c5SAndroid Build Coastguard Worker gl::ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
1672*8975f5c5SAndroid Build Coastguard Worker const bool hasDrawID = executable->hasDrawIDUniform();
1673*8975f5c5SAndroid Build Coastguard Worker const bool hasBaseVertex = executable->hasBaseVertexUniform();
1674*8975f5c5SAndroid Build Coastguard Worker const bool hasBaseInstance = executable->hasBaseInstanceUniform();
1675*8975f5c5SAndroid Build Coastguard Worker ResetBaseVertexBaseInstance resetUniforms(executable, hasBaseVertex, hasBaseInstance);
1676*8975f5c5SAndroid Build Coastguard Worker
1677*8975f5c5SAndroid Build Coastguard Worker if (hasDrawID)
1678*8975f5c5SAndroid Build Coastguard Worker {
1679*8975f5c5SAndroid Build Coastguard Worker if (hasBaseVertex)
1680*8975f5c5SAndroid Build Coastguard Worker {
1681*8975f5c5SAndroid Build Coastguard Worker if (hasBaseInstance)
1682*8975f5c5SAndroid Build Coastguard Worker {
1683*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1);
1684*8975f5c5SAndroid Build Coastguard Worker }
1685*8975f5c5SAndroid Build Coastguard Worker else
1686*8975f5c5SAndroid Build Coastguard Worker {
1687*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0);
1688*8975f5c5SAndroid Build Coastguard Worker }
1689*8975f5c5SAndroid Build Coastguard Worker }
1690*8975f5c5SAndroid Build Coastguard Worker else
1691*8975f5c5SAndroid Build Coastguard Worker {
1692*8975f5c5SAndroid Build Coastguard Worker if (hasBaseInstance)
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1);
1695*8975f5c5SAndroid Build Coastguard Worker }
1696*8975f5c5SAndroid Build Coastguard Worker else
1697*8975f5c5SAndroid Build Coastguard Worker {
1698*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0);
1699*8975f5c5SAndroid Build Coastguard Worker }
1700*8975f5c5SAndroid Build Coastguard Worker }
1701*8975f5c5SAndroid Build Coastguard Worker }
1702*8975f5c5SAndroid Build Coastguard Worker else
1703*8975f5c5SAndroid Build Coastguard Worker {
1704*8975f5c5SAndroid Build Coastguard Worker if (hasBaseVertex)
1705*8975f5c5SAndroid Build Coastguard Worker {
1706*8975f5c5SAndroid Build Coastguard Worker if (hasBaseInstance)
1707*8975f5c5SAndroid Build Coastguard Worker {
1708*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1);
1709*8975f5c5SAndroid Build Coastguard Worker }
1710*8975f5c5SAndroid Build Coastguard Worker else
1711*8975f5c5SAndroid Build Coastguard Worker {
1712*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0);
1713*8975f5c5SAndroid Build Coastguard Worker }
1714*8975f5c5SAndroid Build Coastguard Worker }
1715*8975f5c5SAndroid Build Coastguard Worker else
1716*8975f5c5SAndroid Build Coastguard Worker {
1717*8975f5c5SAndroid Build Coastguard Worker if (hasBaseInstance)
1718*8975f5c5SAndroid Build Coastguard Worker {
1719*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1);
1720*8975f5c5SAndroid Build Coastguard Worker }
1721*8975f5c5SAndroid Build Coastguard Worker else
1722*8975f5c5SAndroid Build Coastguard Worker {
1723*8975f5c5SAndroid Build Coastguard Worker MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0);
1724*8975f5c5SAndroid Build Coastguard Worker }
1725*8975f5c5SAndroid Build Coastguard Worker }
1726*8975f5c5SAndroid Build Coastguard Worker }
1727*8975f5c5SAndroid Build Coastguard Worker
1728*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker
ResetBaseVertexBaseInstance(gl::ProgramExecutable * executable,bool resetBaseVertex,bool resetBaseInstance)1731*8975f5c5SAndroid Build Coastguard Worker ResetBaseVertexBaseInstance::ResetBaseVertexBaseInstance(gl::ProgramExecutable *executable,
1732*8975f5c5SAndroid Build Coastguard Worker bool resetBaseVertex,
1733*8975f5c5SAndroid Build Coastguard Worker bool resetBaseInstance)
1734*8975f5c5SAndroid Build Coastguard Worker : mExecutable(executable),
1735*8975f5c5SAndroid Build Coastguard Worker mResetBaseVertex(resetBaseVertex),
1736*8975f5c5SAndroid Build Coastguard Worker mResetBaseInstance(resetBaseInstance)
1737*8975f5c5SAndroid Build Coastguard Worker {}
1738*8975f5c5SAndroid Build Coastguard Worker
~ResetBaseVertexBaseInstance()1739*8975f5c5SAndroid Build Coastguard Worker ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance()
1740*8975f5c5SAndroid Build Coastguard Worker {
1741*8975f5c5SAndroid Build Coastguard Worker if (mExecutable)
1742*8975f5c5SAndroid Build Coastguard Worker {
1743*8975f5c5SAndroid Build Coastguard Worker // Reset emulated uniforms to zero to avoid affecting other draw calls
1744*8975f5c5SAndroid Build Coastguard Worker if (mResetBaseVertex)
1745*8975f5c5SAndroid Build Coastguard Worker {
1746*8975f5c5SAndroid Build Coastguard Worker mExecutable->setBaseVertexUniform(0);
1747*8975f5c5SAndroid Build Coastguard Worker }
1748*8975f5c5SAndroid Build Coastguard Worker
1749*8975f5c5SAndroid Build Coastguard Worker if (mResetBaseInstance)
1750*8975f5c5SAndroid Build Coastguard Worker {
1751*8975f5c5SAndroid Build Coastguard Worker mExecutable->setBaseInstanceUniform(0);
1752*8975f5c5SAndroid Build Coastguard Worker }
1753*8975f5c5SAndroid Build Coastguard Worker }
1754*8975f5c5SAndroid Build Coastguard Worker }
1755*8975f5c5SAndroid Build Coastguard Worker
ConvertToSRGB(angle::FormatID formatID)1756*8975f5c5SAndroid Build Coastguard Worker angle::FormatID ConvertToSRGB(angle::FormatID formatID)
1757*8975f5c5SAndroid Build Coastguard Worker {
1758*8975f5c5SAndroid Build Coastguard Worker switch (formatID)
1759*8975f5c5SAndroid Build Coastguard Worker {
1760*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8_UNORM:
1761*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8_UNORM_SRGB;
1762*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8_UNORM:
1763*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8_UNORM_SRGB;
1764*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8B8_UNORM:
1765*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8B8_UNORM_SRGB;
1766*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8B8A8_UNORM:
1767*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8B8A8_UNORM_SRGB;
1768*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::B8G8R8A8_UNORM:
1769*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::B8G8R8A8_UNORM_SRGB;
1770*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC1_RGB_UNORM_BLOCK:
1771*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
1772*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC1_RGBA_UNORM_BLOCK:
1773*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
1774*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC2_RGBA_UNORM_BLOCK:
1775*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
1776*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC3_RGBA_UNORM_BLOCK:
1777*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
1778*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC7_RGBA_UNORM_BLOCK:
1779*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK;
1780*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
1781*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
1782*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
1783*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
1784*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
1785*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
1786*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_4x4_UNORM_BLOCK:
1787*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_4x4_SRGB_BLOCK;
1788*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_5x4_UNORM_BLOCK:
1789*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_5x4_SRGB_BLOCK;
1790*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_5x5_UNORM_BLOCK:
1791*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_5x5_SRGB_BLOCK;
1792*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_6x5_UNORM_BLOCK:
1793*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_6x5_SRGB_BLOCK;
1794*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_6x6_UNORM_BLOCK:
1795*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_6x6_SRGB_BLOCK;
1796*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x5_UNORM_BLOCK:
1797*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x5_SRGB_BLOCK;
1798*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x6_UNORM_BLOCK:
1799*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x6_SRGB_BLOCK;
1800*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x8_UNORM_BLOCK:
1801*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x8_SRGB_BLOCK;
1802*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x5_UNORM_BLOCK:
1803*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x5_SRGB_BLOCK;
1804*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x6_UNORM_BLOCK:
1805*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x6_SRGB_BLOCK;
1806*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x8_UNORM_BLOCK:
1807*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x8_SRGB_BLOCK;
1808*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x10_UNORM_BLOCK:
1809*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x10_SRGB_BLOCK;
1810*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_12x10_UNORM_BLOCK:
1811*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_12x10_SRGB_BLOCK;
1812*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_12x12_UNORM_BLOCK:
1813*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_12x12_SRGB_BLOCK;
1814*8975f5c5SAndroid Build Coastguard Worker default:
1815*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::NONE;
1816*8975f5c5SAndroid Build Coastguard Worker }
1817*8975f5c5SAndroid Build Coastguard Worker }
1818*8975f5c5SAndroid Build Coastguard Worker
ConvertToLinear(angle::FormatID formatID)1819*8975f5c5SAndroid Build Coastguard Worker angle::FormatID ConvertToLinear(angle::FormatID formatID)
1820*8975f5c5SAndroid Build Coastguard Worker {
1821*8975f5c5SAndroid Build Coastguard Worker switch (formatID)
1822*8975f5c5SAndroid Build Coastguard Worker {
1823*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8_UNORM_SRGB:
1824*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8_UNORM;
1825*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8_UNORM_SRGB:
1826*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8_UNORM;
1827*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8B8_UNORM_SRGB:
1828*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8B8_UNORM;
1829*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::R8G8B8A8_UNORM_SRGB:
1830*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::R8G8B8A8_UNORM;
1831*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::B8G8R8A8_UNORM_SRGB:
1832*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::B8G8R8A8_UNORM;
1833*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
1834*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC1_RGB_UNORM_BLOCK;
1835*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
1836*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC1_RGBA_UNORM_BLOCK;
1837*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK:
1838*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC2_RGBA_UNORM_BLOCK;
1839*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK:
1840*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC3_RGBA_UNORM_BLOCK;
1841*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK:
1842*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::BC7_RGBA_UNORM_BLOCK;
1843*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
1844*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
1845*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
1846*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
1847*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
1848*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
1849*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_4x4_SRGB_BLOCK:
1850*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_4x4_UNORM_BLOCK;
1851*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_5x4_SRGB_BLOCK:
1852*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_5x4_UNORM_BLOCK;
1853*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_5x5_SRGB_BLOCK:
1854*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_5x5_UNORM_BLOCK;
1855*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_6x5_SRGB_BLOCK:
1856*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_6x5_UNORM_BLOCK;
1857*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_6x6_SRGB_BLOCK:
1858*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_6x6_UNORM_BLOCK;
1859*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x5_SRGB_BLOCK:
1860*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x5_UNORM_BLOCK;
1861*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x6_SRGB_BLOCK:
1862*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x6_UNORM_BLOCK;
1863*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_8x8_SRGB_BLOCK:
1864*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_8x8_UNORM_BLOCK;
1865*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x5_SRGB_BLOCK:
1866*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x5_UNORM_BLOCK;
1867*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x6_SRGB_BLOCK:
1868*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x6_UNORM_BLOCK;
1869*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x8_SRGB_BLOCK:
1870*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x8_UNORM_BLOCK;
1871*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_10x10_SRGB_BLOCK:
1872*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_10x10_UNORM_BLOCK;
1873*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_12x10_SRGB_BLOCK:
1874*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_12x10_UNORM_BLOCK;
1875*8975f5c5SAndroid Build Coastguard Worker case angle::FormatID::ASTC_12x12_SRGB_BLOCK:
1876*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::ASTC_12x12_UNORM_BLOCK;
1877*8975f5c5SAndroid Build Coastguard Worker default:
1878*8975f5c5SAndroid Build Coastguard Worker return angle::FormatID::NONE;
1879*8975f5c5SAndroid Build Coastguard Worker }
1880*8975f5c5SAndroid Build Coastguard Worker }
1881*8975f5c5SAndroid Build Coastguard Worker
IsOverridableLinearFormat(angle::FormatID formatID)1882*8975f5c5SAndroid Build Coastguard Worker bool IsOverridableLinearFormat(angle::FormatID formatID)
1883*8975f5c5SAndroid Build Coastguard Worker {
1884*8975f5c5SAndroid Build Coastguard Worker return ConvertToSRGB(formatID) != angle::FormatID::NONE;
1885*8975f5c5SAndroid Build Coastguard Worker }
1886*8975f5c5SAndroid Build Coastguard Worker
1887*8975f5c5SAndroid Build Coastguard Worker template <bool swizzledLuma>
AdjustBorderColor(const angle::ColorGeneric & borderColorGeneric,const angle::Format & format,bool stencilMode)1888*8975f5c5SAndroid Build Coastguard Worker const gl::ColorGeneric AdjustBorderColor(const angle::ColorGeneric &borderColorGeneric,
1889*8975f5c5SAndroid Build Coastguard Worker const angle::Format &format,
1890*8975f5c5SAndroid Build Coastguard Worker bool stencilMode)
1891*8975f5c5SAndroid Build Coastguard Worker {
1892*8975f5c5SAndroid Build Coastguard Worker gl::ColorGeneric adjustedBorderColor = borderColorGeneric;
1893*8975f5c5SAndroid Build Coastguard Worker
1894*8975f5c5SAndroid Build Coastguard Worker // Handle depth formats
1895*8975f5c5SAndroid Build Coastguard Worker if (format.hasDepthOrStencilBits())
1896*8975f5c5SAndroid Build Coastguard Worker {
1897*8975f5c5SAndroid Build Coastguard Worker if (stencilMode)
1898*8975f5c5SAndroid Build Coastguard Worker {
1899*8975f5c5SAndroid Build Coastguard Worker // Stencil component
1900*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.red = gl::clampForBitCount<unsigned int>(
1901*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.red, format.stencilBits);
1902*8975f5c5SAndroid Build Coastguard Worker // Unused components need to be reset because some backends simulate integer samplers
1903*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.green = 0u;
1904*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.blue = 0u;
1905*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.alpha = 1u;
1906*8975f5c5SAndroid Build Coastguard Worker }
1907*8975f5c5SAndroid Build Coastguard Worker else
1908*8975f5c5SAndroid Build Coastguard Worker {
1909*8975f5c5SAndroid Build Coastguard Worker // Depth component
1910*8975f5c5SAndroid Build Coastguard Worker if (format.isUnorm())
1911*8975f5c5SAndroid Build Coastguard Worker {
1912*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = gl::clamp01(adjustedBorderColor.colorF.red);
1913*8975f5c5SAndroid Build Coastguard Worker }
1914*8975f5c5SAndroid Build Coastguard Worker }
1915*8975f5c5SAndroid Build Coastguard Worker
1916*8975f5c5SAndroid Build Coastguard Worker return adjustedBorderColor;
1917*8975f5c5SAndroid Build Coastguard Worker }
1918*8975f5c5SAndroid Build Coastguard Worker
1919*8975f5c5SAndroid Build Coastguard Worker // Handle LUMA formats
1920*8975f5c5SAndroid Build Coastguard Worker if (format.isLUMA())
1921*8975f5c5SAndroid Build Coastguard Worker {
1922*8975f5c5SAndroid Build Coastguard Worker if (format.isUnorm())
1923*8975f5c5SAndroid Build Coastguard Worker {
1924*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = gl::clamp01(adjustedBorderColor.colorF.red);
1925*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.alpha = gl::clamp01(adjustedBorderColor.colorF.alpha);
1926*8975f5c5SAndroid Build Coastguard Worker }
1927*8975f5c5SAndroid Build Coastguard Worker
1928*8975f5c5SAndroid Build Coastguard Worker // Luma formats are either unpacked to RGBA or emulated with component swizzling
1929*8975f5c5SAndroid Build Coastguard Worker if (swizzledLuma)
1930*8975f5c5SAndroid Build Coastguard Worker {
1931*8975f5c5SAndroid Build Coastguard Worker // L is R (no-op); A is R; LA is RG
1932*8975f5c5SAndroid Build Coastguard Worker if (format.alphaBits > 0)
1933*8975f5c5SAndroid Build Coastguard Worker {
1934*8975f5c5SAndroid Build Coastguard Worker if (format.luminanceBits > 0)
1935*8975f5c5SAndroid Build Coastguard Worker {
1936*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.green = adjustedBorderColor.colorF.alpha;
1937*8975f5c5SAndroid Build Coastguard Worker }
1938*8975f5c5SAndroid Build Coastguard Worker else
1939*8975f5c5SAndroid Build Coastguard Worker {
1940*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = adjustedBorderColor.colorF.alpha;
1941*8975f5c5SAndroid Build Coastguard Worker }
1942*8975f5c5SAndroid Build Coastguard Worker }
1943*8975f5c5SAndroid Build Coastguard Worker }
1944*8975f5c5SAndroid Build Coastguard Worker else
1945*8975f5c5SAndroid Build Coastguard Worker {
1946*8975f5c5SAndroid Build Coastguard Worker // L is RGBX; A is A or RGBA; LA is RGBA
1947*8975f5c5SAndroid Build Coastguard Worker if (format.alphaBits == 0)
1948*8975f5c5SAndroid Build Coastguard Worker {
1949*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.alpha = 1.0f;
1950*8975f5c5SAndroid Build Coastguard Worker }
1951*8975f5c5SAndroid Build Coastguard Worker else if (format.luminanceBits == 0)
1952*8975f5c5SAndroid Build Coastguard Worker {
1953*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = 0.0f;
1954*8975f5c5SAndroid Build Coastguard Worker }
1955*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.green = adjustedBorderColor.colorF.red;
1956*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.blue = adjustedBorderColor.colorF.red;
1957*8975f5c5SAndroid Build Coastguard Worker }
1958*8975f5c5SAndroid Build Coastguard Worker
1959*8975f5c5SAndroid Build Coastguard Worker return adjustedBorderColor;
1960*8975f5c5SAndroid Build Coastguard Worker }
1961*8975f5c5SAndroid Build Coastguard Worker
1962*8975f5c5SAndroid Build Coastguard Worker // Handle all other formats. Clamp border color to the ranges of color components.
1963*8975f5c5SAndroid Build Coastguard Worker // On some platforms, RGB formats may be emulated with RGBA, enforce opaque border color there.
1964*8975f5c5SAndroid Build Coastguard Worker if (format.isSint())
1965*8975f5c5SAndroid Build Coastguard Worker {
1966*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorI.red =
1967*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<int>(adjustedBorderColor.colorI.red, format.redBits);
1968*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorI.green =
1969*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<int>(adjustedBorderColor.colorI.green, format.greenBits);
1970*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorI.blue =
1971*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<int>(adjustedBorderColor.colorI.blue, format.blueBits);
1972*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorI.alpha =
1973*8975f5c5SAndroid Build Coastguard Worker format.alphaBits > 0
1974*8975f5c5SAndroid Build Coastguard Worker ? gl::clampForBitCount<int>(adjustedBorderColor.colorI.alpha, format.alphaBits)
1975*8975f5c5SAndroid Build Coastguard Worker : 1;
1976*8975f5c5SAndroid Build Coastguard Worker }
1977*8975f5c5SAndroid Build Coastguard Worker else if (format.isUint())
1978*8975f5c5SAndroid Build Coastguard Worker {
1979*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.red =
1980*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<unsigned int>(adjustedBorderColor.colorUI.red, format.redBits);
1981*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.green =
1982*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<unsigned int>(adjustedBorderColor.colorUI.green, format.greenBits);
1983*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.blue =
1984*8975f5c5SAndroid Build Coastguard Worker gl::clampForBitCount<unsigned int>(adjustedBorderColor.colorUI.blue, format.blueBits);
1985*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.alpha =
1986*8975f5c5SAndroid Build Coastguard Worker format.alphaBits > 0 ? gl::clampForBitCount<unsigned int>(
1987*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorUI.alpha, format.alphaBits)
1988*8975f5c5SAndroid Build Coastguard Worker : 1;
1989*8975f5c5SAndroid Build Coastguard Worker }
1990*8975f5c5SAndroid Build Coastguard Worker else if (format.isSnorm())
1991*8975f5c5SAndroid Build Coastguard Worker {
1992*8975f5c5SAndroid Build Coastguard Worker // clamp between -1.0f and 1.0f
1993*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = gl::clamp(adjustedBorderColor.colorF.red, -1.0f, 1.0f);
1994*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.green = gl::clamp(adjustedBorderColor.colorF.green, -1.0f, 1.0f);
1995*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.blue = gl::clamp(adjustedBorderColor.colorF.blue, -1.0f, 1.0f);
1996*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.alpha =
1997*8975f5c5SAndroid Build Coastguard Worker format.alphaBits > 0 ? gl::clamp(adjustedBorderColor.colorF.alpha, -1.0f, 1.0f) : 1.0f;
1998*8975f5c5SAndroid Build Coastguard Worker }
1999*8975f5c5SAndroid Build Coastguard Worker else if (format.isUnorm())
2000*8975f5c5SAndroid Build Coastguard Worker {
2001*8975f5c5SAndroid Build Coastguard Worker // clamp between 0.0f and 1.0f
2002*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.red = gl::clamp01(adjustedBorderColor.colorF.red);
2003*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.green = gl::clamp01(adjustedBorderColor.colorF.green);
2004*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.blue = gl::clamp01(adjustedBorderColor.colorF.blue);
2005*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.alpha =
2006*8975f5c5SAndroid Build Coastguard Worker format.alphaBits > 0 ? gl::clamp01(adjustedBorderColor.colorF.alpha) : 1.0f;
2007*8975f5c5SAndroid Build Coastguard Worker }
2008*8975f5c5SAndroid Build Coastguard Worker else if (format.isFloat() && format.alphaBits == 0)
2009*8975f5c5SAndroid Build Coastguard Worker {
2010*8975f5c5SAndroid Build Coastguard Worker adjustedBorderColor.colorF.alpha = 1.0;
2011*8975f5c5SAndroid Build Coastguard Worker }
2012*8975f5c5SAndroid Build Coastguard Worker
2013*8975f5c5SAndroid Build Coastguard Worker return adjustedBorderColor;
2014*8975f5c5SAndroid Build Coastguard Worker }
2015*8975f5c5SAndroid Build Coastguard Worker
2016*8975f5c5SAndroid Build Coastguard Worker template const gl::ColorGeneric AdjustBorderColor<true>(
2017*8975f5c5SAndroid Build Coastguard Worker const angle::ColorGeneric &borderColorGeneric,
2018*8975f5c5SAndroid Build Coastguard Worker const angle::Format &format,
2019*8975f5c5SAndroid Build Coastguard Worker bool stencilMode);
2020*8975f5c5SAndroid Build Coastguard Worker template const gl::ColorGeneric AdjustBorderColor<false>(
2021*8975f5c5SAndroid Build Coastguard Worker const angle::ColorGeneric &borderColorGeneric,
2022*8975f5c5SAndroid Build Coastguard Worker const angle::Format &format,
2023*8975f5c5SAndroid Build Coastguard Worker bool stencilMode);
2024*8975f5c5SAndroid Build Coastguard Worker
TextureHasAnyRedefinedLevels(const gl::CubeFaceArray<gl::TexLevelMask> & redefinedLevels)2025*8975f5c5SAndroid Build Coastguard Worker bool TextureHasAnyRedefinedLevels(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels)
2026*8975f5c5SAndroid Build Coastguard Worker {
2027*8975f5c5SAndroid Build Coastguard Worker for (gl::TexLevelMask faceRedefinedLevels : redefinedLevels)
2028*8975f5c5SAndroid Build Coastguard Worker {
2029*8975f5c5SAndroid Build Coastguard Worker if (faceRedefinedLevels.any())
2030*8975f5c5SAndroid Build Coastguard Worker {
2031*8975f5c5SAndroid Build Coastguard Worker return true;
2032*8975f5c5SAndroid Build Coastguard Worker }
2033*8975f5c5SAndroid Build Coastguard Worker }
2034*8975f5c5SAndroid Build Coastguard Worker
2035*8975f5c5SAndroid Build Coastguard Worker return false;
2036*8975f5c5SAndroid Build Coastguard Worker }
2037*8975f5c5SAndroid Build Coastguard Worker
IsTextureLevelRedefined(const gl::CubeFaceArray<gl::TexLevelMask> & redefinedLevels,gl::TextureType textureType,gl::LevelIndex level)2038*8975f5c5SAndroid Build Coastguard Worker bool IsTextureLevelRedefined(const gl::CubeFaceArray<gl::TexLevelMask> &redefinedLevels,
2039*8975f5c5SAndroid Build Coastguard Worker gl::TextureType textureType,
2040*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex level)
2041*8975f5c5SAndroid Build Coastguard Worker {
2042*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask redefined = redefinedLevels[0];
2043*8975f5c5SAndroid Build Coastguard Worker
2044*8975f5c5SAndroid Build Coastguard Worker if (textureType == gl::TextureType::CubeMap)
2045*8975f5c5SAndroid Build Coastguard Worker {
2046*8975f5c5SAndroid Build Coastguard Worker for (size_t face = 1; face < gl::kCubeFaceCount; ++face)
2047*8975f5c5SAndroid Build Coastguard Worker {
2048*8975f5c5SAndroid Build Coastguard Worker redefined |= redefinedLevels[face];
2049*8975f5c5SAndroid Build Coastguard Worker }
2050*8975f5c5SAndroid Build Coastguard Worker }
2051*8975f5c5SAndroid Build Coastguard Worker
2052*8975f5c5SAndroid Build Coastguard Worker return redefined.test(level.get());
2053*8975f5c5SAndroid Build Coastguard Worker }
2054*8975f5c5SAndroid Build Coastguard Worker
TextureRedefineLevel(const TextureLevelAllocation levelAllocation,const TextureLevelDefinition levelDefinition,bool immutableFormat,uint32_t levelCount,const uint32_t layerIndex,const gl::ImageIndex & index,gl::LevelIndex imageFirstAllocatedLevel,gl::CubeFaceArray<gl::TexLevelMask> * redefinedLevels)2055*8975f5c5SAndroid Build Coastguard Worker bool TextureRedefineLevel(const TextureLevelAllocation levelAllocation,
2056*8975f5c5SAndroid Build Coastguard Worker const TextureLevelDefinition levelDefinition,
2057*8975f5c5SAndroid Build Coastguard Worker bool immutableFormat,
2058*8975f5c5SAndroid Build Coastguard Worker uint32_t levelCount,
2059*8975f5c5SAndroid Build Coastguard Worker const uint32_t layerIndex,
2060*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
2061*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex imageFirstAllocatedLevel,
2062*8975f5c5SAndroid Build Coastguard Worker gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels)
2063*8975f5c5SAndroid Build Coastguard Worker {
2064*8975f5c5SAndroid Build Coastguard Worker // If the level that's being redefined is outside the level range of the allocated
2065*8975f5c5SAndroid Build Coastguard Worker // image, the application is free to use any size or format. Any data uploaded to it
2066*8975f5c5SAndroid Build Coastguard Worker // will live in staging area until the texture base/max level is adjusted to include
2067*8975f5c5SAndroid Build Coastguard Worker // this level, at which point the image will be recreated.
2068*8975f5c5SAndroid Build Coastguard Worker //
2069*8975f5c5SAndroid Build Coastguard Worker // Otherwise, if the level that's being redefined has a different format or size,
2070*8975f5c5SAndroid Build Coastguard Worker // only release the image if it's single-mip, and keep the uploaded data staged.
2071*8975f5c5SAndroid Build Coastguard Worker // Otherwise the image is mip-incomplete anyway and will be eventually recreated when
2072*8975f5c5SAndroid Build Coastguard Worker // needed. Only exception to this latter is if all the levels of the texture are
2073*8975f5c5SAndroid Build Coastguard Worker // redefined such that the image becomes mip-complete in the end.
2074*8975f5c5SAndroid Build Coastguard Worker // redefinedLevels is used during syncState to support this use-case.
2075*8975f5c5SAndroid Build Coastguard Worker //
2076*8975f5c5SAndroid Build Coastguard Worker // Note that if the image has multiple mips, there could be a copy from one mip
2077*8975f5c5SAndroid Build Coastguard Worker // happening to the other, which means the image cannot be released.
2078*8975f5c5SAndroid Build Coastguard Worker //
2079*8975f5c5SAndroid Build Coastguard Worker // In summary:
2080*8975f5c5SAndroid Build Coastguard Worker //
2081*8975f5c5SAndroid Build Coastguard Worker // - If the image has a single level, and that level is being redefined, release the
2082*8975f5c5SAndroid Build Coastguard Worker // image.
2083*8975f5c5SAndroid Build Coastguard Worker // - Otherwise keep the image intact (another mip may be the source of a copy), and
2084*8975f5c5SAndroid Build Coastguard Worker // make sure any updates to this level are staged.
2085*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex levelIndexGL(index.getLevelIndex());
2086*8975f5c5SAndroid Build Coastguard Worker const bool isCompatibleRedefinition =
2087*8975f5c5SAndroid Build Coastguard Worker levelAllocation == TextureLevelAllocation::WithinAllocatedImage &&
2088*8975f5c5SAndroid Build Coastguard Worker levelDefinition == TextureLevelDefinition::Compatible;
2089*8975f5c5SAndroid Build Coastguard Worker const bool isCubeMap = index.getType() == gl::TextureType::CubeMap;
2090*8975f5c5SAndroid Build Coastguard Worker
2091*8975f5c5SAndroid Build Coastguard Worker // Mark the level as incompatibly redefined if that's the case. Note that if the level
2092*8975f5c5SAndroid Build Coastguard Worker // was previously incompatibly defined, then later redefined to be compatible, the
2093*8975f5c5SAndroid Build Coastguard Worker // corresponding bit should clear.
2094*8975f5c5SAndroid Build Coastguard Worker if (levelAllocation == TextureLevelAllocation::WithinAllocatedImage)
2095*8975f5c5SAndroid Build Coastguard Worker {
2096*8975f5c5SAndroid Build Coastguard Worker // Immutable texture should never have levels redefined.
2097*8975f5c5SAndroid Build Coastguard Worker ASSERT(isCompatibleRedefinition || !immutableFormat);
2098*8975f5c5SAndroid Build Coastguard Worker
2099*8975f5c5SAndroid Build Coastguard Worker const uint32_t redefinedFace = isCubeMap ? layerIndex : 0;
2100*8975f5c5SAndroid Build Coastguard Worker (*redefinedLevels)[redefinedFace].set(levelIndexGL.get(), !isCompatibleRedefinition);
2101*8975f5c5SAndroid Build Coastguard Worker }
2102*8975f5c5SAndroid Build Coastguard Worker
2103*8975f5c5SAndroid Build Coastguard Worker const bool isUpdateToSingleLevelImage =
2104*8975f5c5SAndroid Build Coastguard Worker levelCount == 1 && imageFirstAllocatedLevel == levelIndexGL;
2105*8975f5c5SAndroid Build Coastguard Worker
2106*8975f5c5SAndroid Build Coastguard Worker // If incompatible, and redefining the single-level image, the caller will release the texture
2107*8975f5c5SAndroid Build Coastguard Worker // so it can be recreated immediately. This is needed so that the texture can be reallocated
2108*8975f5c5SAndroid Build Coastguard Worker // with the correct format/size.
2109*8975f5c5SAndroid Build Coastguard Worker //
2110*8975f5c5SAndroid Build Coastguard Worker // This is not done for cubemaps because every face may be separately redefined. Note
2111*8975f5c5SAndroid Build Coastguard Worker // that this is not possible for texture arrays in general.
2112*8975f5c5SAndroid Build Coastguard Worker bool shouldReleaseImage = !isCompatibleRedefinition && isUpdateToSingleLevelImage && !isCubeMap;
2113*8975f5c5SAndroid Build Coastguard Worker return shouldReleaseImage;
2114*8975f5c5SAndroid Build Coastguard Worker }
2115*8975f5c5SAndroid Build Coastguard Worker
TextureRedefineGenerateMipmapLevels(gl::LevelIndex baseLevel,gl::LevelIndex maxLevel,gl::LevelIndex firstGeneratedLevel,gl::CubeFaceArray<gl::TexLevelMask> * redefinedLevels)2116*8975f5c5SAndroid Build Coastguard Worker void TextureRedefineGenerateMipmapLevels(gl::LevelIndex baseLevel,
2117*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex maxLevel,
2118*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex firstGeneratedLevel,
2119*8975f5c5SAndroid Build Coastguard Worker gl::CubeFaceArray<gl::TexLevelMask> *redefinedLevels)
2120*8975f5c5SAndroid Build Coastguard Worker {
2121*8975f5c5SAndroid Build Coastguard Worker static_assert(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS < 32,
2122*8975f5c5SAndroid Build Coastguard Worker "levels mask assumes 32-bits is enough");
2123*8975f5c5SAndroid Build Coastguard Worker // Generate bitmask for (baseLevel, maxLevel]. `+1` because bitMask takes `the number of bits`
2124*8975f5c5SAndroid Build Coastguard Worker // but levels start counting from 0
2125*8975f5c5SAndroid Build Coastguard Worker gl::TexLevelMask levelsMask(angle::BitMask<uint32_t>(maxLevel.get() + 1));
2126*8975f5c5SAndroid Build Coastguard Worker levelsMask &= static_cast<uint32_t>(~angle::BitMask<uint32_t>(firstGeneratedLevel.get()));
2127*8975f5c5SAndroid Build Coastguard Worker // Remove (baseLevel, maxLevel] from redefinedLevels. These levels are no longer incompatibly
2128*8975f5c5SAndroid Build Coastguard Worker // defined if they previously were. The corresponding bits in redefinedLevels should be
2129*8975f5c5SAndroid Build Coastguard Worker // cleared.
2130*8975f5c5SAndroid Build Coastguard Worker for (size_t face = 0; face < gl::kCubeFaceCount; ++face)
2131*8975f5c5SAndroid Build Coastguard Worker {
2132*8975f5c5SAndroid Build Coastguard Worker (*redefinedLevels)[face] &= ~levelsMask;
2133*8975f5c5SAndroid Build Coastguard Worker }
2134*8975f5c5SAndroid Build Coastguard Worker }
2135*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
2136