1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 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 // AttributeLayoutTest:
7*8975f5c5SAndroid Build Coastguard Worker // Test various layouts of vertex attribute data:
8*8975f5c5SAndroid Build Coastguard Worker // - in memory, in buffer object, or combination of both
9*8975f5c5SAndroid Build Coastguard Worker // - sequential or interleaved
10*8975f5c5SAndroid Build Coastguard Worker // - various combinations of data types
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include <vector>
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard Worker // Test will draw these four triangles.
23*8975f5c5SAndroid Build Coastguard Worker // clang-format off
24*8975f5c5SAndroid Build Coastguard Worker constexpr double kTriangleData[] = {
25*8975f5c5SAndroid Build Coastguard Worker // xy rgb
26*8975f5c5SAndroid Build Coastguard Worker 0,0, 1,1,0,
27*8975f5c5SAndroid Build Coastguard Worker -1,+1, 1,1,0,
28*8975f5c5SAndroid Build Coastguard Worker +1,+1, 1,1,0,
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Worker 0,0, 0,1,0,
31*8975f5c5SAndroid Build Coastguard Worker +1,+1, 0,1,0,
32*8975f5c5SAndroid Build Coastguard Worker +1,-1, 0,1,0,
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker 0,0, 0,1,1,
35*8975f5c5SAndroid Build Coastguard Worker +1,-1, 0,1,1,
36*8975f5c5SAndroid Build Coastguard Worker -1,-1, 0,1,1,
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker 0,0, 1,0,1,
39*8975f5c5SAndroid Build Coastguard Worker -1,-1, 1,0,1,
40*8975f5c5SAndroid Build Coastguard Worker -1,+1, 1,0,1,
41*8975f5c5SAndroid Build Coastguard Worker };
42*8975f5c5SAndroid Build Coastguard Worker // clang-format on
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kNumVertices = ArraySize(kTriangleData) / 5;
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker // Vertex data source description.
47*8975f5c5SAndroid Build Coastguard Worker class VertexData
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker public:
VertexData(int dimension,const double * data,unsigned offset,unsigned stride,unsigned numVertices)50*8975f5c5SAndroid Build Coastguard Worker VertexData(int dimension,
51*8975f5c5SAndroid Build Coastguard Worker const double *data,
52*8975f5c5SAndroid Build Coastguard Worker unsigned offset,
53*8975f5c5SAndroid Build Coastguard Worker unsigned stride,
54*8975f5c5SAndroid Build Coastguard Worker unsigned numVertices)
55*8975f5c5SAndroid Build Coastguard Worker : mNumVertices(numVertices),
56*8975f5c5SAndroid Build Coastguard Worker mDimension(dimension),
57*8975f5c5SAndroid Build Coastguard Worker mData(data),
58*8975f5c5SAndroid Build Coastguard Worker mOffset(offset),
59*8975f5c5SAndroid Build Coastguard Worker mStride(stride)
60*8975f5c5SAndroid Build Coastguard Worker {}
getDimension() const61*8975f5c5SAndroid Build Coastguard Worker int getDimension() const { return mDimension; }
getNumVertices() const62*8975f5c5SAndroid Build Coastguard Worker unsigned getNumVertices() const { return mNumVertices; }
getValue(unsigned vertexNumber,int component) const63*8975f5c5SAndroid Build Coastguard Worker double getValue(unsigned vertexNumber, int component) const
64*8975f5c5SAndroid Build Coastguard Worker {
65*8975f5c5SAndroid Build Coastguard Worker return mData[mOffset + mStride * vertexNumber + component];
66*8975f5c5SAndroid Build Coastguard Worker }
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker private:
69*8975f5c5SAndroid Build Coastguard Worker unsigned mNumVertices;
70*8975f5c5SAndroid Build Coastguard Worker int mDimension;
71*8975f5c5SAndroid Build Coastguard Worker const double *mData;
72*8975f5c5SAndroid Build Coastguard Worker // offset and stride in doubles
73*8975f5c5SAndroid Build Coastguard Worker unsigned mOffset;
74*8975f5c5SAndroid Build Coastguard Worker unsigned mStride;
75*8975f5c5SAndroid Build Coastguard Worker };
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Worker // A container for one or more vertex attributes.
78*8975f5c5SAndroid Build Coastguard Worker class Container
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker public:
81*8975f5c5SAndroid Build Coastguard Worker static constexpr size_t kSize = 1024;
82*8975f5c5SAndroid Build Coastguard Worker
open(void)83*8975f5c5SAndroid Build Coastguard Worker void open(void) { memset(mMemory, 0xff, kSize); }
getDestination(size_t offset)84*8975f5c5SAndroid Build Coastguard Worker void *getDestination(size_t offset) { return mMemory + offset; }
close(void)85*8975f5c5SAndroid Build Coastguard Worker virtual void close(void) {}
~Container()86*8975f5c5SAndroid Build Coastguard Worker virtual ~Container() {}
87*8975f5c5SAndroid Build Coastguard Worker virtual const char *getAddress() = 0;
88*8975f5c5SAndroid Build Coastguard Worker virtual GLuint getBuffer() = 0;
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker protected:
91*8975f5c5SAndroid Build Coastguard Worker char mMemory[kSize];
92*8975f5c5SAndroid Build Coastguard Worker };
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker // Vertex attribute data in client memory.
95*8975f5c5SAndroid Build Coastguard Worker class Memory : public Container
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker public:
getAddress()98*8975f5c5SAndroid Build Coastguard Worker const char *getAddress() override { return mMemory; }
getBuffer()99*8975f5c5SAndroid Build Coastguard Worker GLuint getBuffer() override { return 0; }
100*8975f5c5SAndroid Build Coastguard Worker };
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker // Vertex attribute data in buffer object.
103*8975f5c5SAndroid Build Coastguard Worker class Buffer : public Container
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker public:
close(void)106*8975f5c5SAndroid Build Coastguard Worker void close(void) override
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
109*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, sizeof(mMemory), mMemory, GL_STATIC_DRAW);
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker
getAddress()112*8975f5c5SAndroid Build Coastguard Worker const char *getAddress() override { return nullptr; }
getBuffer()113*8975f5c5SAndroid Build Coastguard Worker GLuint getBuffer() override { return mBuffer; }
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker protected:
116*8975f5c5SAndroid Build Coastguard Worker GLBuffer mBuffer;
117*8975f5c5SAndroid Build Coastguard Worker };
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker // Encapsulate the storage, layout, format and data of a vertex attribute.
120*8975f5c5SAndroid Build Coastguard Worker struct Attrib
121*8975f5c5SAndroid Build Coastguard Worker {
openContainer__anon4c90fb2d0111::Attrib122*8975f5c5SAndroid Build Coastguard Worker void openContainer(void) const { mContainer->open(); }
123*8975f5c5SAndroid Build Coastguard Worker
fillContainer__anon4c90fb2d0111::Attrib124*8975f5c5SAndroid Build Coastguard Worker void fillContainer(void) const
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker for (unsigned i = 0; i < mData.getNumVertices(); ++i)
127*8975f5c5SAndroid Build Coastguard Worker {
128*8975f5c5SAndroid Build Coastguard Worker for (int j = 0; j < mData.getDimension(); ++j)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker size_t destOffset = mOffset + mStride * i + mCTypeSize * j;
131*8975f5c5SAndroid Build Coastguard Worker if (destOffset + mCTypeSize > Container::kSize)
132*8975f5c5SAndroid Build Coastguard Worker FAIL() << "test case does not fit container";
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Worker double value = mData.getValue(i, j);
135*8975f5c5SAndroid Build Coastguard Worker if (mGLType == GL_FIXED)
136*8975f5c5SAndroid Build Coastguard Worker value *= 1 << 16;
137*8975f5c5SAndroid Build Coastguard Worker else if (mNormalized)
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker if (value < mMinIn || value > mMaxIn)
140*8975f5c5SAndroid Build Coastguard Worker FAIL() << "test data does not fit format";
141*8975f5c5SAndroid Build Coastguard Worker value = (value - mMinIn) * mScale + mMinOut;
142*8975f5c5SAndroid Build Coastguard Worker }
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Worker mStore(value, mContainer->getDestination(destOffset));
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker }
147*8975f5c5SAndroid Build Coastguard Worker }
148*8975f5c5SAndroid Build Coastguard Worker
closeContainer__anon4c90fb2d0111::Attrib149*8975f5c5SAndroid Build Coastguard Worker void closeContainer(void) const { mContainer->close(); }
150*8975f5c5SAndroid Build Coastguard Worker
enable__anon4c90fb2d0111::Attrib151*8975f5c5SAndroid Build Coastguard Worker void enable(unsigned index) const
152*8975f5c5SAndroid Build Coastguard Worker {
153*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, mContainer->getBuffer());
154*8975f5c5SAndroid Build Coastguard Worker if (mPureInteger)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker glVertexAttribIPointer(index, mData.getDimension(), mGLType, mStride,
157*8975f5c5SAndroid Build Coastguard Worker mContainer->getAddress() + mOffset);
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker else
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(index, mData.getDimension(), mGLType, mNormalized, mStride,
162*8975f5c5SAndroid Build Coastguard Worker mContainer->getAddress() + mOffset);
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
165*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(index);
166*8975f5c5SAndroid Build Coastguard Worker }
167*8975f5c5SAndroid Build Coastguard Worker
inClientMemory__anon4c90fb2d0111::Attrib168*8975f5c5SAndroid Build Coastguard Worker bool inClientMemory(void) const { return mContainer->getAddress() != nullptr; }
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> mContainer;
171*8975f5c5SAndroid Build Coastguard Worker unsigned mOffset;
172*8975f5c5SAndroid Build Coastguard Worker unsigned mStride;
173*8975f5c5SAndroid Build Coastguard Worker const VertexData &mData;
174*8975f5c5SAndroid Build Coastguard Worker void (*mStore)(double value, void *dest);
175*8975f5c5SAndroid Build Coastguard Worker GLenum mGLType;
176*8975f5c5SAndroid Build Coastguard Worker GLboolean mNormalized;
177*8975f5c5SAndroid Build Coastguard Worker GLboolean mPureInteger = GL_FALSE;
178*8975f5c5SAndroid Build Coastguard Worker size_t mCTypeSize;
179*8975f5c5SAndroid Build Coastguard Worker double mMinIn;
180*8975f5c5SAndroid Build Coastguard Worker double mMaxIn;
181*8975f5c5SAndroid Build Coastguard Worker double mMinOut;
182*8975f5c5SAndroid Build Coastguard Worker double mScale;
183*8975f5c5SAndroid Build Coastguard Worker };
184*8975f5c5SAndroid Build Coastguard Worker
185*8975f5c5SAndroid Build Coastguard Worker // Change type and store.
186*8975f5c5SAndroid Build Coastguard Worker template <class T>
Store(double value,void * dest)187*8975f5c5SAndroid Build Coastguard Worker void Store(double value, void *dest)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker T v = static_cast<T>(value);
190*8975f5c5SAndroid Build Coastguard Worker memcpy(dest, &v, sizeof(v));
191*8975f5c5SAndroid Build Coastguard Worker }
192*8975f5c5SAndroid Build Coastguard Worker
193*8975f5c5SAndroid Build Coastguard Worker // Function object that makes Attrib structs according to a vertex format.
194*8975f5c5SAndroid Build Coastguard Worker template <class CType, GLenum GLType, bool Normalized, bool PureInteger = false>
195*8975f5c5SAndroid Build Coastguard Worker class Format
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker static_assert(!(Normalized && GLType == GL_FLOAT), "Normalized float does not make sense.");
198*8975f5c5SAndroid Build Coastguard Worker
199*8975f5c5SAndroid Build Coastguard Worker public:
Format(bool es3)200*8975f5c5SAndroid Build Coastguard Worker Format(bool es3) : mES3(es3) {}
201*8975f5c5SAndroid Build Coastguard Worker
operator ()(std::shared_ptr<Container> container,unsigned offset,unsigned stride,const VertexData & data) const202*8975f5c5SAndroid Build Coastguard Worker Attrib operator()(std::shared_ptr<Container> container,
203*8975f5c5SAndroid Build Coastguard Worker unsigned offset,
204*8975f5c5SAndroid Build Coastguard Worker unsigned stride,
205*8975f5c5SAndroid Build Coastguard Worker const VertexData &data) const
206*8975f5c5SAndroid Build Coastguard Worker {
207*8975f5c5SAndroid Build Coastguard Worker double minIn = 0;
208*8975f5c5SAndroid Build Coastguard Worker double maxIn = 1;
209*8975f5c5SAndroid Build Coastguard Worker double minOut = std::numeric_limits<CType>::min();
210*8975f5c5SAndroid Build Coastguard Worker double rangeOut = std::numeric_limits<CType>::max() - minOut;
211*8975f5c5SAndroid Build Coastguard Worker
212*8975f5c5SAndroid Build Coastguard Worker if (std::is_signed<CType>::value)
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker minIn = -1;
215*8975f5c5SAndroid Build Coastguard Worker maxIn = +1;
216*8975f5c5SAndroid Build Coastguard Worker if (mES3)
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker minOut += 1;
219*8975f5c5SAndroid Build Coastguard Worker rangeOut -= 1;
220*8975f5c5SAndroid Build Coastguard Worker }
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker
223*8975f5c5SAndroid Build Coastguard Worker return {
224*8975f5c5SAndroid Build Coastguard Worker container,
225*8975f5c5SAndroid Build Coastguard Worker offset,
226*8975f5c5SAndroid Build Coastguard Worker stride,
227*8975f5c5SAndroid Build Coastguard Worker data,
228*8975f5c5SAndroid Build Coastguard Worker Store<CType>,
229*8975f5c5SAndroid Build Coastguard Worker GLType,
230*8975f5c5SAndroid Build Coastguard Worker Normalized,
231*8975f5c5SAndroid Build Coastguard Worker PureInteger,
232*8975f5c5SAndroid Build Coastguard Worker sizeof(CType),
233*8975f5c5SAndroid Build Coastguard Worker minIn,
234*8975f5c5SAndroid Build Coastguard Worker maxIn,
235*8975f5c5SAndroid Build Coastguard Worker minOut,
236*8975f5c5SAndroid Build Coastguard Worker rangeOut / (maxIn - minIn),
237*8975f5c5SAndroid Build Coastguard Worker };
238*8975f5c5SAndroid Build Coastguard Worker }
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker protected:
241*8975f5c5SAndroid Build Coastguard Worker const bool mES3;
242*8975f5c5SAndroid Build Coastguard Worker };
243*8975f5c5SAndroid Build Coastguard Worker
244*8975f5c5SAndroid Build Coastguard Worker typedef std::vector<Attrib> TestCase;
245*8975f5c5SAndroid Build Coastguard Worker
PrepareTestCase(const TestCase & tc)246*8975f5c5SAndroid Build Coastguard Worker void PrepareTestCase(const TestCase &tc)
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker for (const Attrib &a : tc)
249*8975f5c5SAndroid Build Coastguard Worker a.openContainer();
250*8975f5c5SAndroid Build Coastguard Worker for (const Attrib &a : tc)
251*8975f5c5SAndroid Build Coastguard Worker a.fillContainer();
252*8975f5c5SAndroid Build Coastguard Worker for (const Attrib &a : tc)
253*8975f5c5SAndroid Build Coastguard Worker a.closeContainer();
254*8975f5c5SAndroid Build Coastguard Worker unsigned i = 0;
255*8975f5c5SAndroid Build Coastguard Worker for (const Attrib &a : tc)
256*8975f5c5SAndroid Build Coastguard Worker a.enable(i++);
257*8975f5c5SAndroid Build Coastguard Worker }
258*8975f5c5SAndroid Build Coastguard Worker
259*8975f5c5SAndroid Build Coastguard Worker class AttributeLayoutTest : public ANGLETest<>
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker protected:
AttributeLayoutTest()262*8975f5c5SAndroid Build Coastguard Worker AttributeLayoutTest()
263*8975f5c5SAndroid Build Coastguard Worker : mProgram(0),
264*8975f5c5SAndroid Build Coastguard Worker mCoord(2, kTriangleData, 0, 5, kNumVertices),
265*8975f5c5SAndroid Build Coastguard Worker mColor(3, kTriangleData, 2, 5, kNumVertices)
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
268*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
269*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
270*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
271*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
272*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
273*8975f5c5SAndroid Build Coastguard Worker }
274*8975f5c5SAndroid Build Coastguard Worker
275*8975f5c5SAndroid Build Coastguard Worker void GetTestCases(void);
276*8975f5c5SAndroid Build Coastguard Worker
testSetUp()277*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override
278*8975f5c5SAndroid Build Coastguard Worker {
279*8975f5c5SAndroid Build Coastguard Worker glClearColor(.2f, .2f, .2f, .0f);
280*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
283*8975f5c5SAndroid Build Coastguard Worker
284*8975f5c5SAndroid Build Coastguard Worker constexpr char kVS[] =
285*8975f5c5SAndroid Build Coastguard Worker "attribute mediump vec2 coord;\n"
286*8975f5c5SAndroid Build Coastguard Worker "attribute mediump vec3 color;\n"
287*8975f5c5SAndroid Build Coastguard Worker "varying mediump vec3 vcolor;\n"
288*8975f5c5SAndroid Build Coastguard Worker "void main(void)\n"
289*8975f5c5SAndroid Build Coastguard Worker "{\n"
290*8975f5c5SAndroid Build Coastguard Worker " gl_Position = vec4(coord, 0, 1);\n"
291*8975f5c5SAndroid Build Coastguard Worker " vcolor = color;\n"
292*8975f5c5SAndroid Build Coastguard Worker "}\n";
293*8975f5c5SAndroid Build Coastguard Worker
294*8975f5c5SAndroid Build Coastguard Worker constexpr char kFS[] =
295*8975f5c5SAndroid Build Coastguard Worker "varying mediump vec3 vcolor;\n"
296*8975f5c5SAndroid Build Coastguard Worker "void main(void)\n"
297*8975f5c5SAndroid Build Coastguard Worker "{\n"
298*8975f5c5SAndroid Build Coastguard Worker " gl_FragColor = vec4(vcolor, 0);\n"
299*8975f5c5SAndroid Build Coastguard Worker "}\n";
300*8975f5c5SAndroid Build Coastguard Worker
301*8975f5c5SAndroid Build Coastguard Worker mProgram = CompileProgram(kVS, kFS);
302*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mProgram);
303*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mProgram);
304*8975f5c5SAndroid Build Coastguard Worker
305*8975f5c5SAndroid Build Coastguard Worker glGenBuffers(1, &mIndexBuffer);
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker GetTestCases();
308*8975f5c5SAndroid Build Coastguard Worker }
309*8975f5c5SAndroid Build Coastguard Worker
testTearDown()310*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
311*8975f5c5SAndroid Build Coastguard Worker {
312*8975f5c5SAndroid Build Coastguard Worker mTestCases.clear();
313*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mProgram);
314*8975f5c5SAndroid Build Coastguard Worker glDeleteBuffers(1, &mIndexBuffer);
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker
Skip(const TestCase &)317*8975f5c5SAndroid Build Coastguard Worker virtual bool Skip(const TestCase &) { return false; }
318*8975f5c5SAndroid Build Coastguard Worker virtual void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) = 0;
319*8975f5c5SAndroid Build Coastguard Worker
Run(bool drawFirstTriangle)320*8975f5c5SAndroid Build Coastguard Worker void Run(bool drawFirstTriangle)
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, getWindowWidth(), getWindowHeight());
323*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mProgram);
324*8975f5c5SAndroid Build Coastguard Worker
325*8975f5c5SAndroid Build Coastguard Worker for (unsigned i = 0; i < mTestCases.size(); ++i)
326*8975f5c5SAndroid Build Coastguard Worker {
327*8975f5c5SAndroid Build Coastguard Worker if (mTestCases[i].size() == 0 || Skip(mTestCases[i]))
328*8975f5c5SAndroid Build Coastguard Worker continue;
329*8975f5c5SAndroid Build Coastguard Worker
330*8975f5c5SAndroid Build Coastguard Worker PrepareTestCase(mTestCases[i]);
331*8975f5c5SAndroid Build Coastguard Worker
332*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
333*8975f5c5SAndroid Build Coastguard Worker
334*8975f5c5SAndroid Build Coastguard Worker std::string testCase;
335*8975f5c5SAndroid Build Coastguard Worker if (drawFirstTriangle)
336*8975f5c5SAndroid Build Coastguard Worker {
337*8975f5c5SAndroid Build Coastguard Worker Draw(0, kNumVertices, mIndices);
338*8975f5c5SAndroid Build Coastguard Worker testCase = "draw";
339*8975f5c5SAndroid Build Coastguard Worker }
340*8975f5c5SAndroid Build Coastguard Worker else
341*8975f5c5SAndroid Build Coastguard Worker {
342*8975f5c5SAndroid Build Coastguard Worker Draw(3, kNumVertices - 3, mIndices + 3);
343*8975f5c5SAndroid Build Coastguard Worker testCase = "skip";
344*8975f5c5SAndroid Build Coastguard Worker }
345*8975f5c5SAndroid Build Coastguard Worker
346*8975f5c5SAndroid Build Coastguard Worker testCase += " first triangle case ";
347*8975f5c5SAndroid Build Coastguard Worker int w = getWindowWidth() / 4;
348*8975f5c5SAndroid Build Coastguard Worker int h = getWindowHeight() / 4;
349*8975f5c5SAndroid Build Coastguard Worker if (drawFirstTriangle)
350*8975f5c5SAndroid Build Coastguard Worker {
351*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_EQ(w * 2, h * 3, 255, 255, 0, 0) << testCase << i;
352*8975f5c5SAndroid Build Coastguard Worker }
353*8975f5c5SAndroid Build Coastguard Worker else
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_EQ(w * 2, h * 3, 51, 51, 51, 0) << testCase << i;
356*8975f5c5SAndroid Build Coastguard Worker }
357*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_EQ(w * 3, h * 2, 0, 255, 0, 0) << testCase << i;
358*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_EQ(w * 2, h * 1, 0, 255, 255, 0) << testCase << i;
359*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_EQ(w * 1, h * 2, 255, 0, 255, 0) << testCase << i;
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker }
362*8975f5c5SAndroid Build Coastguard Worker
363*8975f5c5SAndroid Build Coastguard Worker static const GLushort mIndices[kNumVertices];
364*8975f5c5SAndroid Build Coastguard Worker
365*8975f5c5SAndroid Build Coastguard Worker GLuint mProgram;
366*8975f5c5SAndroid Build Coastguard Worker GLuint mIndexBuffer;
367*8975f5c5SAndroid Build Coastguard Worker
368*8975f5c5SAndroid Build Coastguard Worker std::vector<TestCase> mTestCases;
369*8975f5c5SAndroid Build Coastguard Worker
370*8975f5c5SAndroid Build Coastguard Worker VertexData mCoord;
371*8975f5c5SAndroid Build Coastguard Worker VertexData mColor;
372*8975f5c5SAndroid Build Coastguard Worker };
373*8975f5c5SAndroid Build Coastguard Worker const GLushort AttributeLayoutTest::mIndices[kNumVertices] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
374*8975f5c5SAndroid Build Coastguard Worker
GetTestCases(void)375*8975f5c5SAndroid Build Coastguard Worker void AttributeLayoutTest::GetTestCases(void)
376*8975f5c5SAndroid Build Coastguard Worker {
377*8975f5c5SAndroid Build Coastguard Worker const bool es3 = getClientMajorVersion() >= 3;
378*8975f5c5SAndroid Build Coastguard Worker
379*8975f5c5SAndroid Build Coastguard Worker Format<GLfloat, GL_FLOAT, false> Float(es3);
380*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_FIXED, false> Fixed(es3);
381*8975f5c5SAndroid Build Coastguard Worker
382*8975f5c5SAndroid Build Coastguard Worker Format<GLbyte, GL_BYTE, false> SByte(es3);
383*8975f5c5SAndroid Build Coastguard Worker Format<GLubyte, GL_UNSIGNED_BYTE, false> UByte(es3);
384*8975f5c5SAndroid Build Coastguard Worker Format<GLshort, GL_SHORT, false> SShort(es3);
385*8975f5c5SAndroid Build Coastguard Worker Format<GLushort, GL_UNSIGNED_SHORT, false> UShort(es3);
386*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_INT, false> SInt(es3);
387*8975f5c5SAndroid Build Coastguard Worker Format<GLuint, GL_UNSIGNED_INT, false> UInt(es3);
388*8975f5c5SAndroid Build Coastguard Worker
389*8975f5c5SAndroid Build Coastguard Worker Format<GLbyte, GL_BYTE, true> NormSByte(es3);
390*8975f5c5SAndroid Build Coastguard Worker Format<GLubyte, GL_UNSIGNED_BYTE, true> NormUByte(es3);
391*8975f5c5SAndroid Build Coastguard Worker Format<GLshort, GL_SHORT, true> NormSShort(es3);
392*8975f5c5SAndroid Build Coastguard Worker Format<GLushort, GL_UNSIGNED_SHORT, true> NormUShort(es3);
393*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_INT, true> NormSInt(es3);
394*8975f5c5SAndroid Build Coastguard Worker Format<GLuint, GL_UNSIGNED_INT, true> NormUInt(es3);
395*8975f5c5SAndroid Build Coastguard Worker
396*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> M0 = std::make_shared<Memory>();
397*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> M1 = std::make_shared<Memory>();
398*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> B0 = std::make_shared<Buffer>();
399*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> B1 = std::make_shared<Buffer>();
400*8975f5c5SAndroid Build Coastguard Worker
401*8975f5c5SAndroid Build Coastguard Worker // 0. two buffers
402*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(B1, 0, 12, mColor)});
403*8975f5c5SAndroid Build Coastguard Worker
404*8975f5c5SAndroid Build Coastguard Worker // 1. two memory
405*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(M1, 0, 12, mColor)});
406*8975f5c5SAndroid Build Coastguard Worker
407*8975f5c5SAndroid Build Coastguard Worker // 2. one memory, sequential
408*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(M0, 96, 12, mColor)});
409*8975f5c5SAndroid Build Coastguard Worker
410*8975f5c5SAndroid Build Coastguard Worker // 3. one memory, interleaved
411*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 20, mCoord), Float(M0, 8, 20, mColor)});
412*8975f5c5SAndroid Build Coastguard Worker
413*8975f5c5SAndroid Build Coastguard Worker // 4. buffer and memory
414*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(M0, 0, 12, mColor)});
415*8975f5c5SAndroid Build Coastguard Worker
416*8975f5c5SAndroid Build Coastguard Worker // 5. stride != size
417*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), Float(B1, 0, 12, mColor)});
418*8975f5c5SAndroid Build Coastguard Worker
419*8975f5c5SAndroid Build Coastguard Worker // 6-7. same stride and format, switching data between memory and buffer
420*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 16, mCoord), Float(M1, 0, 12, mColor)});
421*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), Float(B1, 0, 12, mColor)});
422*8975f5c5SAndroid Build Coastguard Worker
423*8975f5c5SAndroid Build Coastguard Worker // 8-9. same stride and format, offset change
424*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(B1, 0, 12, mColor)});
425*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 3, 8, mCoord), Float(B1, 4, 12, mColor)});
426*8975f5c5SAndroid Build Coastguard Worker
427*8975f5c5SAndroid Build Coastguard Worker // 10-11. unaligned buffer data
428*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(B0, 1, 13, mColor)});
429*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(B1, 1, 13, mColor)});
430*8975f5c5SAndroid Build Coastguard Worker
431*8975f5c5SAndroid Build Coastguard Worker // 12-15. byte/short
432*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({SByte(M0, 0, 20, mCoord), UByte(M0, 10, 20, mColor)});
433*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({SShort(M0, 0, 20, mCoord), UShort(M0, 8, 20, mColor)});
434*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({NormSByte(M0, 0, 8, mCoord), NormUByte(M0, 4, 8, mColor)});
435*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({NormSShort(M0, 0, 20, mCoord), NormUShort(M0, 8, 20, mColor)});
436*8975f5c5SAndroid Build Coastguard Worker
437*8975f5c5SAndroid Build Coastguard Worker // 16. one buffer, sequential
438*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Fixed(B0, 0, 8, mCoord), Float(B0, 96, 12, mColor)});
439*8975f5c5SAndroid Build Coastguard Worker
440*8975f5c5SAndroid Build Coastguard Worker // 17. one buffer, interleaved
441*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Fixed(B0, 0, 20, mCoord), Float(B0, 8, 20, mColor)});
442*8975f5c5SAndroid Build Coastguard Worker
443*8975f5c5SAndroid Build Coastguard Worker // 18. memory and buffer, float and integer
444*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(M0, 0, 8, mCoord), SByte(B0, 0, 12, mColor)});
445*8975f5c5SAndroid Build Coastguard Worker
446*8975f5c5SAndroid Build Coastguard Worker // 19. buffer and memory, unusual offset and stride
447*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 11, 13, mCoord), Float(M0, 23, 17, mColor)});
448*8975f5c5SAndroid Build Coastguard Worker
449*8975f5c5SAndroid Build Coastguard Worker // 20-21. remaining ES3 formats
450*8975f5c5SAndroid Build Coastguard Worker if (es3)
451*8975f5c5SAndroid Build Coastguard Worker {
452*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({SInt(M0, 0, 40, mCoord), UInt(M0, 16, 40, mColor)});
453*8975f5c5SAndroid Build Coastguard Worker // Fails on Nexus devices (anglebug.com/42261348)
454*8975f5c5SAndroid Build Coastguard Worker if (!IsNexus5X())
455*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({NormSInt(M0, 0, 40, mCoord), NormUInt(M0, 16, 40, mColor)});
456*8975f5c5SAndroid Build Coastguard Worker }
457*8975f5c5SAndroid Build Coastguard Worker }
458*8975f5c5SAndroid Build Coastguard Worker
459*8975f5c5SAndroid Build Coastguard Worker class AttributeLayoutNonIndexed : public AttributeLayoutTest
460*8975f5c5SAndroid Build Coastguard Worker {
Draw(int firstVertex,unsigned vertexCount,const GLushort * indices)461*8975f5c5SAndroid Build Coastguard Worker void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
462*8975f5c5SAndroid Build Coastguard Worker {
463*8975f5c5SAndroid Build Coastguard Worker glDrawArrays(GL_TRIANGLES, firstVertex, vertexCount);
464*8975f5c5SAndroid Build Coastguard Worker }
465*8975f5c5SAndroid Build Coastguard Worker };
466*8975f5c5SAndroid Build Coastguard Worker
467*8975f5c5SAndroid Build Coastguard Worker class AttributeLayoutMemoryIndexed : public AttributeLayoutTest
468*8975f5c5SAndroid Build Coastguard Worker {
Draw(int firstVertex,unsigned vertexCount,const GLushort * indices)469*8975f5c5SAndroid Build Coastguard Worker void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
470*8975f5c5SAndroid Build Coastguard Worker {
471*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
472*8975f5c5SAndroid Build Coastguard Worker glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, indices);
473*8975f5c5SAndroid Build Coastguard Worker }
474*8975f5c5SAndroid Build Coastguard Worker };
475*8975f5c5SAndroid Build Coastguard Worker
476*8975f5c5SAndroid Build Coastguard Worker class AttributeLayoutBufferIndexed : public AttributeLayoutTest
477*8975f5c5SAndroid Build Coastguard Worker {
Draw(int firstVertex,unsigned vertexCount,const GLushort * indices)478*8975f5c5SAndroid Build Coastguard Worker void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
479*8975f5c5SAndroid Build Coastguard Worker {
480*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
481*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*mIndices) * vertexCount, indices,
482*8975f5c5SAndroid Build Coastguard Worker GL_STATIC_DRAW);
483*8975f5c5SAndroid Build Coastguard Worker glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, nullptr);
484*8975f5c5SAndroid Build Coastguard Worker }
485*8975f5c5SAndroid Build Coastguard Worker };
486*8975f5c5SAndroid Build Coastguard Worker
TEST_P(AttributeLayoutNonIndexed,Test)487*8975f5c5SAndroid Build Coastguard Worker TEST_P(AttributeLayoutNonIndexed, Test)
488*8975f5c5SAndroid Build Coastguard Worker {
489*8975f5c5SAndroid Build Coastguard Worker Run(true);
490*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
491*8975f5c5SAndroid Build Coastguard Worker Run(false);
492*8975f5c5SAndroid Build Coastguard Worker }
493*8975f5c5SAndroid Build Coastguard Worker
TEST_P(AttributeLayoutMemoryIndexed,Test)494*8975f5c5SAndroid Build Coastguard Worker TEST_P(AttributeLayoutMemoryIndexed, Test)
495*8975f5c5SAndroid Build Coastguard Worker {
496*8975f5c5SAndroid Build Coastguard Worker Run(true);
497*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
498*8975f5c5SAndroid Build Coastguard Worker Run(false);
499*8975f5c5SAndroid Build Coastguard Worker }
500*8975f5c5SAndroid Build Coastguard Worker
TEST_P(AttributeLayoutBufferIndexed,Test)501*8975f5c5SAndroid Build Coastguard Worker TEST_P(AttributeLayoutBufferIndexed, Test)
502*8975f5c5SAndroid Build Coastguard Worker {
503*8975f5c5SAndroid Build Coastguard Worker Run(true);
504*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
505*8975f5c5SAndroid Build Coastguard Worker Run(false);
506*8975f5c5SAndroid Build Coastguard Worker }
507*8975f5c5SAndroid Build Coastguard Worker
508*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutNonIndexed,
509*8975f5c5SAndroid Build Coastguard Worker ES3_VULKAN()
510*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState)
511*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState2));
512*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutMemoryIndexed,
513*8975f5c5SAndroid Build Coastguard Worker ES3_VULKAN()
514*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState)
515*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState2));
516*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutBufferIndexed,
517*8975f5c5SAndroid Build Coastguard Worker ES3_VULKAN()
518*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState)
519*8975f5c5SAndroid Build Coastguard Worker .disable(Feature::SupportsExtendedDynamicState2));
520*8975f5c5SAndroid Build Coastguard Worker
521*8975f5c5SAndroid Build Coastguard Worker #define STRINGIFY2(X) #X
522*8975f5c5SAndroid Build Coastguard Worker #define STRINGIFY(X) STRINGIFY2(X)
523*8975f5c5SAndroid Build Coastguard Worker
524*8975f5c5SAndroid Build Coastguard Worker // clang-format off
525*8975f5c5SAndroid Build Coastguard Worker #define VS_SHADER(ColorDataType) \
526*8975f5c5SAndroid Build Coastguard Worker "#version 300 es\n"\
527*8975f5c5SAndroid Build Coastguard Worker "in highp vec2 coord;\n"\
528*8975f5c5SAndroid Build Coastguard Worker "in highp " STRINGIFY(ColorDataType) " color;\n"\
529*8975f5c5SAndroid Build Coastguard Worker "flat out highp " STRINGIFY(ColorDataType) " vcolor;\n"\
530*8975f5c5SAndroid Build Coastguard Worker "void main(void)\n"\
531*8975f5c5SAndroid Build Coastguard Worker "{\n"\
532*8975f5c5SAndroid Build Coastguard Worker " gl_Position = vec4(coord, 0, 1);\n"\
533*8975f5c5SAndroid Build Coastguard Worker " vcolor = color;\n"\
534*8975f5c5SAndroid Build Coastguard Worker "}\n"
535*8975f5c5SAndroid Build Coastguard Worker
536*8975f5c5SAndroid Build Coastguard Worker #define PS_SHADER(ColorDataType) \
537*8975f5c5SAndroid Build Coastguard Worker "#version 300 es\n"\
538*8975f5c5SAndroid Build Coastguard Worker "flat in highp " STRINGIFY(ColorDataType) " vcolor;\n"\
539*8975f5c5SAndroid Build Coastguard Worker "out highp " STRINGIFY(ColorDataType) " outColor;\n"\
540*8975f5c5SAndroid Build Coastguard Worker "void main(void)\n"\
541*8975f5c5SAndroid Build Coastguard Worker "{\n"\
542*8975f5c5SAndroid Build Coastguard Worker " outColor = vcolor;\n"\
543*8975f5c5SAndroid Build Coastguard Worker "}\n"
544*8975f5c5SAndroid Build Coastguard Worker
545*8975f5c5SAndroid Build Coastguard Worker // clang-format on
546*8975f5c5SAndroid Build Coastguard Worker
547*8975f5c5SAndroid Build Coastguard Worker // clang-format off
548*8975f5c5SAndroid Build Coastguard Worker constexpr double kVertexData[] = {
549*8975f5c5SAndroid Build Coastguard Worker //x y rgba
550*8975f5c5SAndroid Build Coastguard Worker -1, -1, 128, 128, 93, 255,
551*8975f5c5SAndroid Build Coastguard Worker +1, -1, 128, 128, 93, 255,
552*8975f5c5SAndroid Build Coastguard Worker -1, +1, 128, 128, 93, 255,
553*8975f5c5SAndroid Build Coastguard Worker +1, +1, 128, 128, 93, 255,
554*8975f5c5SAndroid Build Coastguard Worker };
555*8975f5c5SAndroid Build Coastguard Worker // clang-format on
556*8975f5c5SAndroid Build Coastguard Worker
557*8975f5c5SAndroid Build Coastguard Worker template <class ResType>
GetRefValue(const void * data,GLenum glType)558*8975f5c5SAndroid Build Coastguard Worker ResType GetRefValue(const void *data, GLenum glType)
559*8975f5c5SAndroid Build Coastguard Worker {
560*8975f5c5SAndroid Build Coastguard Worker switch (glType)
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker case GL_BYTE:
563*8975f5c5SAndroid Build Coastguard Worker {
564*8975f5c5SAndroid Build Coastguard Worker const int8_t *p = reinterpret_cast<const int8_t *>(data);
565*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
566*8975f5c5SAndroid Build Coastguard Worker }
567*8975f5c5SAndroid Build Coastguard Worker case GL_SHORT:
568*8975f5c5SAndroid Build Coastguard Worker case GL_HALF_FLOAT:
569*8975f5c5SAndroid Build Coastguard Worker {
570*8975f5c5SAndroid Build Coastguard Worker const int16_t *p = reinterpret_cast<const int16_t *>(data);
571*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
572*8975f5c5SAndroid Build Coastguard Worker }
573*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
574*8975f5c5SAndroid Build Coastguard Worker case GL_FIXED:
575*8975f5c5SAndroid Build Coastguard Worker {
576*8975f5c5SAndroid Build Coastguard Worker const int32_t *p = reinterpret_cast<const int32_t *>(data);
577*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
578*8975f5c5SAndroid Build Coastguard Worker }
579*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_BYTE:
580*8975f5c5SAndroid Build Coastguard Worker {
581*8975f5c5SAndroid Build Coastguard Worker const uint8_t *p = reinterpret_cast<const uint8_t *>(data);
582*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
583*8975f5c5SAndroid Build Coastguard Worker }
584*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT:
585*8975f5c5SAndroid Build Coastguard Worker {
586*8975f5c5SAndroid Build Coastguard Worker const uint16_t *p = reinterpret_cast<const uint16_t *>(data);
587*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
588*8975f5c5SAndroid Build Coastguard Worker }
589*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
590*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
591*8975f5c5SAndroid Build Coastguard Worker {
592*8975f5c5SAndroid Build Coastguard Worker const uint32_t *p = reinterpret_cast<const uint32_t *>(data);
593*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
594*8975f5c5SAndroid Build Coastguard Worker }
595*8975f5c5SAndroid Build Coastguard Worker default:
596*8975f5c5SAndroid Build Coastguard Worker {
597*8975f5c5SAndroid Build Coastguard Worker ASSERT(0);
598*8975f5c5SAndroid Build Coastguard Worker const uint32_t *p = reinterpret_cast<const uint32_t *>(data);
599*8975f5c5SAndroid Build Coastguard Worker return ResType(p[0], p[1], p[2], p[3]);
600*8975f5c5SAndroid Build Coastguard Worker }
601*8975f5c5SAndroid Build Coastguard Worker }
602*8975f5c5SAndroid Build Coastguard Worker }
603*8975f5c5SAndroid Build Coastguard Worker
604*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kIndexCount = 6;
605*8975f5c5SAndroid Build Coastguard Worker constexpr int kRboSize = 8;
606*8975f5c5SAndroid Build Coastguard Worker
ConvertFloatToUnorm8(const GLColor32F & color32f)607*8975f5c5SAndroid Build Coastguard Worker GLColor ConvertFloatToUnorm8(const GLColor32F &color32f)
608*8975f5c5SAndroid Build Coastguard Worker {
609*8975f5c5SAndroid Build Coastguard Worker float r = std::clamp(color32f.R, 0.0f, 1.0f);
610*8975f5c5SAndroid Build Coastguard Worker float g = std::clamp(color32f.G, 0.0f, 1.0f);
611*8975f5c5SAndroid Build Coastguard Worker float b = std::clamp(color32f.B, 0.0f, 1.0f);
612*8975f5c5SAndroid Build Coastguard Worker float a = std::clamp(color32f.A, 0.0f, 1.0f);
613*8975f5c5SAndroid Build Coastguard Worker return GLColor(std::round(r * 255), std::round(g * 255), std::round(b * 255),
614*8975f5c5SAndroid Build Coastguard Worker std::round(a * 255));
615*8975f5c5SAndroid Build Coastguard Worker }
616*8975f5c5SAndroid Build Coastguard Worker
BindAttribLocation(GLuint program)617*8975f5c5SAndroid Build Coastguard Worker void BindAttribLocation(GLuint program)
618*8975f5c5SAndroid Build Coastguard Worker {
619*8975f5c5SAndroid Build Coastguard Worker glBindAttribLocation(program, 0, "coord");
620*8975f5c5SAndroid Build Coastguard Worker glBindAttribLocation(program, 1, "color");
621*8975f5c5SAndroid Build Coastguard Worker }
622*8975f5c5SAndroid Build Coastguard Worker
623*8975f5c5SAndroid Build Coastguard Worker class AttributeDataTypeMismatchTest : public ANGLETest<>
624*8975f5c5SAndroid Build Coastguard Worker {
625*8975f5c5SAndroid Build Coastguard Worker public:
626*8975f5c5SAndroid Build Coastguard Worker enum VsInputDataType
627*8975f5c5SAndroid Build Coastguard Worker {
628*8975f5c5SAndroid Build Coastguard Worker FLOAT = 0,
629*8975f5c5SAndroid Build Coastguard Worker INT = 1,
630*8975f5c5SAndroid Build Coastguard Worker UNSIGNED = 2,
631*8975f5c5SAndroid Build Coastguard Worker COUNT = 3,
632*8975f5c5SAndroid Build Coastguard Worker };
633*8975f5c5SAndroid Build Coastguard Worker
634*8975f5c5SAndroid Build Coastguard Worker protected:
AttributeDataTypeMismatchTest()635*8975f5c5SAndroid Build Coastguard Worker AttributeDataTypeMismatchTest()
636*8975f5c5SAndroid Build Coastguard Worker : mCoord(2, kVertexData, 0, 6, 4), mColor(4, kVertexData, 2, 6, 4)
637*8975f5c5SAndroid Build Coastguard Worker {
638*8975f5c5SAndroid Build Coastguard Worker setWindowWidth(128);
639*8975f5c5SAndroid Build Coastguard Worker setWindowHeight(128);
640*8975f5c5SAndroid Build Coastguard Worker setConfigRedBits(8);
641*8975f5c5SAndroid Build Coastguard Worker setConfigGreenBits(8);
642*8975f5c5SAndroid Build Coastguard Worker setConfigBlueBits(8);
643*8975f5c5SAndroid Build Coastguard Worker setConfigAlphaBits(8);
644*8975f5c5SAndroid Build Coastguard Worker }
645*8975f5c5SAndroid Build Coastguard Worker
createFbo(GLuint rbo)646*8975f5c5SAndroid Build Coastguard Worker GLuint createFbo(GLuint rbo)
647*8975f5c5SAndroid Build Coastguard Worker {
648*8975f5c5SAndroid Build Coastguard Worker
649*8975f5c5SAndroid Build Coastguard Worker GLuint fbo = 0;
650*8975f5c5SAndroid Build Coastguard Worker glGenFramebuffers(1, &fbo);
651*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fbo);
652*8975f5c5SAndroid Build Coastguard Worker glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
653*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, 0);
654*8975f5c5SAndroid Build Coastguard Worker return fbo;
655*8975f5c5SAndroid Build Coastguard Worker }
656*8975f5c5SAndroid Build Coastguard Worker
createRbo(VsInputDataType inputDataType)657*8975f5c5SAndroid Build Coastguard Worker GLuint createRbo(VsInputDataType inputDataType)
658*8975f5c5SAndroid Build Coastguard Worker {
659*8975f5c5SAndroid Build Coastguard Worker GLuint rbo = 0;
660*8975f5c5SAndroid Build Coastguard Worker glGenRenderbuffers(1, &rbo);
661*8975f5c5SAndroid Build Coastguard Worker GLenum format = GL_RGBA8;
662*8975f5c5SAndroid Build Coastguard Worker if (inputDataType == VsInputDataType::INT)
663*8975f5c5SAndroid Build Coastguard Worker {
664*8975f5c5SAndroid Build Coastguard Worker format = GL_RGBA32I;
665*8975f5c5SAndroid Build Coastguard Worker }
666*8975f5c5SAndroid Build Coastguard Worker else if (inputDataType == VsInputDataType::UNSIGNED)
667*8975f5c5SAndroid Build Coastguard Worker {
668*8975f5c5SAndroid Build Coastguard Worker format = GL_RGBA32UI;
669*8975f5c5SAndroid Build Coastguard Worker }
670*8975f5c5SAndroid Build Coastguard Worker glBindRenderbuffer(GL_RENDERBUFFER, rbo);
671*8975f5c5SAndroid Build Coastguard Worker glRenderbufferStorage(GL_RENDERBUFFER, format, kRboSize, kRboSize);
672*8975f5c5SAndroid Build Coastguard Worker glBindRenderbuffer(GL_RENDERBUFFER, 0);
673*8975f5c5SAndroid Build Coastguard Worker return rbo;
674*8975f5c5SAndroid Build Coastguard Worker }
675*8975f5c5SAndroid Build Coastguard Worker
testSetUp()676*8975f5c5SAndroid Build Coastguard Worker void testSetUp() override
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker glClearColor(.2f, .2f, .2f, .0f);
679*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
680*8975f5c5SAndroid Build Coastguard Worker
681*8975f5c5SAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
682*8975f5c5SAndroid Build Coastguard Worker
683*8975f5c5SAndroid Build Coastguard Worker constexpr const char *kVS[VsInputDataType::COUNT] = {
684*8975f5c5SAndroid Build Coastguard Worker VS_SHADER(vec4),
685*8975f5c5SAndroid Build Coastguard Worker VS_SHADER(ivec4),
686*8975f5c5SAndroid Build Coastguard Worker VS_SHADER(uvec4),
687*8975f5c5SAndroid Build Coastguard Worker };
688*8975f5c5SAndroid Build Coastguard Worker
689*8975f5c5SAndroid Build Coastguard Worker constexpr const char *kFS[VsInputDataType::COUNT] = {
690*8975f5c5SAndroid Build Coastguard Worker PS_SHADER(vec4),
691*8975f5c5SAndroid Build Coastguard Worker PS_SHADER(ivec4),
692*8975f5c5SAndroid Build Coastguard Worker PS_SHADER(uvec4),
693*8975f5c5SAndroid Build Coastguard Worker };
694*8975f5c5SAndroid Build Coastguard Worker
695*8975f5c5SAndroid Build Coastguard Worker for (int i = VsInputDataType::FLOAT; i < VsInputDataType::COUNT; ++i)
696*8975f5c5SAndroid Build Coastguard Worker {
697*8975f5c5SAndroid Build Coastguard Worker mProgram[i] = CompileProgram(kVS[i], kFS[i], BindAttribLocation);
698*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mProgram[i]);
699*8975f5c5SAndroid Build Coastguard Worker mRbo[i] = createRbo(static_cast<VsInputDataType>(i));
700*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mRbo[i]);
701*8975f5c5SAndroid Build Coastguard Worker mFbo[i] = createFbo(mRbo[i]);
702*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mFbo[i]);
703*8975f5c5SAndroid Build Coastguard Worker }
704*8975f5c5SAndroid Build Coastguard Worker
705*8975f5c5SAndroid Build Coastguard Worker glGenBuffers(1, &mIndexBuffer);
706*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
707*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mIndices), mIndices, GL_STATIC_DRAW);
708*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
709*8975f5c5SAndroid Build Coastguard Worker }
710*8975f5c5SAndroid Build Coastguard Worker
GetTestCases(VsInputDataType dataType)711*8975f5c5SAndroid Build Coastguard Worker void GetTestCases(VsInputDataType dataType)
712*8975f5c5SAndroid Build Coastguard Worker {
713*8975f5c5SAndroid Build Coastguard Worker const bool es3 = getClientMajorVersion() >= 3;
714*8975f5c5SAndroid Build Coastguard Worker
715*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> B0 = std::make_shared<Buffer>();
716*8975f5c5SAndroid Build Coastguard Worker if (dataType != VsInputDataType::FLOAT)
717*8975f5c5SAndroid Build Coastguard Worker {
718*8975f5c5SAndroid Build Coastguard Worker // float and fixed.
719*8975f5c5SAndroid Build Coastguard Worker Format<GLfloat, GL_FLOAT, false> Float(es3);
720*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_FIXED, false> Fixed(es3);
721*8975f5c5SAndroid Build Coastguard Worker Format<GLshort, GL_HALF_FLOAT, false> halfFloat(es3);
722*8975f5c5SAndroid Build Coastguard Worker // for UScale, SScale.
723*8975f5c5SAndroid Build Coastguard Worker Format<GLbyte, GL_BYTE, false> SByte(es3);
724*8975f5c5SAndroid Build Coastguard Worker Format<GLubyte, GL_UNSIGNED_BYTE, false> UByte(es3);
725*8975f5c5SAndroid Build Coastguard Worker Format<GLshort, GL_SHORT, false> SShort(es3);
726*8975f5c5SAndroid Build Coastguard Worker Format<GLushort, GL_UNSIGNED_SHORT, false> UShort(es3);
727*8975f5c5SAndroid Build Coastguard Worker // UScale32, Scale32 may emulated. testing unsigned<-->int
728*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_INT, false, true> SInt(es3);
729*8975f5c5SAndroid Build Coastguard Worker Format<GLuint, GL_UNSIGNED_INT, false, true> UInt(es3);
730*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 12, mCoord), SByte(B0, 8, 12, mColor)});
731*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 12, mCoord), UByte(B0, 8, 12, mColor)});
732*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), SShort(B0, 8, 16, mColor)});
733*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), UShort(B0, 8, 16, mColor)});
734*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), halfFloat(B0, 8, 16, mColor)});
735*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 24, mCoord), SInt(B0, 8, 24, mColor)});
736*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 24, mCoord), UInt(B0, 8, 24, mColor)});
737*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 24, mCoord), Float(B0, 8, 24, mColor)});
738*8975f5c5SAndroid Build Coastguard Worker // for GL_FIXED, angle may use GLfloat emulated.
739*8975f5c5SAndroid Build Coastguard Worker // mTestCases.push_back({Float(B0, 0, 24, mCoord), Fixed(B0, 8, 24, mColor)});
740*8975f5c5SAndroid Build Coastguard Worker }
741*8975f5c5SAndroid Build Coastguard Worker else
742*8975f5c5SAndroid Build Coastguard Worker {
743*8975f5c5SAndroid Build Coastguard Worker Format<GLfloat, GL_FLOAT, false> Float(es3);
744*8975f5c5SAndroid Build Coastguard Worker Format<GLbyte, GL_BYTE, false, true> SByte(es3);
745*8975f5c5SAndroid Build Coastguard Worker Format<GLubyte, GL_UNSIGNED_BYTE, false, true> UByte(es3);
746*8975f5c5SAndroid Build Coastguard Worker Format<GLshort, GL_SHORT, false, true> SShort(es3);
747*8975f5c5SAndroid Build Coastguard Worker Format<GLushort, GL_UNSIGNED_SHORT, false, true> UShort(es3);
748*8975f5c5SAndroid Build Coastguard Worker Format<GLint, GL_INT, false, true> SInt(es3);
749*8975f5c5SAndroid Build Coastguard Worker Format<GLuint, GL_UNSIGNED_INT, false, true> UInt(es3);
750*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 12, mCoord), SByte(B0, 8, 12, mColor)});
751*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 12, mCoord), UByte(B0, 8, 12, mColor)});
752*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), SShort(B0, 8, 16, mColor)});
753*8975f5c5SAndroid Build Coastguard Worker mTestCases.push_back({Float(B0, 0, 16, mCoord), UShort(B0, 8, 16, mColor)});
754*8975f5c5SAndroid Build Coastguard Worker // UScale32, Scale32 may emulated.
755*8975f5c5SAndroid Build Coastguard Worker // mTestCases.push_back({Float(B0, 0, 24, mCoord), SInt(B0, 8, 24, mColor)});
756*8975f5c5SAndroid Build Coastguard Worker // mTestCases.push_back({Float(B0, 0, 24, mCoord), UInt(B0, 8, 24, mColor)});
757*8975f5c5SAndroid Build Coastguard Worker }
758*8975f5c5SAndroid Build Coastguard Worker }
759*8975f5c5SAndroid Build Coastguard Worker
testTearDown()760*8975f5c5SAndroid Build Coastguard Worker void testTearDown() override
761*8975f5c5SAndroid Build Coastguard Worker {
762*8975f5c5SAndroid Build Coastguard Worker mTestCases.clear();
763*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < VsInputDataType::COUNT; ++i)
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mProgram[i]);
766*8975f5c5SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &mFbo[i]);
767*8975f5c5SAndroid Build Coastguard Worker glDeleteRenderbuffers(1, &mRbo[i]);
768*8975f5c5SAndroid Build Coastguard Worker }
769*8975f5c5SAndroid Build Coastguard Worker glDeleteBuffers(1, &mIndexBuffer);
770*8975f5c5SAndroid Build Coastguard Worker }
771*8975f5c5SAndroid Build Coastguard Worker
GetMappedGLType(GLenum glType,VsInputDataType vsInputDataType)772*8975f5c5SAndroid Build Coastguard Worker GLenum GetMappedGLType(GLenum glType, VsInputDataType vsInputDataType)
773*8975f5c5SAndroid Build Coastguard Worker {
774*8975f5c5SAndroid Build Coastguard Worker switch (glType)
775*8975f5c5SAndroid Build Coastguard Worker {
776*8975f5c5SAndroid Build Coastguard Worker case GL_BYTE:
777*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::UNSIGNED ? GL_BYTE : GL_UNSIGNED_BYTE;
778*8975f5c5SAndroid Build Coastguard Worker case GL_SHORT:
779*8975f5c5SAndroid Build Coastguard Worker case GL_HALF_FLOAT:
780*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::UNSIGNED ? GL_SHORT : GL_UNSIGNED_SHORT;
781*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
782*8975f5c5SAndroid Build Coastguard Worker case GL_FIXED:
783*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::UNSIGNED ? GL_INT : GL_UNSIGNED_INT;
784*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_BYTE:
785*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_BYTE : GL_BYTE;
786*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT:
787*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_SHORT : GL_SHORT;
788*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
789*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
790*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_INT : GL_INT;
791*8975f5c5SAndroid Build Coastguard Worker default:
792*8975f5c5SAndroid Build Coastguard Worker ASSERT(0);
793*8975f5c5SAndroid Build Coastguard Worker return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_INT : GL_INT;
794*8975f5c5SAndroid Build Coastguard Worker }
795*8975f5c5SAndroid Build Coastguard Worker }
796*8975f5c5SAndroid Build Coastguard Worker
Run(VsInputDataType dataType)797*8975f5c5SAndroid Build Coastguard Worker void Run(VsInputDataType dataType)
798*8975f5c5SAndroid Build Coastguard Worker {
799*8975f5c5SAndroid Build Coastguard Worker GetTestCases(dataType);
800*8975f5c5SAndroid Build Coastguard Worker ASSERT(dataType < VsInputDataType::COUNT);
801*8975f5c5SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, mFbo[dataType]);
802*8975f5c5SAndroid Build Coastguard Worker glViewport(0, 0, kRboSize, kRboSize);
803*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mProgram[dataType]);
804*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
805*8975f5c5SAndroid Build Coastguard Worker for (unsigned i = 0; i < mTestCases.size(); ++i)
806*8975f5c5SAndroid Build Coastguard Worker {
807*8975f5c5SAndroid Build Coastguard Worker if (mTestCases[i].size() == 0)
808*8975f5c5SAndroid Build Coastguard Worker continue;
809*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTestCases[i].size() == 2);
810*8975f5c5SAndroid Build Coastguard Worker PrepareTestCase(mTestCases[i]);
811*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
812*8975f5c5SAndroid Build Coastguard Worker GLint iClearValue[] = {0, 0, 0, 1};
813*8975f5c5SAndroid Build Coastguard Worker GLfloat fClearValue[] = {1.0f, 0.0f, 0.0f, 1.0f};
814*8975f5c5SAndroid Build Coastguard Worker switch (dataType)
815*8975f5c5SAndroid Build Coastguard Worker {
816*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::FLOAT:
817*8975f5c5SAndroid Build Coastguard Worker glClearBufferfv(GL_COLOR, 0, fClearValue);
818*8975f5c5SAndroid Build Coastguard Worker break;
819*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::INT:
820*8975f5c5SAndroid Build Coastguard Worker glClearBufferiv(GL_COLOR, 0, iClearValue);
821*8975f5c5SAndroid Build Coastguard Worker break;
822*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::UNSIGNED:
823*8975f5c5SAndroid Build Coastguard Worker glClearBufferuiv(GL_COLOR, 0, reinterpret_cast<const GLuint *>(iClearValue));
824*8975f5c5SAndroid Build Coastguard Worker break;
825*8975f5c5SAndroid Build Coastguard Worker default:
826*8975f5c5SAndroid Build Coastguard Worker ASSERT(0);
827*8975f5c5SAndroid Build Coastguard Worker }
828*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
829*8975f5c5SAndroid Build Coastguard Worker glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
830*8975f5c5SAndroid Build Coastguard Worker EXPECT_GL_NO_ERROR();
831*8975f5c5SAndroid Build Coastguard Worker
832*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<Container> container = mTestCases[i][1].mContainer;
833*8975f5c5SAndroid Build Coastguard Worker size_t offset = mTestCases[i][1].mOffset;
834*8975f5c5SAndroid Build Coastguard Worker GLenum glType = GetMappedGLType(mTestCases[i][1].mGLType, dataType);
835*8975f5c5SAndroid Build Coastguard Worker switch (dataType)
836*8975f5c5SAndroid Build Coastguard Worker {
837*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::FLOAT:
838*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(0, 0,
839*8975f5c5SAndroid Build Coastguard Worker ConvertFloatToUnorm8(GetRefValue<GLColor32F>(
840*8975f5c5SAndroid Build Coastguard Worker container->getDestination(offset), glType)));
841*8975f5c5SAndroid Build Coastguard Worker break;
842*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::INT:
843*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT32I_EQ(
844*8975f5c5SAndroid Build Coastguard Worker 0, 0, 1, 1,
845*8975f5c5SAndroid Build Coastguard Worker GetRefValue<GLColor32I>(container->getDestination(offset), glType));
846*8975f5c5SAndroid Build Coastguard Worker break;
847*8975f5c5SAndroid Build Coastguard Worker case VsInputDataType::UNSIGNED:
848*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_RECT32UI_EQ(
849*8975f5c5SAndroid Build Coastguard Worker 0, 0, 1, 1,
850*8975f5c5SAndroid Build Coastguard Worker GetRefValue<GLColor32UI>(container->getDestination(offset), glType));
851*8975f5c5SAndroid Build Coastguard Worker break;
852*8975f5c5SAndroid Build Coastguard Worker default:
853*8975f5c5SAndroid Build Coastguard Worker ASSERT(0);
854*8975f5c5SAndroid Build Coastguard Worker }
855*8975f5c5SAndroid Build Coastguard Worker }
856*8975f5c5SAndroid Build Coastguard Worker mTestCases.clear();
857*8975f5c5SAndroid Build Coastguard Worker }
858*8975f5c5SAndroid Build Coastguard Worker
859*8975f5c5SAndroid Build Coastguard Worker static const GLushort mIndices[kIndexCount];
860*8975f5c5SAndroid Build Coastguard Worker
861*8975f5c5SAndroid Build Coastguard Worker GLuint mProgram[VsInputDataType::COUNT];
862*8975f5c5SAndroid Build Coastguard Worker GLuint mFbo[VsInputDataType::COUNT];
863*8975f5c5SAndroid Build Coastguard Worker GLuint mRbo[VsInputDataType::COUNT];
864*8975f5c5SAndroid Build Coastguard Worker GLuint mIndexBuffer;
865*8975f5c5SAndroid Build Coastguard Worker
866*8975f5c5SAndroid Build Coastguard Worker std::vector<TestCase> mTestCases;
867*8975f5c5SAndroid Build Coastguard Worker
868*8975f5c5SAndroid Build Coastguard Worker VertexData mCoord;
869*8975f5c5SAndroid Build Coastguard Worker VertexData mColor;
870*8975f5c5SAndroid Build Coastguard Worker };
871*8975f5c5SAndroid Build Coastguard Worker
872*8975f5c5SAndroid Build Coastguard Worker const GLushort AttributeDataTypeMismatchTest::mIndices[kIndexCount] = {0, 1, 2, 2, 1, 3};
873*8975f5c5SAndroid Build Coastguard Worker
874*8975f5c5SAndroid Build Coastguard Worker // Test Attribute input data type mismatch with vertex shader input.
875*8975f5c5SAndroid Build Coastguard Worker // Change the attribute input data type to vertex shader input data type.
TEST_P(AttributeDataTypeMismatchTest,Test)876*8975f5c5SAndroid Build Coastguard Worker TEST_P(AttributeDataTypeMismatchTest, Test)
877*8975f5c5SAndroid Build Coastguard Worker {
878*8975f5c5SAndroid Build Coastguard Worker // At some device. UScale and Scale are emulated.
879*8975f5c5SAndroid Build Coastguard Worker // Restrict tests running at nvidia device only.
880*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsVulkan() || !IsNVIDIA());
881*8975f5c5SAndroid Build Coastguard Worker Run(VsInputDataType::FLOAT);
882*8975f5c5SAndroid Build Coastguard Worker Run(VsInputDataType::INT);
883*8975f5c5SAndroid Build Coastguard Worker Run(VsInputDataType::UNSIGNED);
884*8975f5c5SAndroid Build Coastguard Worker }
885*8975f5c5SAndroid Build Coastguard Worker
886*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(AttributeDataTypeMismatchTest);
887*8975f5c5SAndroid Build Coastguard Worker
888*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
889