xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fDrawTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Drawing tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fDrawTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
28*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "sglrGLContext.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "glsDrawTest.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "gluCallLogWrapper.hpp"
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include <set>
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker namespace deqp
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker namespace gles31
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker namespace Functional
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker namespace
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker enum TestIterationType
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker     TYPE_DRAW_COUNT,     // !< test with 1, 5, and 25 primitives
53*35238bceSAndroid Build Coastguard Worker     TYPE_INSTANCE_COUNT, // !< test with 1, 4, and 11 instances
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker     TYPE_LAST
56*35238bceSAndroid Build Coastguard Worker };
57*35238bceSAndroid Build Coastguard Worker 
58*35238bceSAndroid Build Coastguard Worker static const char *s_commonVertexShaderSource   = "#version 310 es\n"
59*35238bceSAndroid Build Coastguard Worker                                                   "in highp vec4 a_position;\n"
60*35238bceSAndroid Build Coastguard Worker                                                   "void main (void)\n"
61*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
62*35238bceSAndroid Build Coastguard Worker                                                   "    gl_Position = a_position;\n"
63*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
64*35238bceSAndroid Build Coastguard Worker static const char *s_commonFragmentShaderSource = "#version 310 es\n"
65*35238bceSAndroid Build Coastguard Worker                                                   "layout(location = 0) out highp vec4 fragColor;\n"
66*35238bceSAndroid Build Coastguard Worker                                                   "void main (void)\n"
67*35238bceSAndroid Build Coastguard Worker                                                   "{\n"
68*35238bceSAndroid Build Coastguard Worker                                                   "    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
69*35238bceSAndroid Build Coastguard Worker                                                   "}\n";
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker static const char *s_colorVertexShaderSource   = "#version 310 es\n"
72*35238bceSAndroid Build Coastguard Worker                                                  "in highp vec4 a_position;\n"
73*35238bceSAndroid Build Coastguard Worker                                                  "in highp vec4 a_color;\n"
74*35238bceSAndroid Build Coastguard Worker                                                  "out highp vec4 v_color;\n"
75*35238bceSAndroid Build Coastguard Worker                                                  "void main (void)\n"
76*35238bceSAndroid Build Coastguard Worker                                                  "{\n"
77*35238bceSAndroid Build Coastguard Worker                                                  "    gl_Position = a_position;\n"
78*35238bceSAndroid Build Coastguard Worker                                                  "    v_color = a_color;\n"
79*35238bceSAndroid Build Coastguard Worker                                                  "}\n";
80*35238bceSAndroid Build Coastguard Worker static const char *s_colorFragmentShaderSource = "#version 310 es\n"
81*35238bceSAndroid Build Coastguard Worker                                                  "layout(location = 0) out highp vec4 fragColor;\n"
82*35238bceSAndroid Build Coastguard Worker                                                  "in highp vec4 v_color;\n"
83*35238bceSAndroid Build Coastguard Worker                                                  "void main (void)\n"
84*35238bceSAndroid Build Coastguard Worker                                                  "{\n"
85*35238bceSAndroid Build Coastguard Worker                                                  "    fragColor = v_color;\n"
86*35238bceSAndroid Build Coastguard Worker                                                  "}\n";
87*35238bceSAndroid Build Coastguard Worker struct DrawElementsCommand
88*35238bceSAndroid Build Coastguard Worker {
89*35238bceSAndroid Build Coastguard Worker     uint32_t count;
90*35238bceSAndroid Build Coastguard Worker     uint32_t primCount;
91*35238bceSAndroid Build Coastguard Worker     uint32_t firstIndex;
92*35238bceSAndroid Build Coastguard Worker     int32_t baseVertex;
93*35238bceSAndroid Build Coastguard Worker     uint32_t reservedMustBeZero;
94*35238bceSAndroid Build Coastguard Worker };
95*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(5 * sizeof(uint32_t) == sizeof(DrawElementsCommand)); // tight packing
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker struct DrawArraysCommand
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker     uint32_t count;
100*35238bceSAndroid Build Coastguard Worker     uint32_t primCount;
101*35238bceSAndroid Build Coastguard Worker     uint32_t first;
102*35238bceSAndroid Build Coastguard Worker     uint32_t reservedMustBeZero;
103*35238bceSAndroid Build Coastguard Worker };
104*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(4 * sizeof(uint32_t) == sizeof(DrawArraysCommand)); // tight packing
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker // Verifies image contains only yellow or greeen, or a linear combination
107*35238bceSAndroid Build Coastguard Worker // of these colors.
verifyImageYellowGreen(const tcu::Surface & image,tcu::TestLog & log)108*35238bceSAndroid Build Coastguard Worker static bool verifyImageYellowGreen(const tcu::Surface &image, tcu::TestLog &log)
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker     using tcu::TestLog;
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     const int colorThreshold = 20;
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     tcu::Surface error(image.getWidth(), image.getHeight());
115*35238bceSAndroid Build Coastguard Worker     bool isOk = true;
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < image.getHeight(); y++)
118*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < image.getWidth(); x++)
119*35238bceSAndroid Build Coastguard Worker         {
120*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA pixel = image.getPixel(x, y);
121*35238bceSAndroid Build Coastguard Worker             bool pixelOk          = true;
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker             // Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
124*35238bceSAndroid Build Coastguard Worker             if (de::abs(pixel.getGreen() - 255) > colorThreshold)
125*35238bceSAndroid Build Coastguard Worker                 pixelOk = false;
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker             // Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
128*35238bceSAndroid Build Coastguard Worker             if (de::abs(pixel.getBlue() - 0) > colorThreshold)
129*35238bceSAndroid Build Coastguard Worker                 pixelOk = false;
130*35238bceSAndroid Build Coastguard Worker 
131*35238bceSAndroid Build Coastguard Worker             error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
132*35238bceSAndroid Build Coastguard Worker             isOk = isOk && pixelOk;
133*35238bceSAndroid Build Coastguard Worker         }
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     if (!isOk)
136*35238bceSAndroid Build Coastguard Worker     {
137*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
138*35238bceSAndroid Build Coastguard Worker         log << TestLog::ImageSet("Verfication result", "Result of rendering")
139*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("Result", "Result", image) << TestLog::Image("ErrorMask", "Error mask", error)
140*35238bceSAndroid Build Coastguard Worker             << TestLog::EndImageSet;
141*35238bceSAndroid Build Coastguard Worker     }
142*35238bceSAndroid Build Coastguard Worker     else
143*35238bceSAndroid Build Coastguard Worker     {
144*35238bceSAndroid Build Coastguard Worker         log << TestLog::ImageSet("Verfication result", "Result of rendering")
145*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("Result", "Result", image) << TestLog::EndImageSet;
146*35238bceSAndroid Build Coastguard Worker     }
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker     return isOk;
149*35238bceSAndroid Build Coastguard Worker }
150*35238bceSAndroid Build Coastguard Worker 
addTestIterations(gls::DrawTest * test,gls::DrawTestSpec & spec,TestIterationType type)151*35238bceSAndroid Build Coastguard Worker static void addTestIterations(gls::DrawTest *test, gls::DrawTestSpec &spec, TestIterationType type)
152*35238bceSAndroid Build Coastguard Worker {
153*35238bceSAndroid Build Coastguard Worker     if (type == TYPE_DRAW_COUNT)
154*35238bceSAndroid Build Coastguard Worker     {
155*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount = 1;
156*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "draw count = 1");
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount = 5;
159*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "draw count = 5");
160*35238bceSAndroid Build Coastguard Worker 
161*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount = 25;
162*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "draw count = 25");
163*35238bceSAndroid Build Coastguard Worker     }
164*35238bceSAndroid Build Coastguard Worker     else if (type == TYPE_INSTANCE_COUNT)
165*35238bceSAndroid Build Coastguard Worker     {
166*35238bceSAndroid Build Coastguard Worker         spec.instanceCount = 1;
167*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "instance count = 1");
168*35238bceSAndroid Build Coastguard Worker 
169*35238bceSAndroid Build Coastguard Worker         spec.instanceCount = 4;
170*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "instance count = 4");
171*35238bceSAndroid Build Coastguard Worker 
172*35238bceSAndroid Build Coastguard Worker         spec.instanceCount = 11;
173*35238bceSAndroid Build Coastguard Worker         test->addIteration(spec, "instance count = 11");
174*35238bceSAndroid Build Coastguard Worker     }
175*35238bceSAndroid Build Coastguard Worker     else
176*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
177*35238bceSAndroid Build Coastguard Worker }
178*35238bceSAndroid Build Coastguard Worker 
genBasicSpec(gls::DrawTestSpec & spec,glu::ContextType contextType,gls::DrawTestSpec::DrawMethod method)179*35238bceSAndroid Build Coastguard Worker static void genBasicSpec(gls::DrawTestSpec &spec, glu::ContextType contextType, gls::DrawTestSpec::DrawMethod method)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker     spec.apiType            = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
182*35238bceSAndroid Build Coastguard Worker     spec.primitive          = gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
183*35238bceSAndroid Build Coastguard Worker     spec.primitiveCount     = 5;
184*35238bceSAndroid Build Coastguard Worker     spec.drawMethod         = method;
185*35238bceSAndroid Build Coastguard Worker     spec.indexType          = gls::DrawTestSpec::INDEXTYPE_LAST;
186*35238bceSAndroid Build Coastguard Worker     spec.indexPointerOffset = 0;
187*35238bceSAndroid Build Coastguard Worker     spec.indexStorage       = gls::DrawTestSpec::STORAGE_LAST;
188*35238bceSAndroid Build Coastguard Worker     spec.first              = 0;
189*35238bceSAndroid Build Coastguard Worker     spec.indexMin           = 0;
190*35238bceSAndroid Build Coastguard Worker     spec.indexMax           = 0;
191*35238bceSAndroid Build Coastguard Worker     spec.instanceCount      = 1;
192*35238bceSAndroid Build Coastguard Worker     spec.indirectOffset     = 0;
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker     spec.attribs.resize(2);
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
197*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
198*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
199*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
200*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].componentCount      = 4;
201*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].offset              = 0;
202*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].stride              = 0;
203*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].normalize           = false;
204*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].instanceDivisor     = 0;
205*35238bceSAndroid Build Coastguard Worker     spec.attribs[0].useDefaultAttribute = false;
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
208*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
209*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
210*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
211*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].componentCount      = 2;
212*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].offset              = 0;
213*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].stride              = 0;
214*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].normalize           = false;
215*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].instanceDivisor     = 0;
216*35238bceSAndroid Build Coastguard Worker     spec.attribs[1].useDefaultAttribute = false;
217*35238bceSAndroid Build Coastguard Worker }
218*35238bceSAndroid Build Coastguard Worker 
sizeToString(int size)219*35238bceSAndroid Build Coastguard Worker static std::string sizeToString(int size)
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker     if (size < 1024)
222*35238bceSAndroid Build Coastguard Worker         return de::toString(size) + " byte(s)";
223*35238bceSAndroid Build Coastguard Worker     if (size < 1024 * 1024)
224*35238bceSAndroid Build Coastguard Worker         return de::toString(size / 1024) + " KB";
225*35238bceSAndroid Build Coastguard Worker     return de::toString(size / 1024 / 1024) + " MB";
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker 
228*35238bceSAndroid Build Coastguard Worker class AttributeGroup : public TestCaseGroup
229*35238bceSAndroid Build Coastguard Worker {
230*35238bceSAndroid Build Coastguard Worker public:
231*35238bceSAndroid Build Coastguard Worker     AttributeGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod,
232*35238bceSAndroid Build Coastguard Worker                    gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType,
233*35238bceSAndroid Build Coastguard Worker                    gls::DrawTestSpec::Storage indexStorage);
234*35238bceSAndroid Build Coastguard Worker     ~AttributeGroup(void);
235*35238bceSAndroid Build Coastguard Worker 
236*35238bceSAndroid Build Coastguard Worker     void init(void);
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker private:
239*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod m_method;
240*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::Primitive m_primitive;
241*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::IndexType m_indexType;
242*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::Storage m_indexStorage;
243*35238bceSAndroid Build Coastguard Worker };
244*35238bceSAndroid Build Coastguard Worker 
AttributeGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod,gls::DrawTestSpec::Primitive primitive,gls::DrawTestSpec::IndexType indexType,gls::DrawTestSpec::Storage indexStorage)245*35238bceSAndroid Build Coastguard Worker AttributeGroup::AttributeGroup(Context &context, const char *name, const char *descr,
246*35238bceSAndroid Build Coastguard Worker                                gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive,
247*35238bceSAndroid Build Coastguard Worker                                gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
248*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
249*35238bceSAndroid Build Coastguard Worker     , m_method(drawMethod)
250*35238bceSAndroid Build Coastguard Worker     , m_primitive(primitive)
251*35238bceSAndroid Build Coastguard Worker     , m_indexType(indexType)
252*35238bceSAndroid Build Coastguard Worker     , m_indexStorage(indexStorage)
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
~AttributeGroup(void)256*35238bceSAndroid Build Coastguard Worker AttributeGroup::~AttributeGroup(void)
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker }
259*35238bceSAndroid Build Coastguard Worker 
init(void)260*35238bceSAndroid Build Coastguard Worker void AttributeGroup::init(void)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker     // Single attribute
263*35238bceSAndroid Build Coastguard Worker     {
264*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test =
265*35238bceSAndroid Build Coastguard Worker             new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
266*35238bceSAndroid Build Coastguard Worker         glu::ContextType contextType = m_context.getRenderContext().getType();
267*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec spec;
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker         spec.apiType            = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
270*35238bceSAndroid Build Coastguard Worker         spec.primitive          = m_primitive;
271*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount     = 5;
272*35238bceSAndroid Build Coastguard Worker         spec.drawMethod         = m_method;
273*35238bceSAndroid Build Coastguard Worker         spec.indexType          = m_indexType;
274*35238bceSAndroid Build Coastguard Worker         spec.indexPointerOffset = 0;
275*35238bceSAndroid Build Coastguard Worker         spec.indexStorage       = m_indexStorage;
276*35238bceSAndroid Build Coastguard Worker         spec.first              = 0;
277*35238bceSAndroid Build Coastguard Worker         spec.indexMin           = 0;
278*35238bceSAndroid Build Coastguard Worker         spec.indexMax           = 0;
279*35238bceSAndroid Build Coastguard Worker         spec.instanceCount      = 1;
280*35238bceSAndroid Build Coastguard Worker         spec.indirectOffset     = 0;
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker         spec.attribs.resize(1);
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
285*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
286*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
287*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
288*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].componentCount      = 2;
289*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].offset              = 0;
290*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].stride              = 0;
291*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].normalize           = false;
292*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].instanceDivisor     = 0;
293*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].useDefaultAttribute = false;
294*35238bceSAndroid Build Coastguard Worker 
295*35238bceSAndroid Build Coastguard Worker         addTestIterations(test, spec, TYPE_DRAW_COUNT);
296*35238bceSAndroid Build Coastguard Worker 
297*35238bceSAndroid Build Coastguard Worker         this->addChild(test);
298*35238bceSAndroid Build Coastguard Worker     }
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker     // Multiple attribute
301*35238bceSAndroid Build Coastguard Worker     {
302*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test          = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes",
303*35238bceSAndroid Build Coastguard Worker                                                          "Multiple attribute arrays.");
304*35238bceSAndroid Build Coastguard Worker         glu::ContextType contextType = m_context.getRenderContext().getType();
305*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec spec;
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker         spec.apiType            = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
308*35238bceSAndroid Build Coastguard Worker         spec.primitive          = m_primitive;
309*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount     = 5;
310*35238bceSAndroid Build Coastguard Worker         spec.drawMethod         = m_method;
311*35238bceSAndroid Build Coastguard Worker         spec.indexType          = m_indexType;
312*35238bceSAndroid Build Coastguard Worker         spec.indexPointerOffset = 0;
313*35238bceSAndroid Build Coastguard Worker         spec.indexStorage       = m_indexStorage;
314*35238bceSAndroid Build Coastguard Worker         spec.first              = 0;
315*35238bceSAndroid Build Coastguard Worker         spec.indexMin           = 0;
316*35238bceSAndroid Build Coastguard Worker         spec.indexMax           = 0;
317*35238bceSAndroid Build Coastguard Worker         spec.instanceCount      = 1;
318*35238bceSAndroid Build Coastguard Worker         spec.indirectOffset     = 0;
319*35238bceSAndroid Build Coastguard Worker 
320*35238bceSAndroid Build Coastguard Worker         spec.attribs.resize(2);
321*35238bceSAndroid Build Coastguard Worker 
322*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
323*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
324*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
325*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
326*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].componentCount      = 4;
327*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].offset              = 0;
328*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].stride              = 0;
329*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].normalize           = false;
330*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].instanceDivisor     = 0;
331*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].useDefaultAttribute = false;
332*35238bceSAndroid Build Coastguard Worker 
333*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
334*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
335*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
336*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
337*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].componentCount      = 2;
338*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].offset              = 0;
339*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].stride              = 0;
340*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].normalize           = false;
341*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].instanceDivisor     = 0;
342*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].useDefaultAttribute = false;
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker         addTestIterations(test, spec, TYPE_DRAW_COUNT);
345*35238bceSAndroid Build Coastguard Worker 
346*35238bceSAndroid Build Coastguard Worker         this->addChild(test);
347*35238bceSAndroid Build Coastguard Worker     }
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker     // Multiple attribute, second one divided
350*35238bceSAndroid Build Coastguard Worker     {
351*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes",
352*35238bceSAndroid Build Coastguard Worker                                                 "Instanced attribute array.");
353*35238bceSAndroid Build Coastguard Worker         glu::ContextType contextType = m_context.getRenderContext().getType();
354*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec spec;
355*35238bceSAndroid Build Coastguard Worker 
356*35238bceSAndroid Build Coastguard Worker         spec.apiType            = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
357*35238bceSAndroid Build Coastguard Worker         spec.primitive          = m_primitive;
358*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount     = 5;
359*35238bceSAndroid Build Coastguard Worker         spec.drawMethod         = m_method;
360*35238bceSAndroid Build Coastguard Worker         spec.indexType          = m_indexType;
361*35238bceSAndroid Build Coastguard Worker         spec.indexPointerOffset = 0;
362*35238bceSAndroid Build Coastguard Worker         spec.indexStorage       = m_indexStorage;
363*35238bceSAndroid Build Coastguard Worker         spec.first              = 0;
364*35238bceSAndroid Build Coastguard Worker         spec.indexMin           = 0;
365*35238bceSAndroid Build Coastguard Worker         spec.indexMax           = 0;
366*35238bceSAndroid Build Coastguard Worker         spec.instanceCount      = 1;
367*35238bceSAndroid Build Coastguard Worker         spec.indirectOffset     = 0;
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker         spec.attribs.resize(3);
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
372*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
373*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
374*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
375*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].componentCount      = 4;
376*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].offset              = 0;
377*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].stride              = 0;
378*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].normalize           = false;
379*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].instanceDivisor     = 0;
380*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].useDefaultAttribute = false;
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker         // Add another position component so the instances wont be drawn on each other
383*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].inputType                   = gls::DrawTestSpec::INPUTTYPE_FLOAT;
384*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].outputType                  = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
385*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].storage                     = gls::DrawTestSpec::STORAGE_BUFFER;
386*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].usage                       = gls::DrawTestSpec::USAGE_STATIC_DRAW;
387*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].componentCount              = 2;
388*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].offset                      = 0;
389*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].stride                      = 0;
390*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].normalize                   = false;
391*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].instanceDivisor             = 1;
392*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].useDefaultAttribute         = false;
393*35238bceSAndroid Build Coastguard Worker         spec.attribs[1].additionalPositionAttribute = true;
394*35238bceSAndroid Build Coastguard Worker 
395*35238bceSAndroid Build Coastguard Worker         // Instanced color
396*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
397*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
398*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
399*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
400*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].componentCount      = 3;
401*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].offset              = 0;
402*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].stride              = 0;
403*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].normalize           = false;
404*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].instanceDivisor     = 1;
405*35238bceSAndroid Build Coastguard Worker         spec.attribs[2].useDefaultAttribute = false;
406*35238bceSAndroid Build Coastguard Worker 
407*35238bceSAndroid Build Coastguard Worker         addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
408*35238bceSAndroid Build Coastguard Worker 
409*35238bceSAndroid Build Coastguard Worker         this->addChild(test);
410*35238bceSAndroid Build Coastguard Worker     }
411*35238bceSAndroid Build Coastguard Worker 
412*35238bceSAndroid Build Coastguard Worker     // Multiple attribute, second one default
413*35238bceSAndroid Build Coastguard Worker     {
414*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test          = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute",
415*35238bceSAndroid Build Coastguard Worker                                                          "Attribute specified with glVertexAttrib*.");
416*35238bceSAndroid Build Coastguard Worker         glu::ContextType contextType = m_context.getRenderContext().getType();
417*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec spec;
418*35238bceSAndroid Build Coastguard Worker 
419*35238bceSAndroid Build Coastguard Worker         spec.apiType            = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
420*35238bceSAndroid Build Coastguard Worker         spec.primitive          = m_primitive;
421*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount     = 5;
422*35238bceSAndroid Build Coastguard Worker         spec.drawMethod         = m_method;
423*35238bceSAndroid Build Coastguard Worker         spec.indexType          = m_indexType;
424*35238bceSAndroid Build Coastguard Worker         spec.indexPointerOffset = 0;
425*35238bceSAndroid Build Coastguard Worker         spec.indexStorage       = m_indexStorage;
426*35238bceSAndroid Build Coastguard Worker         spec.first              = 0;
427*35238bceSAndroid Build Coastguard Worker         spec.indexMin           = 0;
428*35238bceSAndroid Build Coastguard Worker         spec.indexMax           = 0;
429*35238bceSAndroid Build Coastguard Worker         spec.instanceCount      = 1;
430*35238bceSAndroid Build Coastguard Worker         spec.indirectOffset     = 0;
431*35238bceSAndroid Build Coastguard Worker 
432*35238bceSAndroid Build Coastguard Worker         spec.attribs.resize(2);
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].inputType           = gls::DrawTestSpec::INPUTTYPE_FLOAT;
435*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].outputType          = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
436*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
437*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
438*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].componentCount      = 2;
439*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].offset              = 0;
440*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].stride              = 0;
441*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].normalize           = false;
442*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].instanceDivisor     = 0;
443*35238bceSAndroid Build Coastguard Worker         spec.attribs[0].useDefaultAttribute = false;
444*35238bceSAndroid Build Coastguard Worker 
445*35238bceSAndroid Build Coastguard Worker         struct IOPair
446*35238bceSAndroid Build Coastguard Worker         {
447*35238bceSAndroid Build Coastguard Worker             gls::DrawTestSpec::InputType input;
448*35238bceSAndroid Build Coastguard Worker             gls::DrawTestSpec::OutputType output;
449*35238bceSAndroid Build Coastguard Worker             int componentCount;
450*35238bceSAndroid Build Coastguard Worker         } iopairs[] = {
451*35238bceSAndroid Build Coastguard Worker             {gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4},
452*35238bceSAndroid Build Coastguard Worker             {gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2},
453*35238bceSAndroid Build Coastguard Worker             {gls::DrawTestSpec::INPUTTYPE_INT, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4},
454*35238bceSAndroid Build Coastguard Worker             {gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4},
455*35238bceSAndroid Build Coastguard Worker         };
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker         for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
458*35238bceSAndroid Build Coastguard Worker         {
459*35238bceSAndroid Build Coastguard Worker             const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) +
460*35238bceSAndroid Build Coastguard Worker                                      de::toString(iopairs[ioNdx].componentCount) + " to " +
461*35238bceSAndroid Build Coastguard Worker                                      gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].inputType           = iopairs[ioNdx].input;
464*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].outputType          = iopairs[ioNdx].output;
465*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].storage             = gls::DrawTestSpec::STORAGE_BUFFER;
466*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].usage               = gls::DrawTestSpec::USAGE_STATIC_DRAW;
467*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].componentCount      = iopairs[ioNdx].componentCount;
468*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].offset              = 0;
469*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].stride              = 0;
470*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].normalize           = false;
471*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].instanceDivisor     = 0;
472*35238bceSAndroid Build Coastguard Worker             spec.attribs[1].useDefaultAttribute = true;
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker             test->addIteration(spec, desc.c_str());
475*35238bceSAndroid Build Coastguard Worker         }
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker         this->addChild(test);
478*35238bceSAndroid Build Coastguard Worker     }
479*35238bceSAndroid Build Coastguard Worker }
480*35238bceSAndroid Build Coastguard Worker 
481*35238bceSAndroid Build Coastguard Worker class IndexGroup : public TestCaseGroup
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker public:
484*35238bceSAndroid Build Coastguard Worker     IndexGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod);
485*35238bceSAndroid Build Coastguard Worker     ~IndexGroup(void);
486*35238bceSAndroid Build Coastguard Worker 
487*35238bceSAndroid Build Coastguard Worker     void init(void);
488*35238bceSAndroid Build Coastguard Worker 
489*35238bceSAndroid Build Coastguard Worker private:
490*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod m_method;
491*35238bceSAndroid Build Coastguard Worker };
492*35238bceSAndroid Build Coastguard Worker 
IndexGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)493*35238bceSAndroid Build Coastguard Worker IndexGroup::IndexGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod)
494*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
495*35238bceSAndroid Build Coastguard Worker     , m_method(drawMethod)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker }
498*35238bceSAndroid Build Coastguard Worker 
~IndexGroup(void)499*35238bceSAndroid Build Coastguard Worker IndexGroup::~IndexGroup(void)
500*35238bceSAndroid Build Coastguard Worker {
501*35238bceSAndroid Build Coastguard Worker }
502*35238bceSAndroid Build Coastguard Worker 
init(void)503*35238bceSAndroid Build Coastguard Worker void IndexGroup::init(void)
504*35238bceSAndroid Build Coastguard Worker {
505*35238bceSAndroid Build Coastguard Worker     struct IndexTest
506*35238bceSAndroid Build Coastguard Worker     {
507*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::IndexType type;
508*35238bceSAndroid Build Coastguard Worker         int offsets[3];
509*35238bceSAndroid Build Coastguard Worker     };
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker     const IndexTest tests[] = {
512*35238bceSAndroid Build Coastguard Worker         {gls::DrawTestSpec::INDEXTYPE_BYTE, {0, 1, -1}},
513*35238bceSAndroid Build Coastguard Worker         {gls::DrawTestSpec::INDEXTYPE_SHORT, {0, 2, -1}},
514*35238bceSAndroid Build Coastguard Worker         {gls::DrawTestSpec::INDEXTYPE_INT, {0, 4, -1}},
515*35238bceSAndroid Build Coastguard Worker     };
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec spec;
518*35238bceSAndroid Build Coastguard Worker     genBasicSpec(spec, m_context.getRenderContext().getType(), m_method);
519*35238bceSAndroid Build Coastguard Worker 
520*35238bceSAndroid Build Coastguard Worker     spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
521*35238bceSAndroid Build Coastguard Worker 
522*35238bceSAndroid Build Coastguard Worker     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
523*35238bceSAndroid Build Coastguard Worker     {
524*35238bceSAndroid Build Coastguard Worker         const IndexTest &indexTest = tests[testNdx];
525*35238bceSAndroid Build Coastguard Worker 
526*35238bceSAndroid Build Coastguard Worker         const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
527*35238bceSAndroid Build Coastguard Worker         const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
528*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test    = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
529*35238bceSAndroid Build Coastguard Worker 
530*35238bceSAndroid Build Coastguard Worker         spec.indexType = indexTest.type;
531*35238bceSAndroid Build Coastguard Worker 
532*35238bceSAndroid Build Coastguard Worker         for (int iterationNdx = 0;
533*35238bceSAndroid Build Coastguard Worker              iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1;
534*35238bceSAndroid Build Coastguard Worker              ++iterationNdx)
535*35238bceSAndroid Build Coastguard Worker         {
536*35238bceSAndroid Build Coastguard Worker             const std::string iterationDesc =
537*35238bceSAndroid Build Coastguard Worker                 std::string("first vertex ") +
538*35238bceSAndroid Build Coastguard Worker                 de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
539*35238bceSAndroid Build Coastguard Worker             spec.indexPointerOffset = indexTest.offsets[iterationNdx];
540*35238bceSAndroid Build Coastguard Worker             test->addIteration(spec, iterationDesc.c_str());
541*35238bceSAndroid Build Coastguard Worker         }
542*35238bceSAndroid Build Coastguard Worker 
543*35238bceSAndroid Build Coastguard Worker         addChild(test);
544*35238bceSAndroid Build Coastguard Worker     }
545*35238bceSAndroid Build Coastguard Worker }
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker class BaseVertexGroup : public TestCaseGroup
548*35238bceSAndroid Build Coastguard Worker {
549*35238bceSAndroid Build Coastguard Worker public:
550*35238bceSAndroid Build Coastguard Worker     BaseVertexGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod);
551*35238bceSAndroid Build Coastguard Worker     ~BaseVertexGroup(void);
552*35238bceSAndroid Build Coastguard Worker 
553*35238bceSAndroid Build Coastguard Worker     void init(void);
554*35238bceSAndroid Build Coastguard Worker 
555*35238bceSAndroid Build Coastguard Worker private:
556*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod m_method;
557*35238bceSAndroid Build Coastguard Worker };
558*35238bceSAndroid Build Coastguard Worker 
BaseVertexGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)559*35238bceSAndroid Build Coastguard Worker BaseVertexGroup::BaseVertexGroup(Context &context, const char *name, const char *descr,
560*35238bceSAndroid Build Coastguard Worker                                  gls::DrawTestSpec::DrawMethod drawMethod)
561*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
562*35238bceSAndroid Build Coastguard Worker     , m_method(drawMethod)
563*35238bceSAndroid Build Coastguard Worker {
564*35238bceSAndroid Build Coastguard Worker }
565*35238bceSAndroid Build Coastguard Worker 
~BaseVertexGroup(void)566*35238bceSAndroid Build Coastguard Worker BaseVertexGroup::~BaseVertexGroup(void)
567*35238bceSAndroid Build Coastguard Worker {
568*35238bceSAndroid Build Coastguard Worker }
569*35238bceSAndroid Build Coastguard Worker 
init(void)570*35238bceSAndroid Build Coastguard Worker void BaseVertexGroup::init(void)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker     struct IndexTest
573*35238bceSAndroid Build Coastguard Worker     {
574*35238bceSAndroid Build Coastguard Worker         bool positiveBase;
575*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::IndexType type;
576*35238bceSAndroid Build Coastguard Worker         int baseVertex[2];
577*35238bceSAndroid Build Coastguard Worker     };
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker     const IndexTest tests[] = {
580*35238bceSAndroid Build Coastguard Worker         {true, gls::DrawTestSpec::INDEXTYPE_BYTE, {1, 2}},     {true, gls::DrawTestSpec::INDEXTYPE_SHORT, {1, 2}},
581*35238bceSAndroid Build Coastguard Worker         {true, gls::DrawTestSpec::INDEXTYPE_INT, {1, 2}},      {false, gls::DrawTestSpec::INDEXTYPE_BYTE, {-1, -2}},
582*35238bceSAndroid Build Coastguard Worker         {false, gls::DrawTestSpec::INDEXTYPE_SHORT, {-1, -2}}, {false, gls::DrawTestSpec::INDEXTYPE_INT, {-1, -2}},
583*35238bceSAndroid Build Coastguard Worker     };
584*35238bceSAndroid Build Coastguard Worker 
585*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec spec;
586*35238bceSAndroid Build Coastguard Worker     genBasicSpec(spec, m_context.getRenderContext().getType(), m_method);
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker     spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
589*35238bceSAndroid Build Coastguard Worker 
590*35238bceSAndroid Build Coastguard Worker     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
591*35238bceSAndroid Build Coastguard Worker     {
592*35238bceSAndroid Build Coastguard Worker         const IndexTest &indexTest = tests[testNdx];
593*35238bceSAndroid Build Coastguard Worker 
594*35238bceSAndroid Build Coastguard Worker         const std::string name = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") +
595*35238bceSAndroid Build Coastguard Worker                                  gls::DrawTestSpec::indexTypeToString(indexTest.type);
596*35238bceSAndroid Build Coastguard Worker         const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
597*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test    = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
598*35238bceSAndroid Build Coastguard Worker 
599*35238bceSAndroid Build Coastguard Worker         spec.indexType = indexTest.type;
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker         for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
602*35238bceSAndroid Build Coastguard Worker         {
603*35238bceSAndroid Build Coastguard Worker             const std::string iterationDesc =
604*35238bceSAndroid Build Coastguard Worker                 std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
605*35238bceSAndroid Build Coastguard Worker             spec.baseVertex = indexTest.baseVertex[iterationNdx];
606*35238bceSAndroid Build Coastguard Worker             test->addIteration(spec, iterationDesc.c_str());
607*35238bceSAndroid Build Coastguard Worker         }
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker         addChild(test);
610*35238bceSAndroid Build Coastguard Worker     }
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker class FirstGroup : public TestCaseGroup
614*35238bceSAndroid Build Coastguard Worker {
615*35238bceSAndroid Build Coastguard Worker public:
616*35238bceSAndroid Build Coastguard Worker     FirstGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod);
617*35238bceSAndroid Build Coastguard Worker     ~FirstGroup(void);
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker     void init(void);
620*35238bceSAndroid Build Coastguard Worker 
621*35238bceSAndroid Build Coastguard Worker private:
622*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod m_method;
623*35238bceSAndroid Build Coastguard Worker };
624*35238bceSAndroid Build Coastguard Worker 
FirstGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)625*35238bceSAndroid Build Coastguard Worker FirstGroup::FirstGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod)
626*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
627*35238bceSAndroid Build Coastguard Worker     , m_method(drawMethod)
628*35238bceSAndroid Build Coastguard Worker {
629*35238bceSAndroid Build Coastguard Worker }
630*35238bceSAndroid Build Coastguard Worker 
~FirstGroup(void)631*35238bceSAndroid Build Coastguard Worker FirstGroup::~FirstGroup(void)
632*35238bceSAndroid Build Coastguard Worker {
633*35238bceSAndroid Build Coastguard Worker }
634*35238bceSAndroid Build Coastguard Worker 
init(void)635*35238bceSAndroid Build Coastguard Worker void FirstGroup::init(void)
636*35238bceSAndroid Build Coastguard Worker {
637*35238bceSAndroid Build Coastguard Worker     const int firsts[] = {1, 3, 17};
638*35238bceSAndroid Build Coastguard Worker 
639*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec spec;
640*35238bceSAndroid Build Coastguard Worker     genBasicSpec(spec, m_context.getRenderContext().getType(), m_method);
641*35238bceSAndroid Build Coastguard Worker 
642*35238bceSAndroid Build Coastguard Worker     for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); ++firstNdx)
643*35238bceSAndroid Build Coastguard Worker     {
644*35238bceSAndroid Build Coastguard Worker         const std::string name = std::string("first_") + de::toString(firsts[firstNdx]);
645*35238bceSAndroid Build Coastguard Worker         const std::string desc = std::string("first ") + de::toString(firsts[firstNdx]);
646*35238bceSAndroid Build Coastguard Worker         gls::DrawTest *test    = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
647*35238bceSAndroid Build Coastguard Worker 
648*35238bceSAndroid Build Coastguard Worker         spec.first = firsts[firstNdx];
649*35238bceSAndroid Build Coastguard Worker 
650*35238bceSAndroid Build Coastguard Worker         addTestIterations(test, spec, TYPE_DRAW_COUNT);
651*35238bceSAndroid Build Coastguard Worker 
652*35238bceSAndroid Build Coastguard Worker         this->addChild(test);
653*35238bceSAndroid Build Coastguard Worker     }
654*35238bceSAndroid Build Coastguard Worker }
655*35238bceSAndroid Build Coastguard Worker 
656*35238bceSAndroid Build Coastguard Worker class MethodGroup : public TestCaseGroup
657*35238bceSAndroid Build Coastguard Worker {
658*35238bceSAndroid Build Coastguard Worker public:
659*35238bceSAndroid Build Coastguard Worker     MethodGroup(Context &context, const char *name, const char *descr, gls::DrawTestSpec::DrawMethod drawMethod);
660*35238bceSAndroid Build Coastguard Worker     ~MethodGroup(void);
661*35238bceSAndroid Build Coastguard Worker 
662*35238bceSAndroid Build Coastguard Worker     void init(void);
663*35238bceSAndroid Build Coastguard Worker 
664*35238bceSAndroid Build Coastguard Worker private:
665*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod m_method;
666*35238bceSAndroid Build Coastguard Worker };
667*35238bceSAndroid Build Coastguard Worker 
MethodGroup(Context & context,const char * name,const char * descr,gls::DrawTestSpec::DrawMethod drawMethod)668*35238bceSAndroid Build Coastguard Worker MethodGroup::MethodGroup(Context &context, const char *name, const char *descr,
669*35238bceSAndroid Build Coastguard Worker                          gls::DrawTestSpec::DrawMethod drawMethod)
670*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
671*35238bceSAndroid Build Coastguard Worker     , m_method(drawMethod)
672*35238bceSAndroid Build Coastguard Worker {
673*35238bceSAndroid Build Coastguard Worker }
674*35238bceSAndroid Build Coastguard Worker 
~MethodGroup(void)675*35238bceSAndroid Build Coastguard Worker MethodGroup::~MethodGroup(void)
676*35238bceSAndroid Build Coastguard Worker {
677*35238bceSAndroid Build Coastguard Worker }
678*35238bceSAndroid Build Coastguard Worker 
init(void)679*35238bceSAndroid Build Coastguard Worker void MethodGroup::init(void)
680*35238bceSAndroid Build Coastguard Worker {
681*35238bceSAndroid Build Coastguard Worker     const bool indexed  = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT);
682*35238bceSAndroid Build Coastguard Worker     const bool hasFirst = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT);
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker     const gls::DrawTestSpec::Primitive primitive[] = {
685*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_POINTS,       gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
686*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN, gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
687*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_LINES,        gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
688*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_LINE_LOOP};
689*35238bceSAndroid Build Coastguard Worker 
690*35238bceSAndroid Build Coastguard Worker     if (hasFirst)
691*35238bceSAndroid Build Coastguard Worker     {
692*35238bceSAndroid Build Coastguard Worker         // First-tests
693*35238bceSAndroid Build Coastguard Worker         this->addChild(new FirstGroup(m_context, "first", "First tests", m_method));
694*35238bceSAndroid Build Coastguard Worker     }
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker     if (indexed)
697*35238bceSAndroid Build Coastguard Worker     {
698*35238bceSAndroid Build Coastguard Worker         // Index-tests
699*35238bceSAndroid Build Coastguard Worker         this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
700*35238bceSAndroid Build Coastguard Worker         this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
701*35238bceSAndroid Build Coastguard Worker     }
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
704*35238bceSAndroid Build Coastguard Worker     {
705*35238bceSAndroid Build Coastguard Worker         const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
706*35238bceSAndroid Build Coastguard Worker         const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker         this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx],
709*35238bceSAndroid Build Coastguard Worker                                           gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
710*35238bceSAndroid Build Coastguard Worker     }
711*35238bceSAndroid Build Coastguard Worker }
712*35238bceSAndroid Build Coastguard Worker 
713*35238bceSAndroid Build Coastguard Worker class GridProgram : public sglr::ShaderProgram
714*35238bceSAndroid Build Coastguard Worker {
715*35238bceSAndroid Build Coastguard Worker public:
716*35238bceSAndroid Build Coastguard Worker     GridProgram(void);
717*35238bceSAndroid Build Coastguard Worker 
718*35238bceSAndroid Build Coastguard Worker     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const;
719*35238bceSAndroid Build Coastguard Worker     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
720*35238bceSAndroid Build Coastguard Worker                         const rr::FragmentShadingContext &context) const;
721*35238bceSAndroid Build Coastguard Worker };
722*35238bceSAndroid Build Coastguard Worker 
GridProgram(void)723*35238bceSAndroid Build Coastguard Worker GridProgram::GridProgram(void)
724*35238bceSAndroid Build Coastguard Worker     : sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
725*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
726*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_offset", rr::GENERICVECTYPE_FLOAT)
727*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexAttribute("a_color", rr::GENERICVECTYPE_FLOAT)
728*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
729*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
730*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::VertexSource("#version 310 es\n"
731*35238bceSAndroid Build Coastguard Worker                                                       "in highp vec4 a_position;\n"
732*35238bceSAndroid Build Coastguard Worker                                                       "in highp vec4 a_offset;\n"
733*35238bceSAndroid Build Coastguard Worker                                                       "in highp vec4 a_color;\n"
734*35238bceSAndroid Build Coastguard Worker                                                       "out highp vec4 v_color;\n"
735*35238bceSAndroid Build Coastguard Worker                                                       "void main(void)\n"
736*35238bceSAndroid Build Coastguard Worker                                                       "{\n"
737*35238bceSAndroid Build Coastguard Worker                                                       "    gl_Position = a_position + a_offset;\n"
738*35238bceSAndroid Build Coastguard Worker                                                       "    v_color = a_color;\n"
739*35238bceSAndroid Build Coastguard Worker                                                       "}\n")
740*35238bceSAndroid Build Coastguard Worker                           << sglr::pdec::FragmentSource("#version 310 es\n"
741*35238bceSAndroid Build Coastguard Worker                                                         "layout(location = 0) out highp vec4 dEQP_FragColor;\n"
742*35238bceSAndroid Build Coastguard Worker                                                         "in highp vec4 v_color;\n"
743*35238bceSAndroid Build Coastguard Worker                                                         "void main(void)\n"
744*35238bceSAndroid Build Coastguard Worker                                                         "{\n"
745*35238bceSAndroid Build Coastguard Worker                                                         "    dEQP_FragColor = v_color;\n"
746*35238bceSAndroid Build Coastguard Worker                                                         "}\n"))
747*35238bceSAndroid Build Coastguard Worker {
748*35238bceSAndroid Build Coastguard Worker }
749*35238bceSAndroid Build Coastguard Worker 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const750*35238bceSAndroid Build Coastguard Worker void GridProgram::shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets,
751*35238bceSAndroid Build Coastguard Worker                                 const int numPackets) const
752*35238bceSAndroid Build Coastguard Worker {
753*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numPackets; ++ndx)
754*35238bceSAndroid Build Coastguard Worker     {
755*35238bceSAndroid Build Coastguard Worker         packets[ndx]->position =
756*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[0], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx) +
757*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[1], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
758*35238bceSAndroid Build Coastguard Worker         packets[ndx]->outputs[0] =
759*35238bceSAndroid Build Coastguard Worker             rr::readVertexAttribFloat(inputs[2], packets[ndx]->instanceNdx, packets[ndx]->vertexNdx);
760*35238bceSAndroid Build Coastguard Worker     }
761*35238bceSAndroid Build Coastguard Worker }
762*35238bceSAndroid Build Coastguard Worker 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const763*35238bceSAndroid Build Coastguard Worker void GridProgram::shadeFragments(rr::FragmentPacket *packets, const int numPackets,
764*35238bceSAndroid Build Coastguard Worker                                  const rr::FragmentShadingContext &context) const
765*35238bceSAndroid Build Coastguard Worker {
766*35238bceSAndroid Build Coastguard Worker     for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
767*35238bceSAndroid Build Coastguard Worker         for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
768*35238bceSAndroid Build Coastguard Worker             rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
769*35238bceSAndroid Build Coastguard Worker                                     rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx));
770*35238bceSAndroid Build Coastguard Worker }
771*35238bceSAndroid Build Coastguard Worker 
772*35238bceSAndroid Build Coastguard Worker class InstancedGridRenderTest : public TestCase
773*35238bceSAndroid Build Coastguard Worker {
774*35238bceSAndroid Build Coastguard Worker public:
775*35238bceSAndroid Build Coastguard Worker     InstancedGridRenderTest(Context &context, const char *name, const char *desc, int gridSide, bool useIndices);
776*35238bceSAndroid Build Coastguard Worker     ~InstancedGridRenderTest(void);
777*35238bceSAndroid Build Coastguard Worker 
778*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker private:
781*35238bceSAndroid Build Coastguard Worker     void renderTo(sglr::Context &ctx, sglr::ShaderProgram &program, tcu::Surface &dst);
782*35238bceSAndroid Build Coastguard Worker 
783*35238bceSAndroid Build Coastguard Worker     const int m_gridSide;
784*35238bceSAndroid Build Coastguard Worker     const bool m_useIndices;
785*35238bceSAndroid Build Coastguard Worker };
786*35238bceSAndroid Build Coastguard Worker 
InstancedGridRenderTest(Context & context,const char * name,const char * desc,int gridSide,bool useIndices)787*35238bceSAndroid Build Coastguard Worker InstancedGridRenderTest::InstancedGridRenderTest(Context &context, const char *name, const char *desc, int gridSide,
788*35238bceSAndroid Build Coastguard Worker                                                  bool useIndices)
789*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
790*35238bceSAndroid Build Coastguard Worker     , m_gridSide(gridSide)
791*35238bceSAndroid Build Coastguard Worker     , m_useIndices(useIndices)
792*35238bceSAndroid Build Coastguard Worker {
793*35238bceSAndroid Build Coastguard Worker }
794*35238bceSAndroid Build Coastguard Worker 
~InstancedGridRenderTest(void)795*35238bceSAndroid Build Coastguard Worker InstancedGridRenderTest::~InstancedGridRenderTest(void)
796*35238bceSAndroid Build Coastguard Worker {
797*35238bceSAndroid Build Coastguard Worker }
798*35238bceSAndroid Build Coastguard Worker 
iterate(void)799*35238bceSAndroid Build Coastguard Worker InstancedGridRenderTest::IterateResult InstancedGridRenderTest::iterate(void)
800*35238bceSAndroid Build Coastguard Worker {
801*35238bceSAndroid Build Coastguard Worker     const int renderTargetWidth  = de::min(1024, m_context.getRenderTarget().getWidth());
802*35238bceSAndroid Build Coastguard Worker     const int renderTargetHeight = de::min(1024, m_context.getRenderTarget().getHeight());
803*35238bceSAndroid Build Coastguard Worker 
804*35238bceSAndroid Build Coastguard Worker     sglr::GLContext ctx(m_context.getRenderContext(), m_testCtx.getLog(),
805*35238bceSAndroid Build Coastguard Worker                         sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS,
806*35238bceSAndroid Build Coastguard Worker                         tcu::IVec4(0, 0, renderTargetWidth, renderTargetHeight));
807*35238bceSAndroid Build Coastguard Worker     tcu::Surface surface(renderTargetWidth, renderTargetHeight);
808*35238bceSAndroid Build Coastguard Worker     GridProgram program;
809*35238bceSAndroid Build Coastguard Worker 
810*35238bceSAndroid Build Coastguard Worker     // render
811*35238bceSAndroid Build Coastguard Worker 
812*35238bceSAndroid Build Coastguard Worker     renderTo(ctx, program, surface);
813*35238bceSAndroid Build Coastguard Worker 
814*35238bceSAndroid Build Coastguard Worker     // verify image
815*35238bceSAndroid Build Coastguard Worker     // \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
816*35238bceSAndroid Build Coastguard Worker     if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
817*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
818*35238bceSAndroid Build Coastguard Worker     else
819*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
820*35238bceSAndroid Build Coastguard Worker     return STOP;
821*35238bceSAndroid Build Coastguard Worker }
822*35238bceSAndroid Build Coastguard Worker 
renderTo(sglr::Context & ctx,sglr::ShaderProgram & program,tcu::Surface & dst)823*35238bceSAndroid Build Coastguard Worker void InstancedGridRenderTest::renderTo(sglr::Context &ctx, sglr::ShaderProgram &program, tcu::Surface &dst)
824*35238bceSAndroid Build Coastguard Worker {
825*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green(0, 1, 0, 1);
826*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow(1, 1, 0, 1);
827*35238bceSAndroid Build Coastguard Worker 
828*35238bceSAndroid Build Coastguard Worker     uint32_t vaoID           = 0;
829*35238bceSAndroid Build Coastguard Worker     uint32_t positionBuf     = 0;
830*35238bceSAndroid Build Coastguard Worker     uint32_t offsetBuf       = 0;
831*35238bceSAndroid Build Coastguard Worker     uint32_t colorBuf        = 0;
832*35238bceSAndroid Build Coastguard Worker     uint32_t indexBuf        = 0;
833*35238bceSAndroid Build Coastguard Worker     uint32_t drawIndirectBuf = 0;
834*35238bceSAndroid Build Coastguard Worker     uint32_t programID       = ctx.createProgram(&program);
835*35238bceSAndroid Build Coastguard Worker     int32_t posLocation      = ctx.getAttribLocation(programID, "a_position");
836*35238bceSAndroid Build Coastguard Worker     int32_t offsetLocation   = ctx.getAttribLocation(programID, "a_offset");
837*35238bceSAndroid Build Coastguard Worker     int32_t colorLocation    = ctx.getAttribLocation(programID, "a_color");
838*35238bceSAndroid Build Coastguard Worker 
839*35238bceSAndroid Build Coastguard Worker     float cellW                       = 2.0f / (float)m_gridSide;
840*35238bceSAndroid Build Coastguard Worker     float cellH                       = 2.0f / (float)m_gridSide;
841*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexPositions[] = {
842*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0, 0, 0, 1),     tcu::Vec4(cellW, 0, 0, 1), tcu::Vec4(0, cellH, 0, 1),
843*35238bceSAndroid Build Coastguard Worker 
844*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0, cellH, 0, 1), tcu::Vec4(cellW, 0, 0, 1), tcu::Vec4(cellW, cellH, 0, 1),
845*35238bceSAndroid Build Coastguard Worker     };
846*35238bceSAndroid Build Coastguard Worker 
847*35238bceSAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 4, 3, 2, 1, 5};
848*35238bceSAndroid Build Coastguard Worker 
849*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> offsets;
850*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < m_gridSide; ++x)
851*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < m_gridSide; ++y)
852*35238bceSAndroid Build Coastguard Worker             offsets.push_back(tcu::Vec4((float)x * cellW - 1.0f, (float)y * cellW - 1.0f, 0, 0));
853*35238bceSAndroid Build Coastguard Worker 
854*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::Vec4> colors;
855*35238bceSAndroid Build Coastguard Worker     for (int x = 0; x < m_gridSide; ++x)
856*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < m_gridSide; ++y)
857*35238bceSAndroid Build Coastguard Worker             colors.push_back(((x + y) % 2 == 0) ? (green) : (yellow));
858*35238bceSAndroid Build Coastguard Worker 
859*35238bceSAndroid Build Coastguard Worker     ctx.genVertexArrays(1, &vaoID);
860*35238bceSAndroid Build Coastguard Worker     ctx.bindVertexArray(vaoID);
861*35238bceSAndroid Build Coastguard Worker 
862*35238bceSAndroid Build Coastguard Worker     ctx.genBuffers(1, &positionBuf);
863*35238bceSAndroid Build Coastguard Worker     ctx.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
864*35238bceSAndroid Build Coastguard Worker     ctx.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
865*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
866*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribDivisor(posLocation, 0);
867*35238bceSAndroid Build Coastguard Worker     ctx.enableVertexAttribArray(posLocation);
868*35238bceSAndroid Build Coastguard Worker 
869*35238bceSAndroid Build Coastguard Worker     ctx.genBuffers(1, &offsetBuf);
870*35238bceSAndroid Build Coastguard Worker     ctx.bindBuffer(GL_ARRAY_BUFFER, offsetBuf);
871*35238bceSAndroid Build Coastguard Worker     ctx.bufferData(GL_ARRAY_BUFFER, offsets.size() * sizeof(tcu::Vec4), &offsets[0], GL_STATIC_DRAW);
872*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribPointer(offsetLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
873*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribDivisor(offsetLocation, 1);
874*35238bceSAndroid Build Coastguard Worker     ctx.enableVertexAttribArray(offsetLocation);
875*35238bceSAndroid Build Coastguard Worker 
876*35238bceSAndroid Build Coastguard Worker     ctx.genBuffers(1, &colorBuf);
877*35238bceSAndroid Build Coastguard Worker     ctx.bindBuffer(GL_ARRAY_BUFFER, colorBuf);
878*35238bceSAndroid Build Coastguard Worker     ctx.bufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(tcu::Vec4), &colors[0], GL_STATIC_DRAW);
879*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
880*35238bceSAndroid Build Coastguard Worker     ctx.vertexAttribDivisor(colorLocation, 1);
881*35238bceSAndroid Build Coastguard Worker     ctx.enableVertexAttribArray(colorLocation);
882*35238bceSAndroid Build Coastguard Worker 
883*35238bceSAndroid Build Coastguard Worker     if (m_useIndices)
884*35238bceSAndroid Build Coastguard Worker     {
885*35238bceSAndroid Build Coastguard Worker         ctx.genBuffers(1, &indexBuf);
886*35238bceSAndroid Build Coastguard Worker         ctx.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
887*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
888*35238bceSAndroid Build Coastguard Worker     }
889*35238bceSAndroid Build Coastguard Worker 
890*35238bceSAndroid Build Coastguard Worker     ctx.genBuffers(1, &drawIndirectBuf);
891*35238bceSAndroid Build Coastguard Worker     ctx.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);
892*35238bceSAndroid Build Coastguard Worker 
893*35238bceSAndroid Build Coastguard Worker     if (m_useIndices)
894*35238bceSAndroid Build Coastguard Worker     {
895*35238bceSAndroid Build Coastguard Worker         DrawElementsCommand command;
896*35238bceSAndroid Build Coastguard Worker         command.count              = 6;
897*35238bceSAndroid Build Coastguard Worker         command.primCount          = m_gridSide * m_gridSide;
898*35238bceSAndroid Build Coastguard Worker         command.firstIndex         = 0;
899*35238bceSAndroid Build Coastguard Worker         command.baseVertex         = 0;
900*35238bceSAndroid Build Coastguard Worker         command.reservedMustBeZero = 0;
901*35238bceSAndroid Build Coastguard Worker 
902*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
903*35238bceSAndroid Build Coastguard Worker     }
904*35238bceSAndroid Build Coastguard Worker     else
905*35238bceSAndroid Build Coastguard Worker     {
906*35238bceSAndroid Build Coastguard Worker         DrawArraysCommand command;
907*35238bceSAndroid Build Coastguard Worker         command.count              = 6;
908*35238bceSAndroid Build Coastguard Worker         command.primCount          = m_gridSide * m_gridSide;
909*35238bceSAndroid Build Coastguard Worker         command.first              = 0;
910*35238bceSAndroid Build Coastguard Worker         command.reservedMustBeZero = 0;
911*35238bceSAndroid Build Coastguard Worker 
912*35238bceSAndroid Build Coastguard Worker         ctx.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(command), &command, GL_STATIC_DRAW);
913*35238bceSAndroid Build Coastguard Worker     }
914*35238bceSAndroid Build Coastguard Worker 
915*35238bceSAndroid Build Coastguard Worker     ctx.clearColor(0, 0, 0, 1);
916*35238bceSAndroid Build Coastguard Worker     ctx.clear(GL_COLOR_BUFFER_BIT);
917*35238bceSAndroid Build Coastguard Worker 
918*35238bceSAndroid Build Coastguard Worker     ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
919*35238bceSAndroid Build Coastguard Worker 
920*35238bceSAndroid Build Coastguard Worker     ctx.useProgram(programID);
921*35238bceSAndroid Build Coastguard Worker     if (m_useIndices)
922*35238bceSAndroid Build Coastguard Worker         ctx.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, DE_NULL);
923*35238bceSAndroid Build Coastguard Worker     else
924*35238bceSAndroid Build Coastguard Worker         ctx.drawArraysIndirect(GL_TRIANGLES, DE_NULL);
925*35238bceSAndroid Build Coastguard Worker     ctx.useProgram(0);
926*35238bceSAndroid Build Coastguard Worker 
927*35238bceSAndroid Build Coastguard Worker     glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
928*35238bceSAndroid Build Coastguard Worker 
929*35238bceSAndroid Build Coastguard Worker     ctx.deleteBuffers(1, &drawIndirectBuf);
930*35238bceSAndroid Build Coastguard Worker     if (m_useIndices)
931*35238bceSAndroid Build Coastguard Worker         ctx.deleteBuffers(1, &indexBuf);
932*35238bceSAndroid Build Coastguard Worker     ctx.deleteBuffers(1, &colorBuf);
933*35238bceSAndroid Build Coastguard Worker     ctx.deleteBuffers(1, &offsetBuf);
934*35238bceSAndroid Build Coastguard Worker     ctx.deleteBuffers(1, &positionBuf);
935*35238bceSAndroid Build Coastguard Worker     ctx.deleteVertexArrays(1, &vaoID);
936*35238bceSAndroid Build Coastguard Worker     ctx.deleteProgram(programID);
937*35238bceSAndroid Build Coastguard Worker 
938*35238bceSAndroid Build Coastguard Worker     ctx.finish();
939*35238bceSAndroid Build Coastguard Worker     ctx.readPixels(dst, 0, 0, dst.getWidth(), dst.getHeight());
940*35238bceSAndroid Build Coastguard Worker 
941*35238bceSAndroid Build Coastguard Worker     glu::checkError(ctx.getError(), "", __FILE__, __LINE__);
942*35238bceSAndroid Build Coastguard Worker }
943*35238bceSAndroid Build Coastguard Worker 
944*35238bceSAndroid Build Coastguard Worker class InstancingGroup : public TestCaseGroup
945*35238bceSAndroid Build Coastguard Worker {
946*35238bceSAndroid Build Coastguard Worker public:
947*35238bceSAndroid Build Coastguard Worker     InstancingGroup(Context &context, const char *name, const char *descr);
948*35238bceSAndroid Build Coastguard Worker     ~InstancingGroup(void);
949*35238bceSAndroid Build Coastguard Worker 
950*35238bceSAndroid Build Coastguard Worker     void init(void);
951*35238bceSAndroid Build Coastguard Worker };
952*35238bceSAndroid Build Coastguard Worker 
InstancingGroup(Context & context,const char * name,const char * descr)953*35238bceSAndroid Build Coastguard Worker InstancingGroup::InstancingGroup(Context &context, const char *name, const char *descr)
954*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
955*35238bceSAndroid Build Coastguard Worker {
956*35238bceSAndroid Build Coastguard Worker }
957*35238bceSAndroid Build Coastguard Worker 
~InstancingGroup(void)958*35238bceSAndroid Build Coastguard Worker InstancingGroup::~InstancingGroup(void)
959*35238bceSAndroid Build Coastguard Worker {
960*35238bceSAndroid Build Coastguard Worker }
961*35238bceSAndroid Build Coastguard Worker 
init(void)962*35238bceSAndroid Build Coastguard Worker void InstancingGroup::init(void)
963*35238bceSAndroid Build Coastguard Worker {
964*35238bceSAndroid Build Coastguard Worker     const int gridWidths[] = {
965*35238bceSAndroid Build Coastguard Worker         2, 5, 10, 32, 100,
966*35238bceSAndroid Build Coastguard Worker     };
967*35238bceSAndroid Build Coastguard Worker 
968*35238bceSAndroid Build Coastguard Worker     // drawArrays
969*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
970*35238bceSAndroid Build Coastguard Worker     {
971*35238bceSAndroid Build Coastguard Worker         const std::string name = std::string("draw_arrays_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" +
972*35238bceSAndroid Build Coastguard Worker                                  de::toString(gridWidths[ndx]);
973*35238bceSAndroid Build Coastguard Worker         const std::string desc = std::string("DrawArraysIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" +
974*35238bceSAndroid Build Coastguard Worker                                  de::toString(gridWidths[ndx]);
975*35238bceSAndroid Build Coastguard Worker 
976*35238bceSAndroid Build Coastguard Worker         this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], false));
977*35238bceSAndroid Build Coastguard Worker     }
978*35238bceSAndroid Build Coastguard Worker 
979*35238bceSAndroid Build Coastguard Worker     // drawElements
980*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(gridWidths); ++ndx)
981*35238bceSAndroid Build Coastguard Worker     {
982*35238bceSAndroid Build Coastguard Worker         const std::string name = std::string("draw_elements_indirect_grid_") + de::toString(gridWidths[ndx]) + "x" +
983*35238bceSAndroid Build Coastguard Worker                                  de::toString(gridWidths[ndx]);
984*35238bceSAndroid Build Coastguard Worker         const std::string desc = std::string("DrawElementsIndirect, Grid size ") + de::toString(gridWidths[ndx]) + "x" +
985*35238bceSAndroid Build Coastguard Worker                                  de::toString(gridWidths[ndx]);
986*35238bceSAndroid Build Coastguard Worker 
987*35238bceSAndroid Build Coastguard Worker         this->addChild(new InstancedGridRenderTest(m_context, name.c_str(), desc.c_str(), gridWidths[ndx], true));
988*35238bceSAndroid Build Coastguard Worker     }
989*35238bceSAndroid Build Coastguard Worker }
990*35238bceSAndroid Build Coastguard Worker 
991*35238bceSAndroid Build Coastguard Worker class ComputeShaderGeneratedCase : public TestCase
992*35238bceSAndroid Build Coastguard Worker {
993*35238bceSAndroid Build Coastguard Worker public:
994*35238bceSAndroid Build Coastguard Worker     enum DrawMethod
995*35238bceSAndroid Build Coastguard Worker     {
996*35238bceSAndroid Build Coastguard Worker         DRAWMETHOD_DRAWARRAYS,
997*35238bceSAndroid Build Coastguard Worker         DRAWMETHOD_DRAWELEMENTS,
998*35238bceSAndroid Build Coastguard Worker         DRAWMETHOD_LAST
999*35238bceSAndroid Build Coastguard Worker     };
1000*35238bceSAndroid Build Coastguard Worker 
1001*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCase(Context &context, const char *name, const char *desc, DrawMethod method, bool computeCmd,
1002*35238bceSAndroid Build Coastguard Worker                                bool computeData, bool computeIndices, int gridSize, int drawCallCount);
1003*35238bceSAndroid Build Coastguard Worker     ~ComputeShaderGeneratedCase(void);
1004*35238bceSAndroid Build Coastguard Worker     void init(void);
1005*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1008*35238bceSAndroid Build Coastguard Worker     std::string genComputeSource(bool computeCmd, bool computeData, bool computeIndices) const;
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker private:
1011*35238bceSAndroid Build Coastguard Worker     void createDrawCommand(void);
1012*35238bceSAndroid Build Coastguard Worker     void createDrawData(void);
1013*35238bceSAndroid Build Coastguard Worker     void createDrawIndices(void);
1014*35238bceSAndroid Build Coastguard Worker 
1015*35238bceSAndroid Build Coastguard Worker     virtual void runComputeShader(void) = 0;
1016*35238bceSAndroid Build Coastguard Worker     void renderTo(tcu::Surface &image);
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker protected:
1019*35238bceSAndroid Build Coastguard Worker     uint32_t calcDrawBufferSize(void) const;
1020*35238bceSAndroid Build Coastguard Worker     uint32_t calcIndexBufferSize(void) const;
1021*35238bceSAndroid Build Coastguard Worker 
1022*35238bceSAndroid Build Coastguard Worker     const DrawMethod m_drawMethod;
1023*35238bceSAndroid Build Coastguard Worker     const bool m_computeCmd;
1024*35238bceSAndroid Build Coastguard Worker     const bool m_computeData;
1025*35238bceSAndroid Build Coastguard Worker     const bool m_computeIndices;
1026*35238bceSAndroid Build Coastguard Worker     const int m_commandSize;
1027*35238bceSAndroid Build Coastguard Worker     const int m_numDrawCmds;
1028*35238bceSAndroid Build Coastguard Worker     const int m_gridSize;
1029*35238bceSAndroid Build Coastguard Worker 
1030*35238bceSAndroid Build Coastguard Worker     glw::GLuint m_cmdBufferID;
1031*35238bceSAndroid Build Coastguard Worker     glw::GLuint m_dataBufferID;
1032*35238bceSAndroid Build Coastguard Worker     glw::GLuint m_indexBufferID;
1033*35238bceSAndroid Build Coastguard Worker 
1034*35238bceSAndroid Build Coastguard Worker private:
1035*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_shaderProgram;
1036*35238bceSAndroid Build Coastguard Worker };
1037*35238bceSAndroid Build Coastguard Worker 
ComputeShaderGeneratedCase(Context & context,const char * name,const char * desc,DrawMethod method,bool computeCmd,bool computeData,bool computeIndices,int gridSize,int drawCallCount)1038*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedCase::ComputeShaderGeneratedCase(Context &context, const char *name, const char *desc,
1039*35238bceSAndroid Build Coastguard Worker                                                        DrawMethod method, bool computeCmd, bool computeData,
1040*35238bceSAndroid Build Coastguard Worker                                                        bool computeIndices, int gridSize, int drawCallCount)
1041*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
1042*35238bceSAndroid Build Coastguard Worker     , m_drawMethod(method)
1043*35238bceSAndroid Build Coastguard Worker     , m_computeCmd(computeCmd)
1044*35238bceSAndroid Build Coastguard Worker     , m_computeData(computeData)
1045*35238bceSAndroid Build Coastguard Worker     , m_computeIndices(computeIndices)
1046*35238bceSAndroid Build Coastguard Worker     , m_commandSize((method == DRAWMETHOD_DRAWARRAYS) ? ((int)sizeof(DrawArraysCommand)) :
1047*35238bceSAndroid Build Coastguard Worker                                                         ((int)sizeof(DrawElementsCommand)))
1048*35238bceSAndroid Build Coastguard Worker     , m_numDrawCmds(drawCallCount)
1049*35238bceSAndroid Build Coastguard Worker     , m_gridSize(gridSize)
1050*35238bceSAndroid Build Coastguard Worker     , m_cmdBufferID(0)
1051*35238bceSAndroid Build Coastguard Worker     , m_dataBufferID(0)
1052*35238bceSAndroid Build Coastguard Worker     , m_indexBufferID(0)
1053*35238bceSAndroid Build Coastguard Worker     , m_shaderProgram(DE_NULL)
1054*35238bceSAndroid Build Coastguard Worker {
1055*35238bceSAndroid Build Coastguard Worker     const int triangleCount = m_gridSize * m_gridSize * 2;
1056*35238bceSAndroid Build Coastguard Worker 
1057*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(method < DRAWMETHOD_LAST);
1058*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!computeIndices || method == DRAWMETHOD_DRAWELEMENTS);
1059*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(triangleCount % m_numDrawCmds == 0);
1060*35238bceSAndroid Build Coastguard Worker     DE_UNREF(triangleCount);
1061*35238bceSAndroid Build Coastguard Worker }
1062*35238bceSAndroid Build Coastguard Worker 
~ComputeShaderGeneratedCase(void)1063*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedCase::~ComputeShaderGeneratedCase(void)
1064*35238bceSAndroid Build Coastguard Worker {
1065*35238bceSAndroid Build Coastguard Worker     deinit();
1066*35238bceSAndroid Build Coastguard Worker }
1067*35238bceSAndroid Build Coastguard Worker 
init(void)1068*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::init(void)
1069*35238bceSAndroid Build Coastguard Worker {
1070*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1071*35238bceSAndroid Build Coastguard Worker 
1072*35238bceSAndroid Build Coastguard Worker     // generate basic shader
1073*35238bceSAndroid Build Coastguard Worker 
1074*35238bceSAndroid Build Coastguard Worker     m_shaderProgram = new glu::ShaderProgram(m_context.getRenderContext(),
1075*35238bceSAndroid Build Coastguard Worker                                              glu::ProgramSources() << glu::VertexSource(s_colorVertexShaderSource)
1076*35238bceSAndroid Build Coastguard Worker                                                                    << glu::FragmentSource(s_colorFragmentShaderSource));
1077*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_shaderProgram;
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker     if (!m_shaderProgram->isOk())
1080*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Failed to compile shader.");
1081*35238bceSAndroid Build Coastguard Worker 
1082*35238bceSAndroid Build Coastguard Worker     // gen buffers
1083*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_cmdBufferID);
1084*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_dataBufferID);
1085*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &m_indexBufferID);
1086*35238bceSAndroid Build Coastguard Worker 
1087*35238bceSAndroid Build Coastguard Worker     // check the SSBO buffers are of legal size
1088*35238bceSAndroid Build Coastguard Worker     {
1089*35238bceSAndroid Build Coastguard Worker         const uint64_t drawBufferElementSize  = sizeof(tcu::Vec4);
1090*35238bceSAndroid Build Coastguard Worker         const uint64_t indexBufferElementSize = sizeof(uint32_t);
1091*35238bceSAndroid Build Coastguard Worker         const int commandBufferSize           = m_commandSize * m_numDrawCmds;
1092*35238bceSAndroid Build Coastguard Worker         int64_t maxSSBOSize                   = 0;
1093*35238bceSAndroid Build Coastguard Worker 
1094*35238bceSAndroid Build Coastguard Worker         gl.getInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &maxSSBOSize);
1095*35238bceSAndroid Build Coastguard Worker 
1096*35238bceSAndroid Build Coastguard Worker         if (m_computeData && (uint64_t)calcDrawBufferSize() * drawBufferElementSize > (uint64_t)maxSSBOSize)
1097*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for vertex attrib buffers");
1098*35238bceSAndroid Build Coastguard Worker         if (m_computeIndices && (uint64_t)calcIndexBufferSize() * indexBufferElementSize > (uint64_t)maxSSBOSize)
1099*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for index buffers");
1100*35238bceSAndroid Build Coastguard Worker         if (m_computeCmd && (uint64_t)commandBufferSize > (uint64_t)maxSSBOSize)
1101*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("GL_MAX_SHADER_STORAGE_BLOCK_SIZE is too small for command buffers");
1102*35238bceSAndroid Build Coastguard Worker     }
1103*35238bceSAndroid Build Coastguard Worker }
1104*35238bceSAndroid Build Coastguard Worker 
deinit(void)1105*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::deinit(void)
1106*35238bceSAndroid Build Coastguard Worker {
1107*35238bceSAndroid Build Coastguard Worker     if (m_cmdBufferID)
1108*35238bceSAndroid Build Coastguard Worker     {
1109*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_cmdBufferID);
1110*35238bceSAndroid Build Coastguard Worker         m_cmdBufferID = 0;
1111*35238bceSAndroid Build Coastguard Worker     }
1112*35238bceSAndroid Build Coastguard Worker     if (m_dataBufferID)
1113*35238bceSAndroid Build Coastguard Worker     {
1114*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dataBufferID);
1115*35238bceSAndroid Build Coastguard Worker         m_dataBufferID = 0;
1116*35238bceSAndroid Build Coastguard Worker     }
1117*35238bceSAndroid Build Coastguard Worker     if (m_indexBufferID)
1118*35238bceSAndroid Build Coastguard Worker     {
1119*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBufferID);
1120*35238bceSAndroid Build Coastguard Worker         m_indexBufferID = 0;
1121*35238bceSAndroid Build Coastguard Worker     }
1122*35238bceSAndroid Build Coastguard Worker 
1123*35238bceSAndroid Build Coastguard Worker     if (m_shaderProgram)
1124*35238bceSAndroid Build Coastguard Worker     {
1125*35238bceSAndroid Build Coastguard Worker         delete m_shaderProgram;
1126*35238bceSAndroid Build Coastguard Worker         m_shaderProgram = DE_NULL;
1127*35238bceSAndroid Build Coastguard Worker     }
1128*35238bceSAndroid Build Coastguard Worker }
1129*35238bceSAndroid Build Coastguard Worker 
iterate(void)1130*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedCase::IterateResult ComputeShaderGeneratedCase::iterate(void)
1131*35238bceSAndroid Build Coastguard Worker {
1132*35238bceSAndroid Build Coastguard Worker     const int renderTargetWidth  = de::min(1024, m_context.getRenderTarget().getWidth());
1133*35238bceSAndroid Build Coastguard Worker     const int renderTargetHeight = de::min(1024, m_context.getRenderTarget().getHeight());
1134*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl     = m_context.getRenderContext().getFunctions();
1135*35238bceSAndroid Build Coastguard Worker     tcu::Surface surface(renderTargetWidth, renderTargetHeight);
1136*35238bceSAndroid Build Coastguard Worker 
1137*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Preparing to draw " << m_gridSize << " x " << m_gridSize << " grid."
1138*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1139*35238bceSAndroid Build Coastguard Worker 
1140*35238bceSAndroid Build Coastguard Worker     try
1141*35238bceSAndroid Build Coastguard Worker     {
1142*35238bceSAndroid Build Coastguard Worker         // Gen command buffer
1143*35238bceSAndroid Build Coastguard Worker         if (!m_computeCmd)
1144*35238bceSAndroid Build Coastguard Worker         {
1145*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw command buffer." << tcu::TestLog::EndMessage;
1146*35238bceSAndroid Build Coastguard Worker             createDrawCommand();
1147*35238bceSAndroid Build Coastguard Worker         }
1148*35238bceSAndroid Build Coastguard Worker 
1149*35238bceSAndroid Build Coastguard Worker         // Gen data buffer
1150*35238bceSAndroid Build Coastguard Worker         if (!m_computeData)
1151*35238bceSAndroid Build Coastguard Worker         {
1152*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw data buffer." << tcu::TestLog::EndMessage;
1153*35238bceSAndroid Build Coastguard Worker             createDrawData();
1154*35238bceSAndroid Build Coastguard Worker         }
1155*35238bceSAndroid Build Coastguard Worker 
1156*35238bceSAndroid Build Coastguard Worker         // Gen index buffer
1157*35238bceSAndroid Build Coastguard Worker         if (!m_computeIndices && m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1158*35238bceSAndroid Build Coastguard Worker         {
1159*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Uploading draw index buffer." << tcu::TestLog::EndMessage;
1160*35238bceSAndroid Build Coastguard Worker             createDrawIndices();
1161*35238bceSAndroid Build Coastguard Worker         }
1162*35238bceSAndroid Build Coastguard Worker 
1163*35238bceSAndroid Build Coastguard Worker         // Run compute shader
1164*35238bceSAndroid Build Coastguard Worker         {
1165*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message << "Filling following buffers using compute shader:\n"
1166*35238bceSAndroid Build Coastguard Worker                                << ((m_computeCmd) ? ("\tcommand buffer\n") : (""))
1167*35238bceSAndroid Build Coastguard Worker                                << ((m_computeData) ? ("\tdata buffer\n") : (""))
1168*35238bceSAndroid Build Coastguard Worker                                << ((m_computeIndices) ? ("\tindex buffer\n") : ("")) << tcu::TestLog::EndMessage;
1169*35238bceSAndroid Build Coastguard Worker             runComputeShader();
1170*35238bceSAndroid Build Coastguard Worker         }
1171*35238bceSAndroid Build Coastguard Worker 
1172*35238bceSAndroid Build Coastguard Worker         // Ensure data is written to the buffers before we try to read it
1173*35238bceSAndroid Build Coastguard Worker         {
1174*35238bceSAndroid Build Coastguard Worker             const glw::GLuint barriers = ((m_computeCmd) ? (GL_COMMAND_BARRIER_BIT) : (0)) |
1175*35238bceSAndroid Build Coastguard Worker                                          ((m_computeData) ? (GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) : (0)) |
1176*35238bceSAndroid Build Coastguard Worker                                          ((m_computeIndices) ? (GL_ELEMENT_ARRAY_BARRIER_BIT) : (0));
1177*35238bceSAndroid Build Coastguard Worker 
1178*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << tcu::TestLog::Message
1179*35238bceSAndroid Build Coastguard Worker                                << "Memory barrier. Barriers = " << glu::getMemoryBarrierFlagsStr(barriers)
1180*35238bceSAndroid Build Coastguard Worker                                << tcu::TestLog::EndMessage;
1181*35238bceSAndroid Build Coastguard Worker             gl.memoryBarrier(barriers);
1182*35238bceSAndroid Build Coastguard Worker         }
1183*35238bceSAndroid Build Coastguard Worker 
1184*35238bceSAndroid Build Coastguard Worker         // Draw from buffers
1185*35238bceSAndroid Build Coastguard Worker 
1186*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Drawing from buffers with " << m_numDrawCmds << " draw call(s)."
1187*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1188*35238bceSAndroid Build Coastguard Worker         renderTo(surface);
1189*35238bceSAndroid Build Coastguard Worker     }
1190*35238bceSAndroid Build Coastguard Worker     catch (glu::OutOfMemoryError &)
1191*35238bceSAndroid Build Coastguard Worker     {
1192*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Got GL_OUT_OF_MEMORY." << tcu::TestLog::EndMessage;
1193*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Got GL_OUT_OF_MEMORY");
1194*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTerminateAfter(true); // Do not rely on implementation to be able to recover from OOM
1195*35238bceSAndroid Build Coastguard Worker         return STOP;
1196*35238bceSAndroid Build Coastguard Worker     }
1197*35238bceSAndroid Build Coastguard Worker 
1198*35238bceSAndroid Build Coastguard Worker     // verify image
1199*35238bceSAndroid Build Coastguard Worker     // \note the green/yellow pattern is only for clarity. The test will only verify that all grid cells were drawn by looking for anything non-green/yellow.
1200*35238bceSAndroid Build Coastguard Worker     if (verifyImageYellowGreen(surface, m_testCtx.getLog()))
1201*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1202*35238bceSAndroid Build Coastguard Worker     else
1203*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
1204*35238bceSAndroid Build Coastguard Worker     return STOP;
1205*35238bceSAndroid Build Coastguard Worker }
1206*35238bceSAndroid Build Coastguard Worker 
genComputeSource(bool computeCmd,bool computeData,bool computeIndices) const1207*35238bceSAndroid Build Coastguard Worker std::string ComputeShaderGeneratedCase::genComputeSource(bool computeCmd, bool computeData, bool computeIndices) const
1208*35238bceSAndroid Build Coastguard Worker {
1209*35238bceSAndroid Build Coastguard Worker     const int cmdLayoutBinding   = 0;
1210*35238bceSAndroid Build Coastguard Worker     const int dataLayoutBinding  = (computeCmd) ? (1) : (0);
1211*35238bceSAndroid Build Coastguard Worker     const int indexLayoutBinding = (computeCmd && computeData) ? (2) : (computeCmd || computeData) ? (1) : (0);
1212*35238bceSAndroid Build Coastguard Worker 
1213*35238bceSAndroid Build Coastguard Worker     std::ostringstream buf;
1214*35238bceSAndroid Build Coastguard Worker 
1215*35238bceSAndroid Build Coastguard Worker     buf << "#version 310 es\n\n"
1216*35238bceSAndroid Build Coastguard Worker         << "precision highp int;\n"
1217*35238bceSAndroid Build Coastguard Worker         << "precision highp float;\n\n";
1218*35238bceSAndroid Build Coastguard Worker 
1219*35238bceSAndroid Build Coastguard Worker     if (computeCmd && m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1220*35238bceSAndroid Build Coastguard Worker         buf << "struct DrawArraysIndirectCommand {\n"
1221*35238bceSAndroid Build Coastguard Worker             << "    uint count;\n"
1222*35238bceSAndroid Build Coastguard Worker             << "    uint primCount;\n"
1223*35238bceSAndroid Build Coastguard Worker             << "    uint first;\n"
1224*35238bceSAndroid Build Coastguard Worker             << "    uint reservedMustBeZero;\n"
1225*35238bceSAndroid Build Coastguard Worker             << "};\n\n";
1226*35238bceSAndroid Build Coastguard Worker     else if (computeCmd && m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1227*35238bceSAndroid Build Coastguard Worker         buf << "struct DrawElementsIndirectCommand {\n"
1228*35238bceSAndroid Build Coastguard Worker             << "    uint count;\n"
1229*35238bceSAndroid Build Coastguard Worker             << "    uint primCount;\n"
1230*35238bceSAndroid Build Coastguard Worker             << "    uint firstIndex;\n"
1231*35238bceSAndroid Build Coastguard Worker             << "    int  baseVertex;\n"
1232*35238bceSAndroid Build Coastguard Worker             << "    uint reservedMustBeZero;\n"
1233*35238bceSAndroid Build Coastguard Worker             << "};\n\n";
1234*35238bceSAndroid Build Coastguard Worker 
1235*35238bceSAndroid Build Coastguard Worker     buf << "layout(local_size_x = 1, local_size_y = 1) in;\n"
1236*35238bceSAndroid Build Coastguard Worker         << "layout(std430) buffer;\n\n";
1237*35238bceSAndroid Build Coastguard Worker 
1238*35238bceSAndroid Build Coastguard Worker     if (computeCmd)
1239*35238bceSAndroid Build Coastguard Worker         buf << "layout(binding = " << cmdLayoutBinding << ") writeonly buffer CommandBuffer {\n"
1240*35238bceSAndroid Build Coastguard Worker             << "    "
1241*35238bceSAndroid Build Coastguard Worker             << ((m_drawMethod == DRAWMETHOD_DRAWARRAYS) ? ("DrawArraysIndirectCommand") :
1242*35238bceSAndroid Build Coastguard Worker                                                           ("DrawElementsIndirectCommand"))
1243*35238bceSAndroid Build Coastguard Worker             << " commands[];\n"
1244*35238bceSAndroid Build Coastguard Worker             << "};\n";
1245*35238bceSAndroid Build Coastguard Worker     if (computeData)
1246*35238bceSAndroid Build Coastguard Worker         buf << "layout(binding = " << dataLayoutBinding << ") writeonly buffer DataBuffer {\n"
1247*35238bceSAndroid Build Coastguard Worker             << "    vec4 attribs[];\n"
1248*35238bceSAndroid Build Coastguard Worker             << "};\n";
1249*35238bceSAndroid Build Coastguard Worker     if (computeIndices)
1250*35238bceSAndroid Build Coastguard Worker         buf << "layout(binding = " << indexLayoutBinding << ") writeonly buffer IndexBuffer {\n"
1251*35238bceSAndroid Build Coastguard Worker             << "    uint indices[];\n"
1252*35238bceSAndroid Build Coastguard Worker             << "};\n";
1253*35238bceSAndroid Build Coastguard Worker 
1254*35238bceSAndroid Build Coastguard Worker     buf << "\n"
1255*35238bceSAndroid Build Coastguard Worker         << "void main() {\n"
1256*35238bceSAndroid Build Coastguard Worker         << "    const uint gridSize      = " << m_gridSize << "u;\n"
1257*35238bceSAndroid Build Coastguard Worker         << "    const uint triangleCount = gridSize * gridSize * 2u;\n"
1258*35238bceSAndroid Build Coastguard Worker         << "\n";
1259*35238bceSAndroid Build Coastguard Worker 
1260*35238bceSAndroid Build Coastguard Worker     if (computeCmd)
1261*35238bceSAndroid Build Coastguard Worker     {
1262*35238bceSAndroid Build Coastguard Worker         buf << "    // command\n"
1263*35238bceSAndroid Build Coastguard Worker             << "    if (gl_GlobalInvocationID.x < " << m_numDrawCmds
1264*35238bceSAndroid Build Coastguard Worker             << "u && gl_GlobalInvocationID.y == 0u && gl_GlobalInvocationID.z == 0u) {\n"
1265*35238bceSAndroid Build Coastguard Worker             << "        const uint numDrawCallTris = triangleCount / " << m_numDrawCmds << "u;\n"
1266*35238bceSAndroid Build Coastguard Worker             << "        uint firstTri              = gl_GlobalInvocationID.x * numDrawCallTris;\n\n"
1267*35238bceSAndroid Build Coastguard Worker             << "        commands[gl_GlobalInvocationID.x].count                 = numDrawCallTris*3u;\n"
1268*35238bceSAndroid Build Coastguard Worker             << "        commands[gl_GlobalInvocationID.x].primCount             = 1u;\n";
1269*35238bceSAndroid Build Coastguard Worker 
1270*35238bceSAndroid Build Coastguard Worker         if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1271*35238bceSAndroid Build Coastguard Worker         {
1272*35238bceSAndroid Build Coastguard Worker             buf << "        commands[gl_GlobalInvocationID.x].first                 = firstTri*3u;\n";
1273*35238bceSAndroid Build Coastguard Worker         }
1274*35238bceSAndroid Build Coastguard Worker         else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1275*35238bceSAndroid Build Coastguard Worker         {
1276*35238bceSAndroid Build Coastguard Worker             buf << "        commands[gl_GlobalInvocationID.x].firstIndex            = firstTri*3u;\n";
1277*35238bceSAndroid Build Coastguard Worker             buf << "        commands[gl_GlobalInvocationID.x].baseVertex            = 0;\n";
1278*35238bceSAndroid Build Coastguard Worker         }
1279*35238bceSAndroid Build Coastguard Worker 
1280*35238bceSAndroid Build Coastguard Worker         buf << "        commands[gl_GlobalInvocationID.x].reservedMustBeZero    = 0u;\n"
1281*35238bceSAndroid Build Coastguard Worker             << "    }\n"
1282*35238bceSAndroid Build Coastguard Worker             << "\n";
1283*35238bceSAndroid Build Coastguard Worker     }
1284*35238bceSAndroid Build Coastguard Worker 
1285*35238bceSAndroid Build Coastguard Worker     if (computeData)
1286*35238bceSAndroid Build Coastguard Worker     {
1287*35238bceSAndroid Build Coastguard Worker         buf << "    // vertex attribs\n"
1288*35238bceSAndroid Build Coastguard Worker             << "    const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
1289*35238bceSAndroid Build Coastguard Worker             << "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n";
1290*35238bceSAndroid Build Coastguard Worker 
1291*35238bceSAndroid Build Coastguard Worker         if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1292*35238bceSAndroid Build Coastguard Worker         {
1293*35238bceSAndroid Build Coastguard Worker             buf << "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && "
1294*35238bceSAndroid Build Coastguard Worker                    "gl_GlobalInvocationID.z == 0u) {\n"
1295*35238bceSAndroid Build Coastguard Worker                 << "        uint        y           = gl_GlobalInvocationID.x;\n"
1296*35238bceSAndroid Build Coastguard Worker                 << "        uint        x           = gl_GlobalInvocationID.y;\n"
1297*35238bceSAndroid Build Coastguard Worker                 << "        float       posX        = (float(x)    / float(gridSize)) * 2.0 - 1.0;\n"
1298*35238bceSAndroid Build Coastguard Worker                 << "        float       posXp1      = (float(x+1u) / float(gridSize)) * 2.0 - 1.0;\n"
1299*35238bceSAndroid Build Coastguard Worker                 << "        float       posY        = (float(y)    / float(gridSize)) * 2.0 - 1.0;\n"
1300*35238bceSAndroid Build Coastguard Worker                 << "        float       posYp1      = (float(y+1u) / float(gridSize)) * 2.0 - 1.0;\n"
1301*35238bceSAndroid Build Coastguard Worker                 << "        vec4        color       = ((x + y)%2u != 0u) ? (yellow) : (green);\n"
1302*35238bceSAndroid Build Coastguard Worker                 << "\n"
1303*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 0u] = vec4(posX,   posY,   0.0, 1.0);\n"
1304*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 0u] = vec4(posXp1, posY,   0.0, 1.0);\n"
1305*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 0u] = vec4(posXp1, posYp1, 0.0, 1.0);\n"
1306*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 0u] = vec4(posX,   posY,   0.0, 1.0);\n"
1307*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 0u] = vec4(posXp1, posYp1, 0.0, 1.0);\n"
1308*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 0u] = vec4(posX,   posYp1, 0.0, 1.0);\n"
1309*35238bceSAndroid Build Coastguard Worker                 << "\n"
1310*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 0u) * 2u + 1u] = color;\n"
1311*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 1u) * 2u + 1u] = color;\n"
1312*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 2u) * 2u + 1u] = color;\n"
1313*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 3u) * 2u + 1u] = color;\n"
1314*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 4u) * 2u + 1u] = color;\n"
1315*35238bceSAndroid Build Coastguard Worker                 << "        attribs[((y * gridSize + x) * 6u + 5u) * 2u + 1u] = color;\n"
1316*35238bceSAndroid Build Coastguard Worker                 << "    }\n";
1317*35238bceSAndroid Build Coastguard Worker         }
1318*35238bceSAndroid Build Coastguard Worker         else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1319*35238bceSAndroid Build Coastguard Worker         {
1320*35238bceSAndroid Build Coastguard Worker             buf << "    if (gl_GlobalInvocationID.x < gridSize+1u && gl_GlobalInvocationID.y < gridSize+1u && "
1321*35238bceSAndroid Build Coastguard Worker                    "gl_GlobalInvocationID.z == 0u) {\n"
1322*35238bceSAndroid Build Coastguard Worker                 << "        uint        y           = gl_GlobalInvocationID.x;\n"
1323*35238bceSAndroid Build Coastguard Worker                 << "        uint        x           = gl_GlobalInvocationID.y;\n"
1324*35238bceSAndroid Build Coastguard Worker                 << "        float       posX        = (float(x) / float(gridSize)) * 2.0 - 1.0;\n"
1325*35238bceSAndroid Build Coastguard Worker                 << "        float       posY        = (float(y) / float(gridSize)) * 2.0 - 1.0;\n"
1326*35238bceSAndroid Build Coastguard Worker                 << "\n"
1327*35238bceSAndroid Build Coastguard Worker                 << "        attribs[(y * (gridSize+1u) + x) * 4u + 0u] = vec4(posX, posY, 0.0, 1.0);\n"
1328*35238bceSAndroid Build Coastguard Worker                 << "        attribs[(y * (gridSize+1u) + x) * 4u + 1u] = green;\n"
1329*35238bceSAndroid Build Coastguard Worker                 << "        attribs[(y * (gridSize+1u) + x) * 4u + 2u] = vec4(posX, posY, 0.0, 1.0);\n"
1330*35238bceSAndroid Build Coastguard Worker                 << "        attribs[(y * (gridSize+1u) + x) * 4u + 3u] = yellow;\n"
1331*35238bceSAndroid Build Coastguard Worker                 << "    }\n";
1332*35238bceSAndroid Build Coastguard Worker         }
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker         buf << "\n";
1335*35238bceSAndroid Build Coastguard Worker     }
1336*35238bceSAndroid Build Coastguard Worker 
1337*35238bceSAndroid Build Coastguard Worker     if (computeIndices)
1338*35238bceSAndroid Build Coastguard Worker     {
1339*35238bceSAndroid Build Coastguard Worker         buf << "    // indices\n"
1340*35238bceSAndroid Build Coastguard Worker             << "    if (gl_GlobalInvocationID.x < gridSize && gl_GlobalInvocationID.y < gridSize && "
1341*35238bceSAndroid Build Coastguard Worker                "gl_GlobalInvocationID.z == 0u) {\n"
1342*35238bceSAndroid Build Coastguard Worker             << "        uint    y       = gl_GlobalInvocationID.x;\n"
1343*35238bceSAndroid Build Coastguard Worker             << "        uint    x       = gl_GlobalInvocationID.y;\n"
1344*35238bceSAndroid Build Coastguard Worker             << "        uint    color   = ((x + y)%2u);\n"
1345*35238bceSAndroid Build Coastguard Worker             << "\n"
1346*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 0u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
1347*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 1u] = ((y+1u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
1348*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 2u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
1349*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 3u] = ((y+0u) * (gridSize+1u) + (x+0u)) * 2u + color;\n"
1350*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 4u] = ((y+1u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
1351*35238bceSAndroid Build Coastguard Worker             << "        indices[(y * gridSize + x) * 6u + 5u] = ((y+0u) * (gridSize+1u) + (x+1u)) * 2u + color;\n"
1352*35238bceSAndroid Build Coastguard Worker             << "    }\n"
1353*35238bceSAndroid Build Coastguard Worker             << "\n";
1354*35238bceSAndroid Build Coastguard Worker     }
1355*35238bceSAndroid Build Coastguard Worker 
1356*35238bceSAndroid Build Coastguard Worker     buf << "}\n";
1357*35238bceSAndroid Build Coastguard Worker 
1358*35238bceSAndroid Build Coastguard Worker     return buf.str();
1359*35238bceSAndroid Build Coastguard Worker }
1360*35238bceSAndroid Build Coastguard Worker 
createDrawCommand(void)1361*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::createDrawCommand(void)
1362*35238bceSAndroid Build Coastguard Worker {
1363*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl       = m_context.getRenderContext().getFunctions();
1364*35238bceSAndroid Build Coastguard Worker     const int triangleCount        = m_gridSize * m_gridSize * 2;
1365*35238bceSAndroid Build Coastguard Worker     const uint32_t numDrawCallTris = triangleCount / m_numDrawCmds;
1366*35238bceSAndroid Build Coastguard Worker 
1367*35238bceSAndroid Build Coastguard Worker     if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1368*35238bceSAndroid Build Coastguard Worker     {
1369*35238bceSAndroid Build Coastguard Worker         std::vector<DrawArraysCommand> cmds;
1370*35238bceSAndroid Build Coastguard Worker 
1371*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
1372*35238bceSAndroid Build Coastguard Worker         {
1373*35238bceSAndroid Build Coastguard Worker             const uint32_t firstTri = ndx * numDrawCallTris;
1374*35238bceSAndroid Build Coastguard Worker             DrawArraysCommand data;
1375*35238bceSAndroid Build Coastguard Worker 
1376*35238bceSAndroid Build Coastguard Worker             data.count              = numDrawCallTris * 3;
1377*35238bceSAndroid Build Coastguard Worker             data.primCount          = 1;
1378*35238bceSAndroid Build Coastguard Worker             data.first              = firstTri * 3;
1379*35238bceSAndroid Build Coastguard Worker             data.reservedMustBeZero = 0;
1380*35238bceSAndroid Build Coastguard Worker 
1381*35238bceSAndroid Build Coastguard Worker             cmds.push_back(data);
1382*35238bceSAndroid Build Coastguard Worker         }
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker         DE_ASSERT((int)(sizeof(DrawArraysCommand) * cmds.size()) == m_numDrawCmds * m_commandSize);
1385*35238bceSAndroid Build Coastguard Worker 
1386*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
1387*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawArraysCommand) * cmds.size()), &cmds[0],
1388*35238bceSAndroid Build Coastguard Worker                       GL_STATIC_DRAW);
1389*35238bceSAndroid Build Coastguard Worker     }
1390*35238bceSAndroid Build Coastguard Worker     else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1391*35238bceSAndroid Build Coastguard Worker     {
1392*35238bceSAndroid Build Coastguard Worker         std::vector<DrawElementsCommand> cmds;
1393*35238bceSAndroid Build Coastguard Worker 
1394*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < m_numDrawCmds; ++ndx)
1395*35238bceSAndroid Build Coastguard Worker         {
1396*35238bceSAndroid Build Coastguard Worker             const uint32_t firstTri = ndx * numDrawCallTris;
1397*35238bceSAndroid Build Coastguard Worker             DrawElementsCommand data;
1398*35238bceSAndroid Build Coastguard Worker 
1399*35238bceSAndroid Build Coastguard Worker             data.count              = numDrawCallTris * 3;
1400*35238bceSAndroid Build Coastguard Worker             data.primCount          = 1;
1401*35238bceSAndroid Build Coastguard Worker             data.firstIndex         = firstTri * 3;
1402*35238bceSAndroid Build Coastguard Worker             data.baseVertex         = 0;
1403*35238bceSAndroid Build Coastguard Worker             data.reservedMustBeZero = 0;
1404*35238bceSAndroid Build Coastguard Worker 
1405*35238bceSAndroid Build Coastguard Worker             cmds.push_back(data);
1406*35238bceSAndroid Build Coastguard Worker         }
1407*35238bceSAndroid Build Coastguard Worker 
1408*35238bceSAndroid Build Coastguard Worker         DE_ASSERT((int)(sizeof(DrawElementsCommand) * cmds.size()) == m_numDrawCmds * m_commandSize);
1409*35238bceSAndroid Build Coastguard Worker 
1410*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
1411*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, (glw::GLsizeiptr)(sizeof(DrawElementsCommand) * cmds.size()), &cmds[0],
1412*35238bceSAndroid Build Coastguard Worker                       GL_STATIC_DRAW);
1413*35238bceSAndroid Build Coastguard Worker     }
1414*35238bceSAndroid Build Coastguard Worker     else
1415*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1416*35238bceSAndroid Build Coastguard Worker 
1417*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "create draw command", __FILE__, __LINE__);
1418*35238bceSAndroid Build Coastguard Worker }
1419*35238bceSAndroid Build Coastguard Worker 
createDrawData(void)1420*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::createDrawData(void)
1421*35238bceSAndroid Build Coastguard Worker {
1422*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 yellow(1.0f, 1.0f, 0.0f, 1.0f);
1423*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1424*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1425*35238bceSAndroid Build Coastguard Worker 
1426*35238bceSAndroid Build Coastguard Worker     if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1427*35238bceSAndroid Build Coastguard Worker     {
1428*35238bceSAndroid Build Coastguard Worker         // Store elements in the order they are drawn. Interleave color.
1429*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> buffer(m_gridSize * m_gridSize * 6 * 2);
1430*35238bceSAndroid Build Coastguard Worker 
1431*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(buffer.size() == calcDrawBufferSize());
1432*35238bceSAndroid Build Coastguard Worker 
1433*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < m_gridSize; ++y)
1434*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < m_gridSize; ++x)
1435*35238bceSAndroid Build Coastguard Worker             {
1436*35238bceSAndroid Build Coastguard Worker                 const float posX       = ((float)x / (float)m_gridSize) * 2.0f - 1.0f;
1437*35238bceSAndroid Build Coastguard Worker                 const float posY       = ((float)y / (float)m_gridSize) * 2.0f - 1.0f;
1438*35238bceSAndroid Build Coastguard Worker                 const float cellSize   = 2.0f / (float)m_gridSize;
1439*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 &color = ((x + y) % 2) ? (yellow) : (green);
1440*35238bceSAndroid Build Coastguard Worker 
1441*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 0] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1442*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 0] = tcu::Vec4(posX + cellSize, posY, 0.0f, 1.0f);
1443*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 0] =
1444*35238bceSAndroid Build Coastguard Worker                     tcu::Vec4(posX + cellSize, posY + cellSize, 0.0f, 1.0f);
1445*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 0] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1446*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 0] =
1447*35238bceSAndroid Build Coastguard Worker                     tcu::Vec4(posX + cellSize, posY + cellSize, 0.0f, 1.0f);
1448*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 0] = tcu::Vec4(posX, posY + cellSize, 0.0f, 1.0f);
1449*35238bceSAndroid Build Coastguard Worker 
1450*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 0) * 2 + 1] = color;
1451*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 1) * 2 + 1] = color;
1452*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 2) * 2 + 1] = color;
1453*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 3) * 2 + 1] = color;
1454*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 4) * 2 + 1] = color;
1455*35238bceSAndroid Build Coastguard Worker                 buffer[((y * m_gridSize + x) * 6 + 5) * 2 + 1] = color;
1456*35238bceSAndroid Build Coastguard Worker             }
1457*35238bceSAndroid Build Coastguard Worker 
1458*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
1459*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
1460*35238bceSAndroid Build Coastguard Worker     }
1461*35238bceSAndroid Build Coastguard Worker     else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1462*35238bceSAndroid Build Coastguard Worker     {
1463*35238bceSAndroid Build Coastguard Worker         // Elements are indexed by index buffer. Interleave color. Two vertices per position since 2 colors
1464*35238bceSAndroid Build Coastguard Worker 
1465*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> buffer((m_gridSize + 1) * (m_gridSize + 1) * 4);
1466*35238bceSAndroid Build Coastguard Worker 
1467*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(buffer.size() == calcDrawBufferSize());
1468*35238bceSAndroid Build Coastguard Worker 
1469*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < m_gridSize + 1; ++y)
1470*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < m_gridSize + 1; ++x)
1471*35238bceSAndroid Build Coastguard Worker             {
1472*35238bceSAndroid Build Coastguard Worker                 const float posX = ((float)x / (float)m_gridSize) * 2.0f - 1.0f;
1473*35238bceSAndroid Build Coastguard Worker                 const float posY = ((float)y / (float)m_gridSize) * 2.0f - 1.0f;
1474*35238bceSAndroid Build Coastguard Worker 
1475*35238bceSAndroid Build Coastguard Worker                 buffer[(y * (m_gridSize + 1) + x) * 4 + 0] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1476*35238bceSAndroid Build Coastguard Worker                 buffer[(y * (m_gridSize + 1) + x) * 4 + 1] = green;
1477*35238bceSAndroid Build Coastguard Worker                 buffer[(y * (m_gridSize + 1) + x) * 4 + 2] = tcu::Vec4(posX, posY, 0.0f, 1.0f);
1478*35238bceSAndroid Build Coastguard Worker                 buffer[(y * (m_gridSize + 1) + x) * 4 + 3] = yellow;
1479*35238bceSAndroid Build Coastguard Worker             }
1480*35238bceSAndroid Build Coastguard Worker 
1481*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
1482*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, (int)(buffer.size() * sizeof(tcu::Vec4)), buffer[0].getPtr(), GL_STATIC_DRAW);
1483*35238bceSAndroid Build Coastguard Worker     }
1484*35238bceSAndroid Build Coastguard Worker     else
1485*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1486*35238bceSAndroid Build Coastguard Worker 
1487*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
1488*35238bceSAndroid Build Coastguard Worker }
1489*35238bceSAndroid Build Coastguard Worker 
createDrawIndices(void)1490*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::createDrawIndices(void)
1491*35238bceSAndroid Build Coastguard Worker {
1492*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
1493*35238bceSAndroid Build Coastguard Worker 
1494*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1495*35238bceSAndroid Build Coastguard Worker     std::vector<uint32_t> buffer(m_gridSize * m_gridSize * 6);
1496*35238bceSAndroid Build Coastguard Worker 
1497*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(buffer.size() == calcIndexBufferSize());
1498*35238bceSAndroid Build Coastguard Worker 
1499*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < m_gridSize; ++y)
1500*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < m_gridSize; ++x)
1501*35238bceSAndroid Build Coastguard Worker         {
1502*35238bceSAndroid Build Coastguard Worker             const int color = ((x + y) % 2);
1503*35238bceSAndroid Build Coastguard Worker 
1504*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 0] = ((y + 0) * (m_gridSize + 1) + (x + 0)) * 2 + color;
1505*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 1] = ((y + 1) * (m_gridSize + 1) + (x + 0)) * 2 + color;
1506*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 2] = ((y + 1) * (m_gridSize + 1) + (x + 1)) * 2 + color;
1507*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 3] = ((y + 0) * (m_gridSize + 1) + (x + 0)) * 2 + color;
1508*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 4] = ((y + 1) * (m_gridSize + 1) + (x + 1)) * 2 + color;
1509*35238bceSAndroid Build Coastguard Worker             buffer[(y * m_gridSize + x) * 6 + 5] = ((y + 0) * (m_gridSize + 1) + (x + 1)) * 2 + color;
1510*35238bceSAndroid Build Coastguard Worker         }
1511*35238bceSAndroid Build Coastguard Worker 
1512*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
1513*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (int)(buffer.size() * sizeof(uint32_t)), &buffer[0], GL_STATIC_DRAW);
1514*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
1515*35238bceSAndroid Build Coastguard Worker }
1516*35238bceSAndroid Build Coastguard Worker 
renderTo(tcu::Surface & dst)1517*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCase::renderTo(tcu::Surface &dst)
1518*35238bceSAndroid Build Coastguard Worker {
1519*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl  = m_context.getRenderContext().getFunctions();
1520*35238bceSAndroid Build Coastguard Worker     const int32_t positionLoc = gl.getAttribLocation(m_shaderProgram->getProgram(), "a_position");
1521*35238bceSAndroid Build Coastguard Worker     const int32_t colorLoc    = gl.getAttribLocation(m_shaderProgram->getProgram(), "a_color");
1522*35238bceSAndroid Build Coastguard Worker     uint32_t vaoID            = 0;
1523*35238bceSAndroid Build Coastguard Worker 
1524*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &vaoID);
1525*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(vaoID);
1526*35238bceSAndroid Build Coastguard Worker 
1527*35238bceSAndroid Build Coastguard Worker     // Setup buffers
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBufferID);
1530*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 8 * (int)sizeof(float), DE_NULL);
1531*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 8 * (int)sizeof(float),
1532*35238bceSAndroid Build Coastguard Worker                            glu::BufferOffsetAsPointer(4 * sizeof(float)));
1533*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(positionLoc);
1534*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(colorLoc);
1535*35238bceSAndroid Build Coastguard Worker 
1536*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(positionLoc != -1);
1537*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(colorLoc != -1);
1538*35238bceSAndroid Build Coastguard Worker 
1539*35238bceSAndroid Build Coastguard Worker     if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1540*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferID);
1541*35238bceSAndroid Build Coastguard Worker 
1542*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmdBufferID);
1543*35238bceSAndroid Build Coastguard Worker 
1544*35238bceSAndroid Build Coastguard Worker     // draw
1545*35238bceSAndroid Build Coastguard Worker 
1546*35238bceSAndroid Build Coastguard Worker     gl.clearColor(0, 0, 0, 1);
1547*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
1548*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, dst.getWidth(), dst.getHeight());
1549*35238bceSAndroid Build Coastguard Worker 
1550*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_shaderProgram->getProgram());
1551*35238bceSAndroid Build Coastguard Worker     for (int drawCmdNdx = 0; drawCmdNdx < m_numDrawCmds; ++drawCmdNdx)
1552*35238bceSAndroid Build Coastguard Worker     {
1553*35238bceSAndroid Build Coastguard Worker         const void *offset = glu::BufferOffsetAsPointer(drawCmdNdx * m_commandSize);
1554*35238bceSAndroid Build Coastguard Worker 
1555*35238bceSAndroid Build Coastguard Worker         if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1556*35238bceSAndroid Build Coastguard Worker             gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, offset);
1557*35238bceSAndroid Build Coastguard Worker         else if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1558*35238bceSAndroid Build Coastguard Worker             gl.drawArraysIndirect(GL_TRIANGLES, offset);
1559*35238bceSAndroid Build Coastguard Worker         else
1560*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1561*35238bceSAndroid Build Coastguard Worker     }
1562*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
1563*35238bceSAndroid Build Coastguard Worker 
1564*35238bceSAndroid Build Coastguard Worker     // free
1565*35238bceSAndroid Build Coastguard Worker 
1566*35238bceSAndroid Build Coastguard Worker     gl.deleteVertexArrays(1, &vaoID);
1567*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
1568*35238bceSAndroid Build Coastguard Worker 
1569*35238bceSAndroid Build Coastguard Worker     gl.finish();
1570*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
1571*35238bceSAndroid Build Coastguard Worker 
1572*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess());
1573*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
1574*35238bceSAndroid Build Coastguard Worker }
1575*35238bceSAndroid Build Coastguard Worker 
calcDrawBufferSize(void) const1576*35238bceSAndroid Build Coastguard Worker uint32_t ComputeShaderGeneratedCase::calcDrawBufferSize(void) const
1577*35238bceSAndroid Build Coastguard Worker {
1578*35238bceSAndroid Build Coastguard Worker     // returns size in "vec4"s
1579*35238bceSAndroid Build Coastguard Worker     if (m_drawMethod == DRAWMETHOD_DRAWARRAYS)
1580*35238bceSAndroid Build Coastguard Worker         return m_gridSize * m_gridSize * 6 * 2;
1581*35238bceSAndroid Build Coastguard Worker     else if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1582*35238bceSAndroid Build Coastguard Worker         return (m_gridSize + 1) * (m_gridSize + 1) * 4;
1583*35238bceSAndroid Build Coastguard Worker     else
1584*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1585*35238bceSAndroid Build Coastguard Worker 
1586*35238bceSAndroid Build Coastguard Worker     return 0;
1587*35238bceSAndroid Build Coastguard Worker }
1588*35238bceSAndroid Build Coastguard Worker 
calcIndexBufferSize(void) const1589*35238bceSAndroid Build Coastguard Worker uint32_t ComputeShaderGeneratedCase::calcIndexBufferSize(void) const
1590*35238bceSAndroid Build Coastguard Worker {
1591*35238bceSAndroid Build Coastguard Worker     if (m_drawMethod == DRAWMETHOD_DRAWELEMENTS)
1592*35238bceSAndroid Build Coastguard Worker         return m_gridSize * m_gridSize * 6;
1593*35238bceSAndroid Build Coastguard Worker     else
1594*35238bceSAndroid Build Coastguard Worker         return 0;
1595*35238bceSAndroid Build Coastguard Worker }
1596*35238bceSAndroid Build Coastguard Worker 
1597*35238bceSAndroid Build Coastguard Worker class ComputeShaderGeneratedCombinedCase : public ComputeShaderGeneratedCase
1598*35238bceSAndroid Build Coastguard Worker {
1599*35238bceSAndroid Build Coastguard Worker public:
1600*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCombinedCase(Context &context, const char *name, const char *desc, DrawMethod method,
1601*35238bceSAndroid Build Coastguard Worker                                        bool computeCmd, bool computeData, bool computeIndices, int gridSize,
1602*35238bceSAndroid Build Coastguard Worker                                        int numDrawCalls);
1603*35238bceSAndroid Build Coastguard Worker     ~ComputeShaderGeneratedCombinedCase(void);
1604*35238bceSAndroid Build Coastguard Worker 
1605*35238bceSAndroid Build Coastguard Worker     void init(void);
1606*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1607*35238bceSAndroid Build Coastguard Worker 
1608*35238bceSAndroid Build Coastguard Worker private:
1609*35238bceSAndroid Build Coastguard Worker     void runComputeShader(void);
1610*35238bceSAndroid Build Coastguard Worker 
1611*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_computeProgram;
1612*35238bceSAndroid Build Coastguard Worker };
1613*35238bceSAndroid Build Coastguard Worker 
ComputeShaderGeneratedCombinedCase(Context & context,const char * name,const char * desc,DrawMethod method,bool computeCmd,bool computeData,bool computeIndices,int gridSize,int numDrawCalls)1614*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedCombinedCase::ComputeShaderGeneratedCombinedCase(Context &context, const char *name,
1615*35238bceSAndroid Build Coastguard Worker                                                                        const char *desc, DrawMethod method,
1616*35238bceSAndroid Build Coastguard Worker                                                                        bool computeCmd, bool computeData,
1617*35238bceSAndroid Build Coastguard Worker                                                                        bool computeIndices, int gridSize,
1618*35238bceSAndroid Build Coastguard Worker                                                                        int numDrawCalls)
1619*35238bceSAndroid Build Coastguard Worker     : ComputeShaderGeneratedCase(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize,
1620*35238bceSAndroid Build Coastguard Worker                                  numDrawCalls)
1621*35238bceSAndroid Build Coastguard Worker     , m_computeProgram(DE_NULL)
1622*35238bceSAndroid Build Coastguard Worker {
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker 
~ComputeShaderGeneratedCombinedCase(void)1625*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedCombinedCase::~ComputeShaderGeneratedCombinedCase(void)
1626*35238bceSAndroid Build Coastguard Worker {
1627*35238bceSAndroid Build Coastguard Worker     deinit();
1628*35238bceSAndroid Build Coastguard Worker }
1629*35238bceSAndroid Build Coastguard Worker 
init(void)1630*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCombinedCase::init(void)
1631*35238bceSAndroid Build Coastguard Worker {
1632*35238bceSAndroid Build Coastguard Worker     // generate compute shader
1633*35238bceSAndroid Build Coastguard Worker 
1634*35238bceSAndroid Build Coastguard Worker     m_computeProgram = new glu::ShaderProgram(
1635*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext(),
1636*35238bceSAndroid Build Coastguard Worker         glu::ProgramSources() << glu::ComputeSource(genComputeSource(m_computeCmd, m_computeData, m_computeIndices)));
1637*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << *m_computeProgram;
1638*35238bceSAndroid Build Coastguard Worker 
1639*35238bceSAndroid Build Coastguard Worker     if (!m_computeProgram->isOk())
1640*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Failed to compile compute shader.");
1641*35238bceSAndroid Build Coastguard Worker 
1642*35238bceSAndroid Build Coastguard Worker     // init parent
1643*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCase::init();
1644*35238bceSAndroid Build Coastguard Worker }
1645*35238bceSAndroid Build Coastguard Worker 
deinit(void)1646*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCombinedCase::deinit(void)
1647*35238bceSAndroid Build Coastguard Worker {
1648*35238bceSAndroid Build Coastguard Worker     // deinit parent
1649*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCase::deinit();
1650*35238bceSAndroid Build Coastguard Worker 
1651*35238bceSAndroid Build Coastguard Worker     if (m_computeProgram)
1652*35238bceSAndroid Build Coastguard Worker     {
1653*35238bceSAndroid Build Coastguard Worker         delete m_computeProgram;
1654*35238bceSAndroid Build Coastguard Worker         m_computeProgram = DE_NULL;
1655*35238bceSAndroid Build Coastguard Worker     }
1656*35238bceSAndroid Build Coastguard Worker }
1657*35238bceSAndroid Build Coastguard Worker 
runComputeShader(void)1658*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedCombinedCase::runComputeShader(void)
1659*35238bceSAndroid Build Coastguard Worker {
1660*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1661*35238bceSAndroid Build Coastguard Worker     const bool indexed       = (m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
1662*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 nullSize(0, 0, 0);
1663*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 commandDispatchSize = (m_computeCmd) ? (tcu::IVec3(m_numDrawCmds, 1, 1)) : (nullSize);
1664*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 drawElementsDataBufferDispatchSize =
1665*35238bceSAndroid Build Coastguard Worker         (m_computeData) ? (tcu::IVec3(m_gridSize + 1, m_gridSize + 1, 1)) : (nullSize);
1666*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 drawArraysDataBufferDispatchSize =
1667*35238bceSAndroid Build Coastguard Worker         (m_computeData) ? (tcu::IVec3(m_gridSize, m_gridSize, 1)) : (nullSize);
1668*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 indexBufferDispatchSize =
1669*35238bceSAndroid Build Coastguard Worker         (m_computeIndices && indexed) ? (tcu::IVec3(m_gridSize, m_gridSize, 1)) : (nullSize);
1670*35238bceSAndroid Build Coastguard Worker 
1671*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 dataBufferDispatchSize = (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ?
1672*35238bceSAndroid Build Coastguard Worker                                                   (drawElementsDataBufferDispatchSize) :
1673*35238bceSAndroid Build Coastguard Worker                                                   (drawArraysDataBufferDispatchSize);
1674*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 dispatchSize =
1675*35238bceSAndroid Build Coastguard Worker         tcu::max(tcu::max(commandDispatchSize, dataBufferDispatchSize), indexBufferDispatchSize);
1676*35238bceSAndroid Build Coastguard Worker 
1677*35238bceSAndroid Build Coastguard Worker     gl.useProgram(m_computeProgram->getProgram());
1678*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "use compute shader", __FILE__, __LINE__);
1679*35238bceSAndroid Build Coastguard Worker 
1680*35238bceSAndroid Build Coastguard Worker     // setup buffers
1681*35238bceSAndroid Build Coastguard Worker 
1682*35238bceSAndroid Build Coastguard Worker     if (m_computeCmd)
1683*35238bceSAndroid Build Coastguard Worker     {
1684*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = 0;
1685*35238bceSAndroid Build Coastguard Worker         const int bufferSize   = m_commandSize * m_numDrawCmds;
1686*35238bceSAndroid Build Coastguard Worker 
1687*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint
1688*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1689*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);
1690*35238bceSAndroid Build Coastguard Worker 
1691*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size "
1692*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1693*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1694*35238bceSAndroid Build Coastguard Worker     }
1695*35238bceSAndroid Build Coastguard Worker 
1696*35238bceSAndroid Build Coastguard Worker     if (m_computeData)
1697*35238bceSAndroid Build Coastguard Worker     {
1698*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = (m_computeCmd) ? (1) : (0);
1699*35238bceSAndroid Build Coastguard Worker         const int bufferSize   = (int)(calcDrawBufferSize() * sizeof(tcu::Vec4));
1700*35238bceSAndroid Build Coastguard Worker 
1701*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint
1702*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1703*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);
1704*35238bceSAndroid Build Coastguard Worker 
1705*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size "
1706*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1707*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1708*35238bceSAndroid Build Coastguard Worker     }
1709*35238bceSAndroid Build Coastguard Worker 
1710*35238bceSAndroid Build Coastguard Worker     if (m_computeIndices)
1711*35238bceSAndroid Build Coastguard Worker     {
1712*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = (m_computeCmd && m_computeData) ? (2) : (m_computeCmd || m_computeData) ? (1) : (0);
1713*35238bceSAndroid Build Coastguard Worker         const int bufferSize   = (int)(calcIndexBufferSize() * sizeof(uint32_t));
1714*35238bceSAndroid Build Coastguard Worker 
1715*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint
1716*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1717*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);
1718*35238bceSAndroid Build Coastguard Worker 
1719*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size "
1720*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1721*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1722*35238bceSAndroid Build Coastguard Worker     }
1723*35238bceSAndroid Build Coastguard Worker 
1724*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "setup buffers", __FILE__, __LINE__);
1725*35238bceSAndroid Build Coastguard Worker 
1726*35238bceSAndroid Build Coastguard Worker     // calculate
1727*35238bceSAndroid Build Coastguard Worker 
1728*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching compute, size = " << dispatchSize
1729*35238bceSAndroid Build Coastguard Worker                        << tcu::TestLog::EndMessage;
1730*35238bceSAndroid Build Coastguard Worker     gl.dispatchCompute(dispatchSize.x(), dispatchSize.y(), dispatchSize.z());
1731*35238bceSAndroid Build Coastguard Worker 
1732*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "calculate", __FILE__, __LINE__);
1733*35238bceSAndroid Build Coastguard Worker }
1734*35238bceSAndroid Build Coastguard Worker 
1735*35238bceSAndroid Build Coastguard Worker class ComputeShaderGeneratedSeparateCase : public ComputeShaderGeneratedCase
1736*35238bceSAndroid Build Coastguard Worker {
1737*35238bceSAndroid Build Coastguard Worker public:
1738*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedSeparateCase(Context &context, const char *name, const char *desc, DrawMethod method,
1739*35238bceSAndroid Build Coastguard Worker                                        bool computeCmd, bool computeData, bool computeIndices, int gridSize,
1740*35238bceSAndroid Build Coastguard Worker                                        int numDrawCalls);
1741*35238bceSAndroid Build Coastguard Worker     ~ComputeShaderGeneratedSeparateCase(void);
1742*35238bceSAndroid Build Coastguard Worker 
1743*35238bceSAndroid Build Coastguard Worker     void init(void);
1744*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1745*35238bceSAndroid Build Coastguard Worker 
1746*35238bceSAndroid Build Coastguard Worker private:
1747*35238bceSAndroid Build Coastguard Worker     std::string genCmdComputeSource(void);
1748*35238bceSAndroid Build Coastguard Worker     std::string genDataComputeSource(void);
1749*35238bceSAndroid Build Coastguard Worker     std::string genIndexComputeSource(void);
1750*35238bceSAndroid Build Coastguard Worker     void runComputeShader(void);
1751*35238bceSAndroid Build Coastguard Worker 
1752*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_computeCmdProgram;
1753*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_computeDataProgram;
1754*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram *m_computeIndicesProgram;
1755*35238bceSAndroid Build Coastguard Worker };
1756*35238bceSAndroid Build Coastguard Worker 
ComputeShaderGeneratedSeparateCase(Context & context,const char * name,const char * desc,DrawMethod method,bool computeCmd,bool computeData,bool computeIndices,int gridSize,int numDrawCalls)1757*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedSeparateCase::ComputeShaderGeneratedSeparateCase(Context &context, const char *name,
1758*35238bceSAndroid Build Coastguard Worker                                                                        const char *desc, DrawMethod method,
1759*35238bceSAndroid Build Coastguard Worker                                                                        bool computeCmd, bool computeData,
1760*35238bceSAndroid Build Coastguard Worker                                                                        bool computeIndices, int gridSize,
1761*35238bceSAndroid Build Coastguard Worker                                                                        int numDrawCalls)
1762*35238bceSAndroid Build Coastguard Worker     : ComputeShaderGeneratedCase(context, name, desc, method, computeCmd, computeData, computeIndices, gridSize,
1763*35238bceSAndroid Build Coastguard Worker                                  numDrawCalls)
1764*35238bceSAndroid Build Coastguard Worker     , m_computeCmdProgram(DE_NULL)
1765*35238bceSAndroid Build Coastguard Worker     , m_computeDataProgram(DE_NULL)
1766*35238bceSAndroid Build Coastguard Worker     , m_computeIndicesProgram(DE_NULL)
1767*35238bceSAndroid Build Coastguard Worker {
1768*35238bceSAndroid Build Coastguard Worker }
1769*35238bceSAndroid Build Coastguard Worker 
~ComputeShaderGeneratedSeparateCase(void)1770*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedSeparateCase::~ComputeShaderGeneratedSeparateCase(void)
1771*35238bceSAndroid Build Coastguard Worker {
1772*35238bceSAndroid Build Coastguard Worker     deinit();
1773*35238bceSAndroid Build Coastguard Worker }
1774*35238bceSAndroid Build Coastguard Worker 
init(void)1775*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedSeparateCase::init(void)
1776*35238bceSAndroid Build Coastguard Worker {
1777*35238bceSAndroid Build Coastguard Worker     // generate cmd compute shader
1778*35238bceSAndroid Build Coastguard Worker 
1779*35238bceSAndroid Build Coastguard Worker     if (m_computeCmd)
1780*35238bceSAndroid Build Coastguard Worker     {
1781*35238bceSAndroid Build Coastguard Worker         m_computeCmdProgram = new glu::ShaderProgram(
1782*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genCmdComputeSource()));
1783*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_computeCmdProgram;
1784*35238bceSAndroid Build Coastguard Worker 
1785*35238bceSAndroid Build Coastguard Worker         if (!m_computeCmdProgram->isOk())
1786*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Failed to compile command compute shader.");
1787*35238bceSAndroid Build Coastguard Worker     }
1788*35238bceSAndroid Build Coastguard Worker 
1789*35238bceSAndroid Build Coastguard Worker     // generate data compute shader
1790*35238bceSAndroid Build Coastguard Worker 
1791*35238bceSAndroid Build Coastguard Worker     if (m_computeData)
1792*35238bceSAndroid Build Coastguard Worker     {
1793*35238bceSAndroid Build Coastguard Worker         m_computeDataProgram = new glu::ShaderProgram(
1794*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genDataComputeSource()));
1795*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_computeDataProgram;
1796*35238bceSAndroid Build Coastguard Worker 
1797*35238bceSAndroid Build Coastguard Worker         if (!m_computeDataProgram->isOk())
1798*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Failed to compile data compute shader.");
1799*35238bceSAndroid Build Coastguard Worker     }
1800*35238bceSAndroid Build Coastguard Worker 
1801*35238bceSAndroid Build Coastguard Worker     // generate index compute shader
1802*35238bceSAndroid Build Coastguard Worker 
1803*35238bceSAndroid Build Coastguard Worker     if (m_computeIndices)
1804*35238bceSAndroid Build Coastguard Worker     {
1805*35238bceSAndroid Build Coastguard Worker         m_computeIndicesProgram = new glu::ShaderProgram(
1806*35238bceSAndroid Build Coastguard Worker             m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(genIndexComputeSource()));
1807*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_computeIndicesProgram;
1808*35238bceSAndroid Build Coastguard Worker 
1809*35238bceSAndroid Build Coastguard Worker         if (!m_computeIndicesProgram->isOk())
1810*35238bceSAndroid Build Coastguard Worker             throw tcu::TestError("Failed to compile data compute shader.");
1811*35238bceSAndroid Build Coastguard Worker     }
1812*35238bceSAndroid Build Coastguard Worker 
1813*35238bceSAndroid Build Coastguard Worker     // init parent
1814*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCase::init();
1815*35238bceSAndroid Build Coastguard Worker }
1816*35238bceSAndroid Build Coastguard Worker 
deinit(void)1817*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedSeparateCase::deinit(void)
1818*35238bceSAndroid Build Coastguard Worker {
1819*35238bceSAndroid Build Coastguard Worker     // deinit parent
1820*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedCase::deinit();
1821*35238bceSAndroid Build Coastguard Worker 
1822*35238bceSAndroid Build Coastguard Worker     if (m_computeCmdProgram)
1823*35238bceSAndroid Build Coastguard Worker     {
1824*35238bceSAndroid Build Coastguard Worker         delete m_computeCmdProgram;
1825*35238bceSAndroid Build Coastguard Worker         m_computeCmdProgram = DE_NULL;
1826*35238bceSAndroid Build Coastguard Worker     }
1827*35238bceSAndroid Build Coastguard Worker     if (m_computeDataProgram)
1828*35238bceSAndroid Build Coastguard Worker     {
1829*35238bceSAndroid Build Coastguard Worker         delete m_computeDataProgram;
1830*35238bceSAndroid Build Coastguard Worker         m_computeDataProgram = DE_NULL;
1831*35238bceSAndroid Build Coastguard Worker     }
1832*35238bceSAndroid Build Coastguard Worker     if (m_computeIndicesProgram)
1833*35238bceSAndroid Build Coastguard Worker     {
1834*35238bceSAndroid Build Coastguard Worker         delete m_computeIndicesProgram;
1835*35238bceSAndroid Build Coastguard Worker         m_computeIndicesProgram = DE_NULL;
1836*35238bceSAndroid Build Coastguard Worker     }
1837*35238bceSAndroid Build Coastguard Worker }
1838*35238bceSAndroid Build Coastguard Worker 
genCmdComputeSource(void)1839*35238bceSAndroid Build Coastguard Worker std::string ComputeShaderGeneratedSeparateCase::genCmdComputeSource(void)
1840*35238bceSAndroid Build Coastguard Worker {
1841*35238bceSAndroid Build Coastguard Worker     return ComputeShaderGeneratedCase::genComputeSource(true, false, false);
1842*35238bceSAndroid Build Coastguard Worker }
1843*35238bceSAndroid Build Coastguard Worker 
genDataComputeSource(void)1844*35238bceSAndroid Build Coastguard Worker std::string ComputeShaderGeneratedSeparateCase::genDataComputeSource(void)
1845*35238bceSAndroid Build Coastguard Worker {
1846*35238bceSAndroid Build Coastguard Worker     return ComputeShaderGeneratedCase::genComputeSource(false, true, false);
1847*35238bceSAndroid Build Coastguard Worker }
1848*35238bceSAndroid Build Coastguard Worker 
genIndexComputeSource(void)1849*35238bceSAndroid Build Coastguard Worker std::string ComputeShaderGeneratedSeparateCase::genIndexComputeSource(void)
1850*35238bceSAndroid Build Coastguard Worker {
1851*35238bceSAndroid Build Coastguard Worker     return ComputeShaderGeneratedCase::genComputeSource(false, false, true);
1852*35238bceSAndroid Build Coastguard Worker }
1853*35238bceSAndroid Build Coastguard Worker 
runComputeShader(void)1854*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedSeparateCase::runComputeShader(void)
1855*35238bceSAndroid Build Coastguard Worker {
1856*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1857*35238bceSAndroid Build Coastguard Worker 
1858*35238bceSAndroid Build Coastguard Worker     // Compute command
1859*35238bceSAndroid Build Coastguard Worker 
1860*35238bceSAndroid Build Coastguard Worker     if (m_computeCmd)
1861*35238bceSAndroid Build Coastguard Worker     {
1862*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = 0;
1863*35238bceSAndroid Build Coastguard Worker         const tcu::IVec3 commandDispatchSize(m_numDrawCmds, 1, 1);
1864*35238bceSAndroid Build Coastguard Worker         const int bufferSize = m_commandSize * m_numDrawCmds;
1865*35238bceSAndroid Build Coastguard Worker 
1866*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_computeCmdProgram->getProgram());
1867*35238bceSAndroid Build Coastguard Worker 
1868*35238bceSAndroid Build Coastguard Worker         // setup buffers
1869*35238bceSAndroid Build Coastguard Worker 
1870*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding command buffer to binding point " << bindingPoint
1871*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1872*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_cmdBufferID);
1873*35238bceSAndroid Build Coastguard Worker 
1874*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for command buffer, size "
1875*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1876*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1877*35238bceSAndroid Build Coastguard Worker 
1878*35238bceSAndroid Build Coastguard Worker         // calculate
1879*35238bceSAndroid Build Coastguard Worker 
1880*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching command compute, size = " << commandDispatchSize
1881*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1882*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(commandDispatchSize.x(), commandDispatchSize.y(), commandDispatchSize.z());
1883*35238bceSAndroid Build Coastguard Worker 
1884*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "calculate cmd", __FILE__, __LINE__);
1885*35238bceSAndroid Build Coastguard Worker     }
1886*35238bceSAndroid Build Coastguard Worker 
1887*35238bceSAndroid Build Coastguard Worker     // Compute data
1888*35238bceSAndroid Build Coastguard Worker 
1889*35238bceSAndroid Build Coastguard Worker     if (m_computeData)
1890*35238bceSAndroid Build Coastguard Worker     {
1891*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = 0;
1892*35238bceSAndroid Build Coastguard Worker         const tcu::IVec3 drawElementsDataBufferDispatchSize(m_gridSize + 1, m_gridSize + 1, 1);
1893*35238bceSAndroid Build Coastguard Worker         const tcu::IVec3 drawArraysDataBufferDispatchSize(m_gridSize, m_gridSize, 1);
1894*35238bceSAndroid Build Coastguard Worker         const tcu::IVec3 dataBufferDispatchSize = (m_drawMethod == DRAWMETHOD_DRAWELEMENTS) ?
1895*35238bceSAndroid Build Coastguard Worker                                                       (drawElementsDataBufferDispatchSize) :
1896*35238bceSAndroid Build Coastguard Worker                                                       (drawArraysDataBufferDispatchSize);
1897*35238bceSAndroid Build Coastguard Worker         const int bufferSize                    = (int)(calcDrawBufferSize() * sizeof(tcu::Vec4));
1898*35238bceSAndroid Build Coastguard Worker 
1899*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_computeDataProgram->getProgram());
1900*35238bceSAndroid Build Coastguard Worker 
1901*35238bceSAndroid Build Coastguard Worker         // setup buffers
1902*35238bceSAndroid Build Coastguard Worker 
1903*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding data buffer to binding point " << bindingPoint
1904*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1905*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_dataBufferID);
1906*35238bceSAndroid Build Coastguard Worker 
1907*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for data buffer, size "
1908*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1909*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1910*35238bceSAndroid Build Coastguard Worker 
1911*35238bceSAndroid Build Coastguard Worker         // calculate
1912*35238bceSAndroid Build Coastguard Worker 
1913*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching data compute, size = " << dataBufferDispatchSize
1914*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1915*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(dataBufferDispatchSize.x(), dataBufferDispatchSize.y(), dataBufferDispatchSize.z());
1916*35238bceSAndroid Build Coastguard Worker 
1917*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "calculate data", __FILE__, __LINE__);
1918*35238bceSAndroid Build Coastguard Worker     }
1919*35238bceSAndroid Build Coastguard Worker 
1920*35238bceSAndroid Build Coastguard Worker     // Compute indices
1921*35238bceSAndroid Build Coastguard Worker 
1922*35238bceSAndroid Build Coastguard Worker     if (m_computeIndices)
1923*35238bceSAndroid Build Coastguard Worker     {
1924*35238bceSAndroid Build Coastguard Worker         const int bindingPoint = 0;
1925*35238bceSAndroid Build Coastguard Worker         const tcu::IVec3 indexBufferDispatchSize(m_gridSize, m_gridSize, 1);
1926*35238bceSAndroid Build Coastguard Worker         const int bufferSize = (int)(calcIndexBufferSize() * sizeof(uint32_t));
1927*35238bceSAndroid Build Coastguard Worker 
1928*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_drawMethod == DRAWMETHOD_DRAWELEMENTS);
1929*35238bceSAndroid Build Coastguard Worker 
1930*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_computeIndicesProgram->getProgram());
1931*35238bceSAndroid Build Coastguard Worker 
1932*35238bceSAndroid Build Coastguard Worker         // setup buffers
1933*35238bceSAndroid Build Coastguard Worker 
1934*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Binding index buffer to binding point " << bindingPoint
1935*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1936*35238bceSAndroid Build Coastguard Worker         gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, m_indexBufferID);
1937*35238bceSAndroid Build Coastguard Worker 
1938*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Allocating memory for index buffer, size "
1939*35238bceSAndroid Build Coastguard Worker                            << sizeToString(bufferSize) << "." << tcu::TestLog::EndMessage;
1940*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_DRAW);
1941*35238bceSAndroid Build Coastguard Worker 
1942*35238bceSAndroid Build Coastguard Worker         // calculate
1943*35238bceSAndroid Build Coastguard Worker 
1944*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Dispatching index compute, size = " << indexBufferDispatchSize
1945*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1946*35238bceSAndroid Build Coastguard Worker         gl.dispatchCompute(indexBufferDispatchSize.x(), indexBufferDispatchSize.y(), indexBufferDispatchSize.z());
1947*35238bceSAndroid Build Coastguard Worker 
1948*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "calculate indices", __FILE__, __LINE__);
1949*35238bceSAndroid Build Coastguard Worker     }
1950*35238bceSAndroid Build Coastguard Worker 
1951*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "post dispatch", __FILE__, __LINE__);
1952*35238bceSAndroid Build Coastguard Worker }
1953*35238bceSAndroid Build Coastguard Worker 
1954*35238bceSAndroid Build Coastguard Worker class ComputeShaderGeneratedGroup : public TestCaseGroup
1955*35238bceSAndroid Build Coastguard Worker {
1956*35238bceSAndroid Build Coastguard Worker public:
1957*35238bceSAndroid Build Coastguard Worker     ComputeShaderGeneratedGroup(Context &context, const char *name, const char *descr);
1958*35238bceSAndroid Build Coastguard Worker     ~ComputeShaderGeneratedGroup(void);
1959*35238bceSAndroid Build Coastguard Worker 
1960*35238bceSAndroid Build Coastguard Worker     void init(void);
1961*35238bceSAndroid Build Coastguard Worker };
1962*35238bceSAndroid Build Coastguard Worker 
ComputeShaderGeneratedGroup(Context & context,const char * name,const char * descr)1963*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedGroup::ComputeShaderGeneratedGroup(Context &context, const char *name, const char *descr)
1964*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
1965*35238bceSAndroid Build Coastguard Worker {
1966*35238bceSAndroid Build Coastguard Worker }
1967*35238bceSAndroid Build Coastguard Worker 
~ComputeShaderGeneratedGroup(void)1968*35238bceSAndroid Build Coastguard Worker ComputeShaderGeneratedGroup::~ComputeShaderGeneratedGroup(void)
1969*35238bceSAndroid Build Coastguard Worker {
1970*35238bceSAndroid Build Coastguard Worker }
1971*35238bceSAndroid Build Coastguard Worker 
init(void)1972*35238bceSAndroid Build Coastguard Worker void ComputeShaderGeneratedGroup::init(void)
1973*35238bceSAndroid Build Coastguard Worker {
1974*35238bceSAndroid Build Coastguard Worker     const int gridSize = 8;
1975*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const separateGroup =
1976*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "separate", "Use separate compute shaders for each buffer");
1977*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const combinedGroup =
1978*35238bceSAndroid Build Coastguard Worker         new tcu::TestCaseGroup(m_testCtx, "combined", "Use combined compute shader for all buffers");
1979*35238bceSAndroid Build Coastguard Worker     tcu::TestCaseGroup *const largeGroup = new tcu::TestCaseGroup(m_testCtx, "large", "Draw shapes with large buffers");
1980*35238bceSAndroid Build Coastguard Worker 
1981*35238bceSAndroid Build Coastguard Worker     this->addChild(separateGroup);
1982*35238bceSAndroid Build Coastguard Worker     this->addChild(combinedGroup);
1983*35238bceSAndroid Build Coastguard Worker     this->addChild(largeGroup);
1984*35238bceSAndroid Build Coastguard Worker 
1985*35238bceSAndroid Build Coastguard Worker     // .separate
1986*35238bceSAndroid Build Coastguard Worker     {
1987*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
1988*35238bceSAndroid Build Coastguard Worker             m_context, "drawarrays_compute_cmd", "Command from compute shader",
1989*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, true, false, false, gridSize, 1));
1990*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
1991*35238bceSAndroid Build Coastguard Worker             m_context, "drawarrays_compute_data", "Data from compute shader",
1992*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, false, true, false, gridSize, 1));
1993*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
1994*35238bceSAndroid Build Coastguard Worker             m_context, "drawarrays_compute_cmd_and_data", "Command and data from compute shader",
1995*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, true, true, false, gridSize, 1));
1996*35238bceSAndroid Build Coastguard Worker 
1997*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
1998*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd", "Command from compute shader",
1999*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, false, false, gridSize, 1));
2000*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2001*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_data", "Data from compute shader",
2002*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, false, true, false, gridSize, 1));
2003*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2004*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_indices", "Indices from compute shader",
2005*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, false, false, true, gridSize, 1));
2006*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2007*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_data", "Command and data from compute shader",
2008*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, true, false, gridSize, 1));
2009*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2010*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_indices", "Command and indices from compute shader",
2011*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, false, true, gridSize, 1));
2012*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2013*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_data_and_indices", "Data and indices from compute shader",
2014*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, false, true, true, gridSize, 1));
2015*35238bceSAndroid Build Coastguard Worker         separateGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2016*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_data_and_indices", "Command, data and indices from compute shader",
2017*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, true, true, gridSize, 1));
2018*35238bceSAndroid Build Coastguard Worker     }
2019*35238bceSAndroid Build Coastguard Worker 
2020*35238bceSAndroid Build Coastguard Worker     // .combined
2021*35238bceSAndroid Build Coastguard Worker     {
2022*35238bceSAndroid Build Coastguard Worker         combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2023*35238bceSAndroid Build Coastguard Worker             m_context, "drawarrays_compute_cmd_and_data", "Command and data from compute shader",
2024*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, true, true, false, gridSize, 1));
2025*35238bceSAndroid Build Coastguard Worker         combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2026*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_data", "Command and data from compute shader",
2027*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, true, false, gridSize, 1));
2028*35238bceSAndroid Build Coastguard Worker         combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2029*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_indices", "Command and indices from compute shader",
2030*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, false, true, gridSize, 1));
2031*35238bceSAndroid Build Coastguard Worker         combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2032*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_data_and_indices", "Data and indices from compute shader",
2033*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, false, true, true, gridSize, 1));
2034*35238bceSAndroid Build Coastguard Worker         combinedGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2035*35238bceSAndroid Build Coastguard Worker             m_context, "drawelements_compute_cmd_and_data_and_indices", "Command, data and indices from compute shader",
2036*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true, true, true, gridSize, 1));
2037*35238bceSAndroid Build Coastguard Worker     }
2038*35238bceSAndroid Build Coastguard Worker 
2039*35238bceSAndroid Build Coastguard Worker     // .large
2040*35238bceSAndroid Build Coastguard Worker     {
2041*35238bceSAndroid Build Coastguard Worker         struct TestSpec
2042*35238bceSAndroid Build Coastguard Worker         {
2043*35238bceSAndroid Build Coastguard Worker             int gridSize;
2044*35238bceSAndroid Build Coastguard Worker             int numDrawCommands;
2045*35238bceSAndroid Build Coastguard Worker         };
2046*35238bceSAndroid Build Coastguard Worker         struct TestMethod
2047*35238bceSAndroid Build Coastguard Worker         {
2048*35238bceSAndroid Build Coastguard Worker             ComputeShaderGeneratedCase::DrawMethod method;
2049*35238bceSAndroid Build Coastguard Worker             bool separateCompute;
2050*35238bceSAndroid Build Coastguard Worker         };
2051*35238bceSAndroid Build Coastguard Worker 
2052*35238bceSAndroid Build Coastguard Worker         static const TestSpec specs[] = {
2053*35238bceSAndroid Build Coastguard Worker             {100, 1},  // !< drawArrays array size ~ 1.9 MB
2054*35238bceSAndroid Build Coastguard Worker             {200, 1},  // !< drawArrays array size ~ 7.7 MB
2055*35238bceSAndroid Build Coastguard Worker             {500, 1},  // !< drawArrays array size ~ 48 MB
2056*35238bceSAndroid Build Coastguard Worker             {1000, 1}, // !< drawArrays array size ~ 192 MB
2057*35238bceSAndroid Build Coastguard Worker             {1200, 1}, // !< drawArrays array size ~ 277 MB
2058*35238bceSAndroid Build Coastguard Worker             {1500, 1}, // !< drawArrays array size ~ 430 MB
2059*35238bceSAndroid Build Coastguard Worker 
2060*35238bceSAndroid Build Coastguard Worker             {100, 8},  // !< drawArrays array size ~ 1.9 MB
2061*35238bceSAndroid Build Coastguard Worker             {200, 8},  // !< drawArrays array size ~ 7.7 MB
2062*35238bceSAndroid Build Coastguard Worker             {500, 8},  // !< drawArrays array size ~ 48 MB
2063*35238bceSAndroid Build Coastguard Worker             {1000, 8}, // !< drawArrays array size ~ 192 MB
2064*35238bceSAndroid Build Coastguard Worker             {1200, 8}, // !< drawArrays array size ~ 277 MB
2065*35238bceSAndroid Build Coastguard Worker             {1500, 8}, // !< drawArrays array size ~ 430 MB
2066*35238bceSAndroid Build Coastguard Worker 
2067*35238bceSAndroid Build Coastguard Worker             {100, 200},   // !< 50 cells per draw call
2068*35238bceSAndroid Build Coastguard Worker             {200, 800},   // !< 50 cells per draw call
2069*35238bceSAndroid Build Coastguard Worker             {500, 2500},  // !< 100 cells per draw call
2070*35238bceSAndroid Build Coastguard Worker             {1000, 5000}, // !< 250 cells per draw call
2071*35238bceSAndroid Build Coastguard Worker         };
2072*35238bceSAndroid Build Coastguard Worker         static const TestMethod methods[] = {
2073*35238bceSAndroid Build Coastguard Worker             {ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, true},
2074*35238bceSAndroid Build Coastguard Worker             {ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS, false},
2075*35238bceSAndroid Build Coastguard Worker             {ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, true},
2076*35238bceSAndroid Build Coastguard Worker             {ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS, false},
2077*35238bceSAndroid Build Coastguard Worker         };
2078*35238bceSAndroid Build Coastguard Worker 
2079*35238bceSAndroid Build Coastguard Worker         for (int methodNdx = 0; methodNdx < DE_LENGTH_OF_ARRAY(methods); ++methodNdx)
2080*35238bceSAndroid Build Coastguard Worker             for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); ++specNdx)
2081*35238bceSAndroid Build Coastguard Worker             {
2082*35238bceSAndroid Build Coastguard Worker                 const std::string name =
2083*35238bceSAndroid Build Coastguard Worker                     std::string("") +
2084*35238bceSAndroid Build Coastguard Worker                     ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ?
2085*35238bceSAndroid Build Coastguard Worker                          ("drawarrays") :
2086*35238bceSAndroid Build Coastguard Worker                          ("drawelements")) +
2087*35238bceSAndroid Build Coastguard Worker                     ((methods[methodNdx].separateCompute) ? ("_separate") : ("_combined")) + "_grid_" +
2088*35238bceSAndroid Build Coastguard Worker                     de::toString(specs[specNdx].gridSize) + "x" + de::toString(specs[specNdx].gridSize) +
2089*35238bceSAndroid Build Coastguard Worker                     "_drawcount_" + de::toString(specs[specNdx].numDrawCommands);
2090*35238bceSAndroid Build Coastguard Worker 
2091*35238bceSAndroid Build Coastguard Worker                 const std::string desc =
2092*35238bceSAndroid Build Coastguard Worker                     std::string("Draw grid with ") +
2093*35238bceSAndroid Build Coastguard Worker                     ((methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWARRAYS) ?
2094*35238bceSAndroid Build Coastguard Worker                          ("drawarrays indirect") :
2095*35238bceSAndroid Build Coastguard Worker                          ("drawelements indirect")) +
2096*35238bceSAndroid Build Coastguard Worker                     " calculating buffers in " + ((methods[methodNdx].separateCompute) ? ("separate") : ("combined")) +
2097*35238bceSAndroid Build Coastguard Worker                     " compute shader." + " Grid size is " + de::toString(specs[specNdx].gridSize) + "x" +
2098*35238bceSAndroid Build Coastguard Worker                     de::toString(specs[specNdx].gridSize) + ", draw count is " +
2099*35238bceSAndroid Build Coastguard Worker                     de::toString(specs[specNdx].numDrawCommands);
2100*35238bceSAndroid Build Coastguard Worker 
2101*35238bceSAndroid Build Coastguard Worker                 const bool computeIndices =
2102*35238bceSAndroid Build Coastguard Worker                     (methods[methodNdx].method == ComputeShaderGeneratedCase::DRAWMETHOD_DRAWELEMENTS);
2103*35238bceSAndroid Build Coastguard Worker 
2104*35238bceSAndroid Build Coastguard Worker                 if (methods[methodNdx].separateCompute)
2105*35238bceSAndroid Build Coastguard Worker                     largeGroup->addChild(new ComputeShaderGeneratedSeparateCase(
2106*35238bceSAndroid Build Coastguard Worker                         m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices,
2107*35238bceSAndroid Build Coastguard Worker                         specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
2108*35238bceSAndroid Build Coastguard Worker                 else
2109*35238bceSAndroid Build Coastguard Worker                     largeGroup->addChild(new ComputeShaderGeneratedCombinedCase(
2110*35238bceSAndroid Build Coastguard Worker                         m_context, name.c_str(), desc.c_str(), methods[methodNdx].method, false, true, computeIndices,
2111*35238bceSAndroid Build Coastguard Worker                         specs[specNdx].gridSize, specs[specNdx].numDrawCommands));
2112*35238bceSAndroid Build Coastguard Worker             }
2113*35238bceSAndroid Build Coastguard Worker     }
2114*35238bceSAndroid Build Coastguard Worker }
2115*35238bceSAndroid Build Coastguard Worker 
2116*35238bceSAndroid Build Coastguard Worker class RandomGroup : public TestCaseGroup
2117*35238bceSAndroid Build Coastguard Worker {
2118*35238bceSAndroid Build Coastguard Worker public:
2119*35238bceSAndroid Build Coastguard Worker     RandomGroup(Context &context, const char *name, const char *descr);
2120*35238bceSAndroid Build Coastguard Worker     ~RandomGroup(void);
2121*35238bceSAndroid Build Coastguard Worker 
2122*35238bceSAndroid Build Coastguard Worker     void init(void);
2123*35238bceSAndroid Build Coastguard Worker };
2124*35238bceSAndroid Build Coastguard Worker 
2125*35238bceSAndroid Build Coastguard Worker template <int SIZE>
2126*35238bceSAndroid Build Coastguard Worker struct UniformWeightArray
2127*35238bceSAndroid Build Coastguard Worker {
2128*35238bceSAndroid Build Coastguard Worker     float weights[SIZE];
2129*35238bceSAndroid Build Coastguard Worker 
UniformWeightArraydeqp::gles31::Functional::__anone7c694fc0111::UniformWeightArray2130*35238bceSAndroid Build Coastguard Worker     UniformWeightArray(void)
2131*35238bceSAndroid Build Coastguard Worker     {
2132*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < SIZE; ++i)
2133*35238bceSAndroid Build Coastguard Worker             weights[i] = 1.0f;
2134*35238bceSAndroid Build Coastguard Worker     }
2135*35238bceSAndroid Build Coastguard Worker };
2136*35238bceSAndroid Build Coastguard Worker 
RandomGroup(Context & context,const char * name,const char * descr)2137*35238bceSAndroid Build Coastguard Worker RandomGroup::RandomGroup(Context &context, const char *name, const char *descr) : TestCaseGroup(context, name, descr)
2138*35238bceSAndroid Build Coastguard Worker {
2139*35238bceSAndroid Build Coastguard Worker }
2140*35238bceSAndroid Build Coastguard Worker 
~RandomGroup(void)2141*35238bceSAndroid Build Coastguard Worker RandomGroup::~RandomGroup(void)
2142*35238bceSAndroid Build Coastguard Worker {
2143*35238bceSAndroid Build Coastguard Worker }
2144*35238bceSAndroid Build Coastguard Worker 
init(void)2145*35238bceSAndroid Build Coastguard Worker void RandomGroup::init(void)
2146*35238bceSAndroid Build Coastguard Worker {
2147*35238bceSAndroid Build Coastguard Worker     const int numAttempts = 100;
2148*35238bceSAndroid Build Coastguard Worker 
2149*35238bceSAndroid Build Coastguard Worker     const int attribCounts[]            = {1, 2, 5};
2150*35238bceSAndroid Build Coastguard Worker     const float attribWeights[]         = {30, 10, 1};
2151*35238bceSAndroid Build Coastguard Worker     const int primitiveCounts[]         = {1, 5, 64};
2152*35238bceSAndroid Build Coastguard Worker     const float primitiveCountWeights[] = {20, 10, 1};
2153*35238bceSAndroid Build Coastguard Worker     const int indexOffsets[]            = {0, 7, 13};
2154*35238bceSAndroid Build Coastguard Worker     const float indexOffsetWeights[]    = {20, 20, 1};
2155*35238bceSAndroid Build Coastguard Worker     const int firsts[]                  = {0, 7, 13};
2156*35238bceSAndroid Build Coastguard Worker     const float firstWeights[]          = {20, 20, 1};
2157*35238bceSAndroid Build Coastguard Worker 
2158*35238bceSAndroid Build Coastguard Worker     const int instanceCounts[]           = {1, 2, 16, 17};
2159*35238bceSAndroid Build Coastguard Worker     const float instanceWeights[]        = {20, 10, 5, 1};
2160*35238bceSAndroid Build Coastguard Worker     const int indexMins[]                = {0, 1, 3, 8};
2161*35238bceSAndroid Build Coastguard Worker     const int indexMaxs[]                = {4, 8, 128, 257};
2162*35238bceSAndroid Build Coastguard Worker     const float indexWeights[]           = {50, 50, 50, 50};
2163*35238bceSAndroid Build Coastguard Worker     const int offsets[]                  = {0, 1, 5, 12};
2164*35238bceSAndroid Build Coastguard Worker     const float offsetWeights[]          = {50, 10, 10, 10};
2165*35238bceSAndroid Build Coastguard Worker     const int strides[]                  = {0, 7, 16, 17};
2166*35238bceSAndroid Build Coastguard Worker     const float strideWeights[]          = {50, 10, 10, 10};
2167*35238bceSAndroid Build Coastguard Worker     const int instanceDivisors[]         = {0, 1, 3, 129};
2168*35238bceSAndroid Build Coastguard Worker     const float instanceDivisorWeights[] = {70, 30, 10, 10};
2169*35238bceSAndroid Build Coastguard Worker 
2170*35238bceSAndroid Build Coastguard Worker     const int indirectOffsets[]         = {0, 1, 2};
2171*35238bceSAndroid Build Coastguard Worker     const float indirectOffsetWeigths[] = {2, 1, 1};
2172*35238bceSAndroid Build Coastguard Worker     const int baseVertices[]            = {0, 1, -2, 4, 3};
2173*35238bceSAndroid Build Coastguard Worker     const float baseVertexWeigths[]     = {4, 1, 1, 1, 1};
2174*35238bceSAndroid Build Coastguard Worker 
2175*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::Primitive primitives[] = {
2176*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_POINTS,       gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
2177*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN, gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
2178*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_LINES,        gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
2179*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::PRIMITIVE_LINE_LOOP};
2180*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(primitives)> primitiveWeights;
2181*35238bceSAndroid Build Coastguard Worker 
2182*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::DrawMethod drawMethods[] = {
2183*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
2184*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
2185*35238bceSAndroid Build Coastguard Worker     };
2186*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(drawMethods)> drawMethodWeights;
2187*35238bceSAndroid Build Coastguard Worker 
2188*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::IndexType indexTypes[] = {
2189*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INDEXTYPE_BYTE,
2190*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INDEXTYPE_SHORT,
2191*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INDEXTYPE_INT,
2192*35238bceSAndroid Build Coastguard Worker     };
2193*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(indexTypes)> indexTypeWeights;
2194*35238bceSAndroid Build Coastguard Worker 
2195*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::InputType inputTypes[] = {
2196*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_FLOAT,
2197*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_FIXED,
2198*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_BYTE,
2199*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_SHORT,
2200*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_UNSIGNED_BYTE,
2201*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_UNSIGNED_SHORT,
2202*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_INT,
2203*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT,
2204*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_HALF,
2205*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT_2_10_10_10,
2206*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::INPUTTYPE_INT_2_10_10_10,
2207*35238bceSAndroid Build Coastguard Worker     };
2208*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(inputTypes)> inputTypeWeights;
2209*35238bceSAndroid Build Coastguard Worker 
2210*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::OutputType outputTypes[] = {
2211*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::OUTPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2,  gls::DrawTestSpec::OUTPUTTYPE_VEC3,
2212*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::OUTPUTTYPE_VEC4,  gls::DrawTestSpec::OUTPUTTYPE_INT,   gls::DrawTestSpec::OUTPUTTYPE_UINT,
2213*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::OUTPUTTYPE_IVEC2, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, gls::DrawTestSpec::OUTPUTTYPE_IVEC4,
2214*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::OUTPUTTYPE_UVEC2, gls::DrawTestSpec::OUTPUTTYPE_UVEC3, gls::DrawTestSpec::OUTPUTTYPE_UVEC4,
2215*35238bceSAndroid Build Coastguard Worker     };
2216*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(outputTypes)> outputTypeWeights;
2217*35238bceSAndroid Build Coastguard Worker 
2218*35238bceSAndroid Build Coastguard Worker     gls::DrawTestSpec::Usage usages[] = {
2219*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::USAGE_DYNAMIC_DRAW, gls::DrawTestSpec::USAGE_STATIC_DRAW,
2220*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::USAGE_STREAM_DRAW,  gls::DrawTestSpec::USAGE_STREAM_READ,
2221*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::USAGE_STREAM_COPY,  gls::DrawTestSpec::USAGE_STATIC_READ,
2222*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::USAGE_STATIC_COPY,  gls::DrawTestSpec::USAGE_DYNAMIC_READ,
2223*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec::USAGE_DYNAMIC_COPY,
2224*35238bceSAndroid Build Coastguard Worker     };
2225*35238bceSAndroid Build Coastguard Worker     const UniformWeightArray<DE_LENGTH_OF_ARRAY(usages)> usageWeights;
2226*35238bceSAndroid Build Coastguard Worker 
2227*35238bceSAndroid Build Coastguard Worker     std::set<uint32_t> insertedHashes;
2228*35238bceSAndroid Build Coastguard Worker     size_t insertedCount         = 0;
2229*35238bceSAndroid Build Coastguard Worker     glu::ContextType contextType = m_context.getRenderContext().getType();
2230*35238bceSAndroid Build Coastguard Worker     glu::ApiType apiType         = glu::isContextTypeES(contextType) ? glu::ApiType::es(3, 1) : contextType.getAPI();
2231*35238bceSAndroid Build Coastguard Worker 
2232*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numAttempts; ++ndx)
2233*35238bceSAndroid Build Coastguard Worker     {
2234*35238bceSAndroid Build Coastguard Worker         de::Random random(0xc551393 + ndx); // random does not depend on previous cases
2235*35238bceSAndroid Build Coastguard Worker 
2236*35238bceSAndroid Build Coastguard Worker         int attributeCount = random.chooseWeighted<int, const int *, const float *>(
2237*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(attribCounts), DE_ARRAY_END(attribCounts), attribWeights);
2238*35238bceSAndroid Build Coastguard Worker         int drawCommandSize;
2239*35238bceSAndroid Build Coastguard Worker         gls::DrawTestSpec spec;
2240*35238bceSAndroid Build Coastguard Worker 
2241*35238bceSAndroid Build Coastguard Worker         spec.apiType   = apiType;
2242*35238bceSAndroid Build Coastguard Worker         spec.primitive = random.chooseWeighted<gls::DrawTestSpec::Primitive>(
2243*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(primitives), DE_ARRAY_END(primitives), primitiveWeights.weights);
2244*35238bceSAndroid Build Coastguard Worker         spec.primitiveCount = random.chooseWeighted<int, const int *, const float *>(
2245*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(primitiveCounts), DE_ARRAY_END(primitiveCounts), primitiveCountWeights);
2246*35238bceSAndroid Build Coastguard Worker         spec.drawMethod = random.chooseWeighted<gls::DrawTestSpec::DrawMethod>(
2247*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(drawMethods), DE_ARRAY_END(drawMethods), drawMethodWeights.weights);
2248*35238bceSAndroid Build Coastguard Worker 
2249*35238bceSAndroid Build Coastguard Worker         if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT)
2250*35238bceSAndroid Build Coastguard Worker             drawCommandSize = sizeof(uint32_t[4]);
2251*35238bceSAndroid Build Coastguard Worker         else if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT)
2252*35238bceSAndroid Build Coastguard Worker             drawCommandSize = sizeof(uint32_t[5]);
2253*35238bceSAndroid Build Coastguard Worker         else
2254*35238bceSAndroid Build Coastguard Worker         {
2255*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
2256*35238bceSAndroid Build Coastguard Worker             return;
2257*35238bceSAndroid Build Coastguard Worker         }
2258*35238bceSAndroid Build Coastguard Worker 
2259*35238bceSAndroid Build Coastguard Worker         spec.indexType = random.chooseWeighted<gls::DrawTestSpec::IndexType>(
2260*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(indexTypes), DE_ARRAY_END(indexTypes), indexTypeWeights.weights);
2261*35238bceSAndroid Build Coastguard Worker         spec.indexPointerOffset = random.chooseWeighted<int, const int *, const float *>(
2262*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(indexOffsets), DE_ARRAY_END(indexOffsets), indexOffsetWeights);
2263*35238bceSAndroid Build Coastguard Worker         spec.indexStorage  = gls::DrawTestSpec::STORAGE_BUFFER;
2264*35238bceSAndroid Build Coastguard Worker         spec.first         = random.chooseWeighted<int, const int *, const float *>(DE_ARRAY_BEGIN(firsts),
2265*35238bceSAndroid Build Coastguard Worker                                                                             DE_ARRAY_END(firsts), firstWeights);
2266*35238bceSAndroid Build Coastguard Worker         spec.indexMin      = random.chooseWeighted<int, const int *, const float *>(DE_ARRAY_BEGIN(indexMins),
2267*35238bceSAndroid Build Coastguard Worker                                                                                DE_ARRAY_END(indexMins), indexWeights);
2268*35238bceSAndroid Build Coastguard Worker         spec.indexMax      = random.chooseWeighted<int, const int *, const float *>(DE_ARRAY_BEGIN(indexMaxs),
2269*35238bceSAndroid Build Coastguard Worker                                                                                DE_ARRAY_END(indexMaxs), indexWeights);
2270*35238bceSAndroid Build Coastguard Worker         spec.instanceCount = random.chooseWeighted<int, const int *, const float *>(
2271*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(instanceCounts), DE_ARRAY_END(instanceCounts), instanceWeights);
2272*35238bceSAndroid Build Coastguard Worker         spec.indirectOffset = random.chooseWeighted<int, const int *, const float *>(DE_ARRAY_BEGIN(indirectOffsets),
2273*35238bceSAndroid Build Coastguard Worker                                                                                      DE_ARRAY_END(indirectOffsets),
2274*35238bceSAndroid Build Coastguard Worker                                                                                      indirectOffsetWeigths) *
2275*35238bceSAndroid Build Coastguard Worker                               drawCommandSize;
2276*35238bceSAndroid Build Coastguard Worker         spec.baseVertex = random.chooseWeighted<int, const int *, const float *>(
2277*35238bceSAndroid Build Coastguard Worker             DE_ARRAY_BEGIN(baseVertices), DE_ARRAY_END(baseVertices), baseVertexWeigths);
2278*35238bceSAndroid Build Coastguard Worker 
2279*35238bceSAndroid Build Coastguard Worker         // check spec is legal
2280*35238bceSAndroid Build Coastguard Worker         if (!spec.valid())
2281*35238bceSAndroid Build Coastguard Worker             continue;
2282*35238bceSAndroid Build Coastguard Worker 
2283*35238bceSAndroid Build Coastguard Worker         for (int attrNdx = 0; attrNdx < attributeCount;)
2284*35238bceSAndroid Build Coastguard Worker         {
2285*35238bceSAndroid Build Coastguard Worker             bool valid;
2286*35238bceSAndroid Build Coastguard Worker             gls::DrawTestSpec::AttributeSpec attribSpec;
2287*35238bceSAndroid Build Coastguard Worker 
2288*35238bceSAndroid Build Coastguard Worker             attribSpec.inputType = random.chooseWeighted<gls::DrawTestSpec::InputType>(
2289*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(inputTypes), DE_ARRAY_END(inputTypes), inputTypeWeights.weights);
2290*35238bceSAndroid Build Coastguard Worker             attribSpec.outputType = random.chooseWeighted<gls::DrawTestSpec::OutputType>(
2291*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(outputTypes), DE_ARRAY_END(outputTypes), outputTypeWeights.weights);
2292*35238bceSAndroid Build Coastguard Worker             attribSpec.storage = gls::DrawTestSpec::STORAGE_BUFFER;
2293*35238bceSAndroid Build Coastguard Worker             attribSpec.usage   = random.chooseWeighted<gls::DrawTestSpec::Usage>(
2294*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(usages), DE_ARRAY_END(usages), usageWeights.weights);
2295*35238bceSAndroid Build Coastguard Worker             attribSpec.componentCount = random.getInt(1, 4);
2296*35238bceSAndroid Build Coastguard Worker             attribSpec.offset         = random.chooseWeighted<int, const int *, const float *>(
2297*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), offsetWeights);
2298*35238bceSAndroid Build Coastguard Worker             attribSpec.stride = random.chooseWeighted<int, const int *, const float *>(
2299*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(strides), DE_ARRAY_END(strides), strideWeights);
2300*35238bceSAndroid Build Coastguard Worker             attribSpec.normalize       = random.getBool();
2301*35238bceSAndroid Build Coastguard Worker             attribSpec.instanceDivisor = random.chooseWeighted<int, const int *, const float *>(
2302*35238bceSAndroid Build Coastguard Worker                 DE_ARRAY_BEGIN(instanceDivisors), DE_ARRAY_END(instanceDivisors), instanceDivisorWeights);
2303*35238bceSAndroid Build Coastguard Worker             attribSpec.useDefaultAttribute = random.getBool();
2304*35238bceSAndroid Build Coastguard Worker 
2305*35238bceSAndroid Build Coastguard Worker             // check spec is legal
2306*35238bceSAndroid Build Coastguard Worker             valid = attribSpec.valid(spec.apiType);
2307*35238bceSAndroid Build Coastguard Worker 
2308*35238bceSAndroid Build Coastguard Worker             // we do not want interleaved elements. (Might result in some weird floating point values)
2309*35238bceSAndroid Build Coastguard Worker             if (attribSpec.stride &&
2310*35238bceSAndroid Build Coastguard Worker                 attribSpec.componentCount * gls::DrawTestSpec::inputTypeSize(attribSpec.inputType) > attribSpec.stride)
2311*35238bceSAndroid Build Coastguard Worker                 valid = false;
2312*35238bceSAndroid Build Coastguard Worker 
2313*35238bceSAndroid Build Coastguard Worker             // try again if not valid
2314*35238bceSAndroid Build Coastguard Worker             if (valid)
2315*35238bceSAndroid Build Coastguard Worker             {
2316*35238bceSAndroid Build Coastguard Worker                 spec.attribs.push_back(attribSpec);
2317*35238bceSAndroid Build Coastguard Worker                 ++attrNdx;
2318*35238bceSAndroid Build Coastguard Worker             }
2319*35238bceSAndroid Build Coastguard Worker         }
2320*35238bceSAndroid Build Coastguard Worker 
2321*35238bceSAndroid Build Coastguard Worker         // Do not collapse all vertex positions to a single positions
2322*35238bceSAndroid Build Coastguard Worker         if (spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
2323*35238bceSAndroid Build Coastguard Worker             spec.attribs[0].instanceDivisor = 0;
2324*35238bceSAndroid Build Coastguard Worker 
2325*35238bceSAndroid Build Coastguard Worker         // Is render result meaningful?
2326*35238bceSAndroid Build Coastguard Worker         {
2327*35238bceSAndroid Build Coastguard Worker             // Only one vertex
2328*35238bceSAndroid Build Coastguard Worker             if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED &&
2329*35238bceSAndroid Build Coastguard Worker                 spec.indexMin == spec.indexMax && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
2330*35238bceSAndroid Build Coastguard Worker                 continue;
2331*35238bceSAndroid Build Coastguard Worker             if (spec.attribs[0].useDefaultAttribute && spec.primitive != gls::DrawTestSpec::PRIMITIVE_POINTS)
2332*35238bceSAndroid Build Coastguard Worker                 continue;
2333*35238bceSAndroid Build Coastguard Worker 
2334*35238bceSAndroid Build Coastguard Worker             // Triangle only on one axis
2335*35238bceSAndroid Build Coastguard Worker             if (spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLES ||
2336*35238bceSAndroid Build Coastguard Worker                 spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN ||
2337*35238bceSAndroid Build Coastguard Worker                 spec.primitive == gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP)
2338*35238bceSAndroid Build Coastguard Worker             {
2339*35238bceSAndroid Build Coastguard Worker                 if (spec.attribs[0].componentCount == 1)
2340*35238bceSAndroid Build Coastguard Worker                     continue;
2341*35238bceSAndroid Build Coastguard Worker                 if (spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_FLOAT ||
2342*35238bceSAndroid Build Coastguard Worker                     spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_INT ||
2343*35238bceSAndroid Build Coastguard Worker                     spec.attribs[0].outputType == gls::DrawTestSpec::OUTPUTTYPE_UINT)
2344*35238bceSAndroid Build Coastguard Worker                     continue;
2345*35238bceSAndroid Build Coastguard Worker                 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED &&
2346*35238bceSAndroid Build Coastguard Worker                     (spec.indexMax - spec.indexMin) < 2)
2347*35238bceSAndroid Build Coastguard Worker                     continue;
2348*35238bceSAndroid Build Coastguard Worker             }
2349*35238bceSAndroid Build Coastguard Worker         }
2350*35238bceSAndroid Build Coastguard Worker 
2351*35238bceSAndroid Build Coastguard Worker         // Add case
2352*35238bceSAndroid Build Coastguard Worker         {
2353*35238bceSAndroid Build Coastguard Worker             uint32_t hash = spec.hash();
2354*35238bceSAndroid Build Coastguard Worker             for (int attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
2355*35238bceSAndroid Build Coastguard Worker                 hash = (hash << 2) ^ (uint32_t)spec.attribs[attrNdx].hash();
2356*35238bceSAndroid Build Coastguard Worker 
2357*35238bceSAndroid Build Coastguard Worker             if (insertedHashes.find(hash) == insertedHashes.end())
2358*35238bceSAndroid Build Coastguard Worker             {
2359*35238bceSAndroid Build Coastguard Worker                 // Only aligned cases
2360*35238bceSAndroid Build Coastguard Worker                 if (spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_OFFSET &&
2361*35238bceSAndroid Build Coastguard Worker                     spec.isCompatibilityTest() != gls::DrawTestSpec::COMPATIBILITY_UNALIGNED_STRIDE)
2362*35238bceSAndroid Build Coastguard Worker                     this->addChild(new gls::DrawTest(m_testCtx, m_context.getRenderContext(), spec,
2363*35238bceSAndroid Build Coastguard Worker                                                      de::toString(insertedCount).c_str(), spec.getDesc().c_str()));
2364*35238bceSAndroid Build Coastguard Worker                 insertedHashes.insert(hash);
2365*35238bceSAndroid Build Coastguard Worker 
2366*35238bceSAndroid Build Coastguard Worker                 ++insertedCount;
2367*35238bceSAndroid Build Coastguard Worker             }
2368*35238bceSAndroid Build Coastguard Worker         }
2369*35238bceSAndroid Build Coastguard Worker     }
2370*35238bceSAndroid Build Coastguard Worker }
2371*35238bceSAndroid Build Coastguard Worker 
2372*35238bceSAndroid Build Coastguard Worker class BadCommandBufferCase : public TestCase
2373*35238bceSAndroid Build Coastguard Worker {
2374*35238bceSAndroid Build Coastguard Worker public:
2375*35238bceSAndroid Build Coastguard Worker     enum
2376*35238bceSAndroid Build Coastguard Worker     {
2377*35238bceSAndroid Build Coastguard Worker         CommandSize = 20
2378*35238bceSAndroid Build Coastguard Worker     };
2379*35238bceSAndroid Build Coastguard Worker 
2380*35238bceSAndroid Build Coastguard Worker     BadCommandBufferCase(Context &context, const char *name, const char *desc, uint32_t alignment, uint32_t bufferSize,
2381*35238bceSAndroid Build Coastguard Worker                          bool writeCommandToBuffer, uint32_t m_expectedError);
2382*35238bceSAndroid Build Coastguard Worker     ~BadCommandBufferCase(void);
2383*35238bceSAndroid Build Coastguard Worker 
2384*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2385*35238bceSAndroid Build Coastguard Worker 
2386*35238bceSAndroid Build Coastguard Worker private:
2387*35238bceSAndroid Build Coastguard Worker     const uint32_t m_alignment;
2388*35238bceSAndroid Build Coastguard Worker     const uint32_t m_bufferSize;
2389*35238bceSAndroid Build Coastguard Worker     const bool m_writeCommandToBuffer;
2390*35238bceSAndroid Build Coastguard Worker     const uint32_t m_expectedError;
2391*35238bceSAndroid Build Coastguard Worker };
2392*35238bceSAndroid Build Coastguard Worker 
BadCommandBufferCase(Context & context,const char * name,const char * desc,uint32_t alignment,uint32_t bufferSize,bool writeCommandToBuffer,uint32_t expectedError)2393*35238bceSAndroid Build Coastguard Worker BadCommandBufferCase::BadCommandBufferCase(Context &context, const char *name, const char *desc, uint32_t alignment,
2394*35238bceSAndroid Build Coastguard Worker                                            uint32_t bufferSize, bool writeCommandToBuffer, uint32_t expectedError)
2395*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2396*35238bceSAndroid Build Coastguard Worker     , m_alignment(alignment)
2397*35238bceSAndroid Build Coastguard Worker     , m_bufferSize(bufferSize)
2398*35238bceSAndroid Build Coastguard Worker     , m_writeCommandToBuffer(writeCommandToBuffer)
2399*35238bceSAndroid Build Coastguard Worker     , m_expectedError(expectedError)
2400*35238bceSAndroid Build Coastguard Worker {
2401*35238bceSAndroid Build Coastguard Worker }
2402*35238bceSAndroid Build Coastguard Worker 
~BadCommandBufferCase(void)2403*35238bceSAndroid Build Coastguard Worker BadCommandBufferCase::~BadCommandBufferCase(void)
2404*35238bceSAndroid Build Coastguard Worker {
2405*35238bceSAndroid Build Coastguard Worker }
2406*35238bceSAndroid Build Coastguard Worker 
iterate(void)2407*35238bceSAndroid Build Coastguard Worker BadCommandBufferCase::IterateResult BadCommandBufferCase::iterate(void)
2408*35238bceSAndroid Build Coastguard Worker {
2409*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexPositions[] = {
2410*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0, 0, 0, 1),
2411*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1, 0, 0, 1),
2412*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0, 1, 0, 1),
2413*35238bceSAndroid Build Coastguard Worker     };
2414*35238bceSAndroid Build Coastguard Worker 
2415*35238bceSAndroid Build Coastguard Worker     const uint16_t indices[] = {
2416*35238bceSAndroid Build Coastguard Worker         0,
2417*35238bceSAndroid Build Coastguard Worker         2,
2418*35238bceSAndroid Build Coastguard Worker         1,
2419*35238bceSAndroid Build Coastguard Worker     };
2420*35238bceSAndroid Build Coastguard Worker 
2421*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(CommandSize == sizeof(DrawElementsCommand));
2422*35238bceSAndroid Build Coastguard Worker 
2423*35238bceSAndroid Build Coastguard Worker     sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS,
2424*35238bceSAndroid Build Coastguard Worker                        tcu::IVec4(0, 0, 1, 1));
2425*35238bceSAndroid Build Coastguard Worker 
2426*35238bceSAndroid Build Coastguard Worker     uint32_t vaoID           = 0;
2427*35238bceSAndroid Build Coastguard Worker     uint32_t positionBuf     = 0;
2428*35238bceSAndroid Build Coastguard Worker     uint32_t indexBuf        = 0;
2429*35238bceSAndroid Build Coastguard Worker     uint32_t drawIndirectBuf = 0;
2430*35238bceSAndroid Build Coastguard Worker     uint32_t error;
2431*35238bceSAndroid Build Coastguard Worker 
2432*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources()
2433*35238bceSAndroid Build Coastguard Worker                                                                  << glu::VertexSource(s_commonVertexShaderSource)
2434*35238bceSAndroid Build Coastguard Worker                                                                  << glu::FragmentSource(s_commonFragmentShaderSource));
2435*35238bceSAndroid Build Coastguard Worker     uint32_t programID  = program.getProgram();
2436*35238bceSAndroid Build Coastguard Worker     int32_t posLocation = gl.getAttribLocation(programID, "a_position");
2437*35238bceSAndroid Build Coastguard Worker 
2438*35238bceSAndroid Build Coastguard Worker     DrawElementsCommand drawCommand;
2439*35238bceSAndroid Build Coastguard Worker     drawCommand.count              = 3;
2440*35238bceSAndroid Build Coastguard Worker     drawCommand.primCount          = 1;
2441*35238bceSAndroid Build Coastguard Worker     drawCommand.firstIndex         = 0;
2442*35238bceSAndroid Build Coastguard Worker     drawCommand.baseVertex         = 0;
2443*35238bceSAndroid Build Coastguard Worker     drawCommand.reservedMustBeZero = 0;
2444*35238bceSAndroid Build Coastguard Worker 
2445*35238bceSAndroid Build Coastguard Worker     std::vector<int8_t> drawCommandBuffer;
2446*35238bceSAndroid Build Coastguard Worker     drawCommandBuffer.resize(m_bufferSize);
2447*35238bceSAndroid Build Coastguard Worker 
2448*35238bceSAndroid Build Coastguard Worker     deMemset(&drawCommandBuffer[0], 0, (int)drawCommandBuffer.size());
2449*35238bceSAndroid Build Coastguard Worker 
2450*35238bceSAndroid Build Coastguard Worker     if (m_writeCommandToBuffer)
2451*35238bceSAndroid Build Coastguard Worker     {
2452*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(drawCommandBuffer.size() >= sizeof(drawCommand) + m_alignment);
2453*35238bceSAndroid Build Coastguard Worker         deMemcpy(&drawCommandBuffer[m_alignment], &drawCommand, sizeof(drawCommand));
2454*35238bceSAndroid Build Coastguard Worker     }
2455*35238bceSAndroid Build Coastguard Worker 
2456*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2457*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &vaoID);
2458*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(vaoID);
2459*35238bceSAndroid Build Coastguard Worker 
2460*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &positionBuf);
2461*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, positionBuf);
2462*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
2463*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2464*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribDivisor(posLocation, 0);
2465*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(posLocation);
2466*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2467*35238bceSAndroid Build Coastguard Worker 
2468*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &indexBuf);
2469*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
2470*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
2471*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2472*35238bceSAndroid Build Coastguard Worker 
2473*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &drawIndirectBuf);
2474*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, drawIndirectBuf);
2475*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_DRAW_INDIRECT_BUFFER, drawCommandBuffer.size(), &drawCommandBuffer[0], GL_STATIC_DRAW);
2476*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2477*35238bceSAndroid Build Coastguard Worker 
2478*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, 1, 1);
2479*35238bceSAndroid Build Coastguard Worker 
2480*35238bceSAndroid Build Coastguard Worker     gl.useProgram(programID);
2481*35238bceSAndroid Build Coastguard Worker     gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void *)(uintptr_t)m_alignment);
2482*35238bceSAndroid Build Coastguard Worker 
2483*35238bceSAndroid Build Coastguard Worker     error = gl.getError();
2484*35238bceSAndroid Build Coastguard Worker 
2485*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
2486*35238bceSAndroid Build Coastguard Worker 
2487*35238bceSAndroid Build Coastguard Worker     gl.deleteBuffers(1, &drawIndirectBuf);
2488*35238bceSAndroid Build Coastguard Worker     gl.deleteBuffers(1, &indexBuf);
2489*35238bceSAndroid Build Coastguard Worker     gl.deleteBuffers(1, &positionBuf);
2490*35238bceSAndroid Build Coastguard Worker     gl.deleteVertexArrays(1, &vaoID);
2491*35238bceSAndroid Build Coastguard Worker 
2492*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << tcu::TestLog::Message << "drawElementsIndirect generated " << glu::getErrorStr(error)
2493*35238bceSAndroid Build Coastguard Worker                        << ", expecting " << glu::getErrorStr(m_expectedError) << "." << tcu::TestLog::EndMessage;
2494*35238bceSAndroid Build Coastguard Worker 
2495*35238bceSAndroid Build Coastguard Worker     if (error == m_expectedError)
2496*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2497*35238bceSAndroid Build Coastguard Worker     else
2498*35238bceSAndroid Build Coastguard Worker     {
2499*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "\tUnexpected error." << tcu::TestLog::EndMessage;
2500*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
2501*35238bceSAndroid Build Coastguard Worker     }
2502*35238bceSAndroid Build Coastguard Worker 
2503*35238bceSAndroid Build Coastguard Worker     return STOP;
2504*35238bceSAndroid Build Coastguard Worker }
2505*35238bceSAndroid Build Coastguard Worker 
2506*35238bceSAndroid Build Coastguard Worker class BadAlignmentCase : public BadCommandBufferCase
2507*35238bceSAndroid Build Coastguard Worker {
2508*35238bceSAndroid Build Coastguard Worker public:
2509*35238bceSAndroid Build Coastguard Worker     BadAlignmentCase(Context &context, const char *name, const char *desc, uint32_t alignment);
2510*35238bceSAndroid Build Coastguard Worker     ~BadAlignmentCase(void);
2511*35238bceSAndroid Build Coastguard Worker };
2512*35238bceSAndroid Build Coastguard Worker 
BadAlignmentCase(Context & context,const char * name,const char * desc,uint32_t alignment)2513*35238bceSAndroid Build Coastguard Worker BadAlignmentCase::BadAlignmentCase(Context &context, const char *name, const char *desc, uint32_t alignment)
2514*35238bceSAndroid Build Coastguard Worker     : BadCommandBufferCase(context, name, desc, alignment, CommandSize + alignment, true, GL_INVALID_VALUE)
2515*35238bceSAndroid Build Coastguard Worker {
2516*35238bceSAndroid Build Coastguard Worker }
2517*35238bceSAndroid Build Coastguard Worker 
~BadAlignmentCase(void)2518*35238bceSAndroid Build Coastguard Worker BadAlignmentCase::~BadAlignmentCase(void)
2519*35238bceSAndroid Build Coastguard Worker {
2520*35238bceSAndroid Build Coastguard Worker }
2521*35238bceSAndroid Build Coastguard Worker 
2522*35238bceSAndroid Build Coastguard Worker class BadBufferRangeCase : public BadCommandBufferCase
2523*35238bceSAndroid Build Coastguard Worker {
2524*35238bceSAndroid Build Coastguard Worker public:
2525*35238bceSAndroid Build Coastguard Worker     BadBufferRangeCase(Context &context, const char *name, const char *desc, uint32_t offset);
2526*35238bceSAndroid Build Coastguard Worker     ~BadBufferRangeCase(void);
2527*35238bceSAndroid Build Coastguard Worker };
2528*35238bceSAndroid Build Coastguard Worker 
BadBufferRangeCase(Context & context,const char * name,const char * desc,uint32_t offset)2529*35238bceSAndroid Build Coastguard Worker BadBufferRangeCase::BadBufferRangeCase(Context &context, const char *name, const char *desc, uint32_t offset)
2530*35238bceSAndroid Build Coastguard Worker     : BadCommandBufferCase(context, name, desc, offset, CommandSize, false, GL_INVALID_OPERATION)
2531*35238bceSAndroid Build Coastguard Worker {
2532*35238bceSAndroid Build Coastguard Worker }
2533*35238bceSAndroid Build Coastguard Worker 
~BadBufferRangeCase(void)2534*35238bceSAndroid Build Coastguard Worker BadBufferRangeCase::~BadBufferRangeCase(void)
2535*35238bceSAndroid Build Coastguard Worker {
2536*35238bceSAndroid Build Coastguard Worker }
2537*35238bceSAndroid Build Coastguard Worker 
2538*35238bceSAndroid Build Coastguard Worker class BadStateCase : public TestCase
2539*35238bceSAndroid Build Coastguard Worker {
2540*35238bceSAndroid Build Coastguard Worker public:
2541*35238bceSAndroid Build Coastguard Worker     enum CaseType
2542*35238bceSAndroid Build Coastguard Worker     {
2543*35238bceSAndroid Build Coastguard Worker         CASE_CLIENT_BUFFER_VERTEXATTR = 0,
2544*35238bceSAndroid Build Coastguard Worker         CASE_CLIENT_BUFFER_COMMAND,
2545*35238bceSAndroid Build Coastguard Worker         CASE_DEFAULT_VAO,
2546*35238bceSAndroid Build Coastguard Worker 
2547*35238bceSAndroid Build Coastguard Worker         CASE_CLIENT_LAST
2548*35238bceSAndroid Build Coastguard Worker     };
2549*35238bceSAndroid Build Coastguard Worker 
2550*35238bceSAndroid Build Coastguard Worker     BadStateCase(Context &context, const char *name, const char *desc, CaseType type);
2551*35238bceSAndroid Build Coastguard Worker     ~BadStateCase(void);
2552*35238bceSAndroid Build Coastguard Worker 
2553*35238bceSAndroid Build Coastguard Worker     void init(void);
2554*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2555*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2556*35238bceSAndroid Build Coastguard Worker 
2557*35238bceSAndroid Build Coastguard Worker private:
2558*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
2559*35238bceSAndroid Build Coastguard Worker };
2560*35238bceSAndroid Build Coastguard Worker 
BadStateCase(Context & context,const char * name,const char * desc,CaseType type)2561*35238bceSAndroid Build Coastguard Worker BadStateCase::BadStateCase(Context &context, const char *name, const char *desc, CaseType type)
2562*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2563*35238bceSAndroid Build Coastguard Worker     , m_caseType(type)
2564*35238bceSAndroid Build Coastguard Worker {
2565*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(type < CASE_CLIENT_LAST);
2566*35238bceSAndroid Build Coastguard Worker }
2567*35238bceSAndroid Build Coastguard Worker 
~BadStateCase(void)2568*35238bceSAndroid Build Coastguard Worker BadStateCase::~BadStateCase(void)
2569*35238bceSAndroid Build Coastguard Worker {
2570*35238bceSAndroid Build Coastguard Worker     deinit();
2571*35238bceSAndroid Build Coastguard Worker }
2572*35238bceSAndroid Build Coastguard Worker 
init(void)2573*35238bceSAndroid Build Coastguard Worker void BadStateCase::init(void)
2574*35238bceSAndroid Build Coastguard Worker {
2575*35238bceSAndroid Build Coastguard Worker     if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
2576*35238bceSAndroid Build Coastguard Worker     {
2577*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_CLIENT_BUFFER_VERTEXATTR)
2578*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(
2579*35238bceSAndroid Build Coastguard Worker                 "The negative test for vertex attrib array in the client memory is not supported in the GL context");
2580*35238bceSAndroid Build Coastguard Worker         if (m_caseType == CASE_DEFAULT_VAO)
2581*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError(
2582*35238bceSAndroid Build Coastguard Worker                 "The negative test for use with default vao is not supported in the GL context");
2583*35238bceSAndroid Build Coastguard Worker     }
2584*35238bceSAndroid Build Coastguard Worker }
2585*35238bceSAndroid Build Coastguard Worker 
deinit(void)2586*35238bceSAndroid Build Coastguard Worker void BadStateCase::deinit(void)
2587*35238bceSAndroid Build Coastguard Worker {
2588*35238bceSAndroid Build Coastguard Worker }
2589*35238bceSAndroid Build Coastguard Worker 
iterate(void)2590*35238bceSAndroid Build Coastguard Worker BadStateCase::IterateResult BadStateCase::iterate(void)
2591*35238bceSAndroid Build Coastguard Worker {
2592*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexPositions[] = {
2593*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
2594*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2595*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2596*35238bceSAndroid Build Coastguard Worker     };
2597*35238bceSAndroid Build Coastguard Worker 
2598*35238bceSAndroid Build Coastguard Worker     const uint16_t indices[] = {
2599*35238bceSAndroid Build Coastguard Worker         0,
2600*35238bceSAndroid Build Coastguard Worker         2,
2601*35238bceSAndroid Build Coastguard Worker         1,
2602*35238bceSAndroid Build Coastguard Worker     };
2603*35238bceSAndroid Build Coastguard Worker 
2604*35238bceSAndroid Build Coastguard Worker     sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS,
2605*35238bceSAndroid Build Coastguard Worker                        tcu::IVec4(0, 0, 1, 1));
2606*35238bceSAndroid Build Coastguard Worker 
2607*35238bceSAndroid Build Coastguard Worker     uint32_t error;
2608*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources()
2609*35238bceSAndroid Build Coastguard Worker                                                                  << glu::VertexSource(s_commonVertexShaderSource)
2610*35238bceSAndroid Build Coastguard Worker                                                                  << glu::FragmentSource(s_commonFragmentShaderSource));
2611*35238bceSAndroid Build Coastguard Worker     uint32_t vaoID         = 0;
2612*35238bceSAndroid Build Coastguard Worker     uint32_t dataBufferID  = 0;
2613*35238bceSAndroid Build Coastguard Worker     uint32_t indexBufferID = 0;
2614*35238bceSAndroid Build Coastguard Worker     uint32_t cmdBufferID   = 0;
2615*35238bceSAndroid Build Coastguard Worker 
2616*35238bceSAndroid Build Coastguard Worker     const uint32_t programID  = program.getProgram();
2617*35238bceSAndroid Build Coastguard Worker     const int32_t posLocation = gl.getAttribLocation(programID, "a_position");
2618*35238bceSAndroid Build Coastguard Worker 
2619*35238bceSAndroid Build Coastguard Worker     DrawElementsCommand drawCommand;
2620*35238bceSAndroid Build Coastguard Worker     drawCommand.count              = 3;
2621*35238bceSAndroid Build Coastguard Worker     drawCommand.primCount          = 1;
2622*35238bceSAndroid Build Coastguard Worker     drawCommand.firstIndex         = 0;
2623*35238bceSAndroid Build Coastguard Worker     drawCommand.baseVertex         = 0;
2624*35238bceSAndroid Build Coastguard Worker     drawCommand.reservedMustBeZero = 0;
2625*35238bceSAndroid Build Coastguard Worker 
2626*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2627*35238bceSAndroid Build Coastguard Worker 
2628*35238bceSAndroid Build Coastguard Worker     if (m_caseType == CASE_CLIENT_BUFFER_VERTEXATTR)
2629*35238bceSAndroid Build Coastguard Worker     {
2630*35238bceSAndroid Build Coastguard Worker         // \note We use default VAO since we use client pointers. Trying indirect draw with default VAO is also an error. => This test does two illegal operations
2631*35238bceSAndroid Build Coastguard Worker 
2632*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, vertexPositions);
2633*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(posLocation);
2634*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2635*35238bceSAndroid Build Coastguard Worker     }
2636*35238bceSAndroid Build Coastguard Worker     else if (m_caseType == CASE_CLIENT_BUFFER_COMMAND)
2637*35238bceSAndroid Build Coastguard Worker     {
2638*35238bceSAndroid Build Coastguard Worker         gl.genVertexArrays(1, &vaoID);
2639*35238bceSAndroid Build Coastguard Worker         gl.bindVertexArray(vaoID);
2640*35238bceSAndroid Build Coastguard Worker 
2641*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &dataBufferID);
2642*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
2643*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
2644*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2645*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(posLocation);
2646*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2647*35238bceSAndroid Build Coastguard Worker     }
2648*35238bceSAndroid Build Coastguard Worker     else if (m_caseType == CASE_DEFAULT_VAO)
2649*35238bceSAndroid Build Coastguard Worker     {
2650*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &dataBufferID);
2651*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
2652*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
2653*35238bceSAndroid Build Coastguard Worker         gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2654*35238bceSAndroid Build Coastguard Worker         gl.enableVertexAttribArray(posLocation);
2655*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2656*35238bceSAndroid Build Coastguard Worker     }
2657*35238bceSAndroid Build Coastguard Worker     else
2658*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2659*35238bceSAndroid Build Coastguard Worker 
2660*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &indexBufferID);
2661*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
2662*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
2663*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2664*35238bceSAndroid Build Coastguard Worker 
2665*35238bceSAndroid Build Coastguard Worker     if (m_caseType != CASE_CLIENT_BUFFER_COMMAND)
2666*35238bceSAndroid Build Coastguard Worker     {
2667*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &cmdBufferID);
2668*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
2669*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
2670*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2671*35238bceSAndroid Build Coastguard Worker     }
2672*35238bceSAndroid Build Coastguard Worker 
2673*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, 1, 1);
2674*35238bceSAndroid Build Coastguard Worker 
2675*35238bceSAndroid Build Coastguard Worker     gl.useProgram(programID);
2676*35238bceSAndroid Build Coastguard Worker     gl.drawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
2677*35238bceSAndroid Build Coastguard Worker                             (m_caseType != CASE_CLIENT_BUFFER_COMMAND) ? (DE_NULL) : (&drawCommand));
2678*35238bceSAndroid Build Coastguard Worker 
2679*35238bceSAndroid Build Coastguard Worker     error = gl.getError();
2680*35238bceSAndroid Build Coastguard Worker 
2681*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(0);
2682*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
2683*35238bceSAndroid Build Coastguard Worker 
2684*35238bceSAndroid Build Coastguard Worker     if (error == GL_INVALID_OPERATION)
2685*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2686*35238bceSAndroid Build Coastguard Worker     else
2687*35238bceSAndroid Build Coastguard Worker     {
2688*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_OPERATION, got "
2689*35238bceSAndroid Build Coastguard Worker                            << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
2690*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
2691*35238bceSAndroid Build Coastguard Worker     }
2692*35238bceSAndroid Build Coastguard Worker 
2693*35238bceSAndroid Build Coastguard Worker     return STOP;
2694*35238bceSAndroid Build Coastguard Worker }
2695*35238bceSAndroid Build Coastguard Worker 
2696*35238bceSAndroid Build Coastguard Worker class BadDrawModeCase : public TestCase
2697*35238bceSAndroid Build Coastguard Worker {
2698*35238bceSAndroid Build Coastguard Worker public:
2699*35238bceSAndroid Build Coastguard Worker     enum DrawType
2700*35238bceSAndroid Build Coastguard Worker     {
2701*35238bceSAndroid Build Coastguard Worker         DRAW_ARRAYS = 0,
2702*35238bceSAndroid Build Coastguard Worker         DRAW_ELEMENTS,
2703*35238bceSAndroid Build Coastguard Worker         DRAW_ELEMENTS_BAD_INDEX,
2704*35238bceSAndroid Build Coastguard Worker 
2705*35238bceSAndroid Build Coastguard Worker         DRAW_LAST
2706*35238bceSAndroid Build Coastguard Worker     };
2707*35238bceSAndroid Build Coastguard Worker 
2708*35238bceSAndroid Build Coastguard Worker     BadDrawModeCase(Context &context, const char *name, const char *desc, DrawType type);
2709*35238bceSAndroid Build Coastguard Worker     ~BadDrawModeCase(void);
2710*35238bceSAndroid Build Coastguard Worker 
2711*35238bceSAndroid Build Coastguard Worker     void init(void);
2712*35238bceSAndroid Build Coastguard Worker     void deinit(void);
2713*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
2714*35238bceSAndroid Build Coastguard Worker 
2715*35238bceSAndroid Build Coastguard Worker private:
2716*35238bceSAndroid Build Coastguard Worker     const DrawType m_drawType;
2717*35238bceSAndroid Build Coastguard Worker };
2718*35238bceSAndroid Build Coastguard Worker 
BadDrawModeCase(Context & context,const char * name,const char * desc,DrawType type)2719*35238bceSAndroid Build Coastguard Worker BadDrawModeCase::BadDrawModeCase(Context &context, const char *name, const char *desc, DrawType type)
2720*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
2721*35238bceSAndroid Build Coastguard Worker     , m_drawType(type)
2722*35238bceSAndroid Build Coastguard Worker {
2723*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(type < DRAW_LAST);
2724*35238bceSAndroid Build Coastguard Worker }
2725*35238bceSAndroid Build Coastguard Worker 
~BadDrawModeCase(void)2726*35238bceSAndroid Build Coastguard Worker BadDrawModeCase::~BadDrawModeCase(void)
2727*35238bceSAndroid Build Coastguard Worker {
2728*35238bceSAndroid Build Coastguard Worker     deinit();
2729*35238bceSAndroid Build Coastguard Worker }
2730*35238bceSAndroid Build Coastguard Worker 
init(void)2731*35238bceSAndroid Build Coastguard Worker void BadDrawModeCase::init(void)
2732*35238bceSAndroid Build Coastguard Worker {
2733*35238bceSAndroid Build Coastguard Worker }
2734*35238bceSAndroid Build Coastguard Worker 
deinit(void)2735*35238bceSAndroid Build Coastguard Worker void BadDrawModeCase::deinit(void)
2736*35238bceSAndroid Build Coastguard Worker {
2737*35238bceSAndroid Build Coastguard Worker }
2738*35238bceSAndroid Build Coastguard Worker 
iterate(void)2739*35238bceSAndroid Build Coastguard Worker BadDrawModeCase::IterateResult BadDrawModeCase::iterate(void)
2740*35238bceSAndroid Build Coastguard Worker {
2741*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 vertexPositions[] = {
2742*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
2743*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2744*35238bceSAndroid Build Coastguard Worker         tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2745*35238bceSAndroid Build Coastguard Worker     };
2746*35238bceSAndroid Build Coastguard Worker 
2747*35238bceSAndroid Build Coastguard Worker     const uint16_t indices[] = {
2748*35238bceSAndroid Build Coastguard Worker         0,
2749*35238bceSAndroid Build Coastguard Worker         2,
2750*35238bceSAndroid Build Coastguard Worker         1,
2751*35238bceSAndroid Build Coastguard Worker     };
2752*35238bceSAndroid Build Coastguard Worker 
2753*35238bceSAndroid Build Coastguard Worker     sglr::GLContext gl(m_context.getRenderContext(), m_testCtx.getLog(), sglr::GLCONTEXT_LOG_CALLS,
2754*35238bceSAndroid Build Coastguard Worker                        tcu::IVec4(0, 0, 1, 1));
2755*35238bceSAndroid Build Coastguard Worker 
2756*35238bceSAndroid Build Coastguard Worker     uint32_t error;
2757*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(m_context.getRenderContext(), glu::ProgramSources()
2758*35238bceSAndroid Build Coastguard Worker                                                                  << glu::VertexSource(s_commonVertexShaderSource)
2759*35238bceSAndroid Build Coastguard Worker                                                                  << glu::FragmentSource(s_commonFragmentShaderSource));
2760*35238bceSAndroid Build Coastguard Worker     uint32_t vaoID         = 0;
2761*35238bceSAndroid Build Coastguard Worker     uint32_t dataBufferID  = 0;
2762*35238bceSAndroid Build Coastguard Worker     uint32_t indexBufferID = 0;
2763*35238bceSAndroid Build Coastguard Worker     uint32_t cmdBufferID   = 0;
2764*35238bceSAndroid Build Coastguard Worker 
2765*35238bceSAndroid Build Coastguard Worker     const uint32_t programID    = program.getProgram();
2766*35238bceSAndroid Build Coastguard Worker     const int32_t posLocation   = gl.getAttribLocation(programID, "a_position");
2767*35238bceSAndroid Build Coastguard Worker     const glw::GLenum mode      = (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (GL_TRIANGLES) : (0x123);
2768*35238bceSAndroid Build Coastguard Worker     const glw::GLenum indexType = (m_drawType == DRAW_ELEMENTS_BAD_INDEX) ? (0x123) : (GL_UNSIGNED_SHORT);
2769*35238bceSAndroid Build Coastguard Worker 
2770*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2771*35238bceSAndroid Build Coastguard Worker 
2772*35238bceSAndroid Build Coastguard Worker     // vao
2773*35238bceSAndroid Build Coastguard Worker 
2774*35238bceSAndroid Build Coastguard Worker     gl.genVertexArrays(1, &vaoID);
2775*35238bceSAndroid Build Coastguard Worker     gl.bindVertexArray(vaoID);
2776*35238bceSAndroid Build Coastguard Worker 
2777*35238bceSAndroid Build Coastguard Worker     // va
2778*35238bceSAndroid Build Coastguard Worker 
2779*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &dataBufferID);
2780*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_ARRAY_BUFFER, dataBufferID);
2781*35238bceSAndroid Build Coastguard Worker     gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
2782*35238bceSAndroid Build Coastguard Worker     gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2783*35238bceSAndroid Build Coastguard Worker     gl.enableVertexAttribArray(posLocation);
2784*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2785*35238bceSAndroid Build Coastguard Worker 
2786*35238bceSAndroid Build Coastguard Worker     // index
2787*35238bceSAndroid Build Coastguard Worker 
2788*35238bceSAndroid Build Coastguard Worker     if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
2789*35238bceSAndroid Build Coastguard Worker     {
2790*35238bceSAndroid Build Coastguard Worker         gl.genBuffers(1, &indexBufferID);
2791*35238bceSAndroid Build Coastguard Worker         gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
2792*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
2793*35238bceSAndroid Build Coastguard Worker         glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2794*35238bceSAndroid Build Coastguard Worker     }
2795*35238bceSAndroid Build Coastguard Worker 
2796*35238bceSAndroid Build Coastguard Worker     // cmd
2797*35238bceSAndroid Build Coastguard Worker 
2798*35238bceSAndroid Build Coastguard Worker     gl.genBuffers(1, &cmdBufferID);
2799*35238bceSAndroid Build Coastguard Worker     gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBufferID);
2800*35238bceSAndroid Build Coastguard Worker     if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
2801*35238bceSAndroid Build Coastguard Worker     {
2802*35238bceSAndroid Build Coastguard Worker         DrawElementsCommand drawCommand;
2803*35238bceSAndroid Build Coastguard Worker         drawCommand.count              = 3;
2804*35238bceSAndroid Build Coastguard Worker         drawCommand.primCount          = 1;
2805*35238bceSAndroid Build Coastguard Worker         drawCommand.firstIndex         = 0;
2806*35238bceSAndroid Build Coastguard Worker         drawCommand.baseVertex         = 0;
2807*35238bceSAndroid Build Coastguard Worker         drawCommand.reservedMustBeZero = 0;
2808*35238bceSAndroid Build Coastguard Worker 
2809*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
2810*35238bceSAndroid Build Coastguard Worker     }
2811*35238bceSAndroid Build Coastguard Worker     else if (m_drawType == DRAW_ARRAYS)
2812*35238bceSAndroid Build Coastguard Worker     {
2813*35238bceSAndroid Build Coastguard Worker         DrawArraysCommand drawCommand;
2814*35238bceSAndroid Build Coastguard Worker         drawCommand.count              = 3;
2815*35238bceSAndroid Build Coastguard Worker         drawCommand.primCount          = 1;
2816*35238bceSAndroid Build Coastguard Worker         drawCommand.first              = 0;
2817*35238bceSAndroid Build Coastguard Worker         drawCommand.reservedMustBeZero = 0;
2818*35238bceSAndroid Build Coastguard Worker 
2819*35238bceSAndroid Build Coastguard Worker         gl.bufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(drawCommand), &drawCommand, GL_STATIC_DRAW);
2820*35238bceSAndroid Build Coastguard Worker     }
2821*35238bceSAndroid Build Coastguard Worker     else
2822*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2823*35238bceSAndroid Build Coastguard Worker     glu::checkError(gl.getError(), "", __FILE__, __LINE__);
2824*35238bceSAndroid Build Coastguard Worker 
2825*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, 1, 1);
2826*35238bceSAndroid Build Coastguard Worker     gl.useProgram(programID);
2827*35238bceSAndroid Build Coastguard Worker     if (m_drawType == DRAW_ELEMENTS || m_drawType == DRAW_ELEMENTS_BAD_INDEX)
2828*35238bceSAndroid Build Coastguard Worker         gl.drawElementsIndirect(mode, indexType, DE_NULL);
2829*35238bceSAndroid Build Coastguard Worker     else if (m_drawType == DRAW_ARRAYS)
2830*35238bceSAndroid Build Coastguard Worker         gl.drawArraysIndirect(mode, DE_NULL);
2831*35238bceSAndroid Build Coastguard Worker     else
2832*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2833*35238bceSAndroid Build Coastguard Worker 
2834*35238bceSAndroid Build Coastguard Worker     error = gl.getError();
2835*35238bceSAndroid Build Coastguard Worker     gl.useProgram(0);
2836*35238bceSAndroid Build Coastguard Worker 
2837*35238bceSAndroid Build Coastguard Worker     if (error == GL_INVALID_ENUM)
2838*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2839*35238bceSAndroid Build Coastguard Worker     else
2840*35238bceSAndroid Build Coastguard Worker     {
2841*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected error. Expected GL_INVALID_ENUM, got "
2842*35238bceSAndroid Build Coastguard Worker                            << glu::getErrorStr(error) << tcu::TestLog::EndMessage;
2843*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected error.");
2844*35238bceSAndroid Build Coastguard Worker     }
2845*35238bceSAndroid Build Coastguard Worker 
2846*35238bceSAndroid Build Coastguard Worker     return STOP;
2847*35238bceSAndroid Build Coastguard Worker }
2848*35238bceSAndroid Build Coastguard Worker 
2849*35238bceSAndroid Build Coastguard Worker class NegativeGroup : public TestCaseGroup
2850*35238bceSAndroid Build Coastguard Worker {
2851*35238bceSAndroid Build Coastguard Worker public:
2852*35238bceSAndroid Build Coastguard Worker     NegativeGroup(Context &context, const char *name, const char *descr);
2853*35238bceSAndroid Build Coastguard Worker     ~NegativeGroup(void);
2854*35238bceSAndroid Build Coastguard Worker 
2855*35238bceSAndroid Build Coastguard Worker     void init(void);
2856*35238bceSAndroid Build Coastguard Worker };
2857*35238bceSAndroid Build Coastguard Worker 
NegativeGroup(Context & context,const char * name,const char * descr)2858*35238bceSAndroid Build Coastguard Worker NegativeGroup::NegativeGroup(Context &context, const char *name, const char *descr)
2859*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, name, descr)
2860*35238bceSAndroid Build Coastguard Worker {
2861*35238bceSAndroid Build Coastguard Worker }
2862*35238bceSAndroid Build Coastguard Worker 
~NegativeGroup(void)2863*35238bceSAndroid Build Coastguard Worker NegativeGroup::~NegativeGroup(void)
2864*35238bceSAndroid Build Coastguard Worker {
2865*35238bceSAndroid Build Coastguard Worker }
2866*35238bceSAndroid Build Coastguard Worker 
init(void)2867*35238bceSAndroid Build Coastguard Worker void NegativeGroup::init(void)
2868*35238bceSAndroid Build Coastguard Worker {
2869*35238bceSAndroid Build Coastguard Worker     // invalid alignment
2870*35238bceSAndroid Build Coastguard Worker     addChild(new BadAlignmentCase(m_context, "command_bad_alignment_1", "Bad command alignment", 1));
2871*35238bceSAndroid Build Coastguard Worker     addChild(new BadAlignmentCase(m_context, "command_bad_alignment_2", "Bad command alignment", 2));
2872*35238bceSAndroid Build Coastguard Worker     addChild(new BadAlignmentCase(m_context, "command_bad_alignment_3", "Bad command alignment", 3));
2873*35238bceSAndroid Build Coastguard Worker 
2874*35238bceSAndroid Build Coastguard Worker     // command only partially or not at all in the buffer
2875*35238bceSAndroid Build Coastguard Worker     addChild(new BadBufferRangeCase(m_context, "command_offset_partially_in_buffer",
2876*35238bceSAndroid Build Coastguard Worker                                     "Command not fully in the buffer range", BadBufferRangeCase::CommandSize - 16));
2877*35238bceSAndroid Build Coastguard Worker     addChild(new BadBufferRangeCase(m_context, "command_offset_not_in_buffer", "Command not in the buffer range",
2878*35238bceSAndroid Build Coastguard Worker                                     BadBufferRangeCase::CommandSize));
2879*35238bceSAndroid Build Coastguard Worker     addChild(new BadBufferRangeCase(m_context, "command_offset_not_in_buffer_unsigned32_wrap",
2880*35238bceSAndroid Build Coastguard Worker                                     "Command not in the buffer range", 0xFFFFFFFC));
2881*35238bceSAndroid Build Coastguard Worker     addChild(new BadBufferRangeCase(m_context, "command_offset_not_in_buffer_signed32_wrap",
2882*35238bceSAndroid Build Coastguard Worker                                     "Command not in the buffer range", 0x7FFFFFFC));
2883*35238bceSAndroid Build Coastguard Worker 
2884*35238bceSAndroid Build Coastguard Worker     // use with client data and default vao
2885*35238bceSAndroid Build Coastguard Worker     addChild(new BadStateCase(m_context, "client_vertex_attrib_array", "Vertex attrib array in the client memory",
2886*35238bceSAndroid Build Coastguard Worker                               BadStateCase::CASE_CLIENT_BUFFER_VERTEXATTR));
2887*35238bceSAndroid Build Coastguard Worker     addChild(new BadStateCase(m_context, "client_command_array", "Command array in the client memory",
2888*35238bceSAndroid Build Coastguard Worker                               BadStateCase::CASE_CLIENT_BUFFER_COMMAND));
2889*35238bceSAndroid Build Coastguard Worker     addChild(new BadStateCase(m_context, "default_vao", "Use with default vao", BadStateCase::CASE_DEFAULT_VAO));
2890*35238bceSAndroid Build Coastguard Worker 
2891*35238bceSAndroid Build Coastguard Worker     // invalid mode & type
2892*35238bceSAndroid Build Coastguard Worker     addChild(new BadDrawModeCase(m_context, "invalid_mode_draw_arrays", "Call DrawArraysIndirect with bad mode",
2893*35238bceSAndroid Build Coastguard Worker                                  BadDrawModeCase::DRAW_ARRAYS));
2894*35238bceSAndroid Build Coastguard Worker     addChild(new BadDrawModeCase(m_context, "invalid_mode_draw_elements", "Call DrawelementsIndirect with bad mode",
2895*35238bceSAndroid Build Coastguard Worker                                  BadDrawModeCase::DRAW_ELEMENTS));
2896*35238bceSAndroid Build Coastguard Worker     addChild(new BadDrawModeCase(m_context, "invalid_type_draw_elements", "Call DrawelementsIndirect with bad type",
2897*35238bceSAndroid Build Coastguard Worker                                  BadDrawModeCase::DRAW_ELEMENTS_BAD_INDEX));
2898*35238bceSAndroid Build Coastguard Worker }
2899*35238bceSAndroid Build Coastguard Worker 
2900*35238bceSAndroid Build Coastguard Worker } // namespace
2901*35238bceSAndroid Build Coastguard Worker 
DrawTests(Context & context)2902*35238bceSAndroid Build Coastguard Worker DrawTests::DrawTests(Context &context) : TestCaseGroup(context, "draw_indirect", "Indirect drawing tests")
2903*35238bceSAndroid Build Coastguard Worker {
2904*35238bceSAndroid Build Coastguard Worker }
2905*35238bceSAndroid Build Coastguard Worker 
~DrawTests(void)2906*35238bceSAndroid Build Coastguard Worker DrawTests::~DrawTests(void)
2907*35238bceSAndroid Build Coastguard Worker {
2908*35238bceSAndroid Build Coastguard Worker }
2909*35238bceSAndroid Build Coastguard Worker 
init(void)2910*35238bceSAndroid Build Coastguard Worker void DrawTests::init(void)
2911*35238bceSAndroid Build Coastguard Worker {
2912*35238bceSAndroid Build Coastguard Worker     // Basic
2913*35238bceSAndroid Build Coastguard Worker     {
2914*35238bceSAndroid Build Coastguard Worker         const gls::DrawTestSpec::DrawMethod basicMethods[] = {
2915*35238bceSAndroid Build Coastguard Worker             gls::DrawTestSpec::DRAWMETHOD_DRAWARRAYS_INDIRECT,
2916*35238bceSAndroid Build Coastguard Worker             gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INDIRECT,
2917*35238bceSAndroid Build Coastguard Worker         };
2918*35238bceSAndroid Build Coastguard Worker 
2919*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
2920*35238bceSAndroid Build Coastguard Worker         {
2921*35238bceSAndroid Build Coastguard Worker             const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
2922*35238bceSAndroid Build Coastguard Worker             const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
2923*35238bceSAndroid Build Coastguard Worker 
2924*35238bceSAndroid Build Coastguard Worker             this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));
2925*35238bceSAndroid Build Coastguard Worker         }
2926*35238bceSAndroid Build Coastguard Worker     }
2927*35238bceSAndroid Build Coastguard Worker 
2928*35238bceSAndroid Build Coastguard Worker     // extreme instancing
2929*35238bceSAndroid Build Coastguard Worker 
2930*35238bceSAndroid Build Coastguard Worker     this->addChild(new InstancingGroup(m_context, "instancing", "draw tests with a large instance count."));
2931*35238bceSAndroid Build Coastguard Worker 
2932*35238bceSAndroid Build Coastguard Worker     // compute shader generated commands
2933*35238bceSAndroid Build Coastguard Worker 
2934*35238bceSAndroid Build Coastguard Worker     this->addChild(new ComputeShaderGeneratedGroup(m_context, "compute_interop",
2935*35238bceSAndroid Build Coastguard Worker                                                    "draw tests with a draw command generated in compute shader."));
2936*35238bceSAndroid Build Coastguard Worker 
2937*35238bceSAndroid Build Coastguard Worker     // Random
2938*35238bceSAndroid Build Coastguard Worker 
2939*35238bceSAndroid Build Coastguard Worker     this->addChild(new RandomGroup(m_context, "random", "random draw commands."));
2940*35238bceSAndroid Build Coastguard Worker 
2941*35238bceSAndroid Build Coastguard Worker     // negative
2942*35238bceSAndroid Build Coastguard Worker 
2943*35238bceSAndroid Build Coastguard Worker     this->addChild(new NegativeGroup(m_context, "negative", "invalid draw commands with defined error codes."));
2944*35238bceSAndroid Build Coastguard Worker }
2945*35238bceSAndroid Build Coastguard Worker 
2946*35238bceSAndroid Build Coastguard Worker } // namespace Functional
2947*35238bceSAndroid Build Coastguard Worker } // namespace gles31
2948*35238bceSAndroid Build Coastguard Worker } // namespace deqp
2949