fix 1d depth component 16 sizing in layout locations tests.
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcLayoutLocationTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2018 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  **/ /*!
19  * \file glcLayoutLocationTests.cpp
20  * \brief
21  */ /*-------------------------------------------------------------------*/
22 #include "glcLayoutLocationTests.hpp"
23
24 #include "tcuRenderTarget.hpp"
25 #include "tcuStringTemplate.hpp"
26 #include "tcuSurface.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuTexture.hpp"
29 #include "tcuTextureUtil.hpp"
30
31 #include "deStringUtil.hpp"
32
33 #include "glwDefs.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36
37 #include "gluDrawUtil.hpp"
38 #include "gluPixelTransfer.hpp"
39 #include "gluShaderProgram.hpp"
40 #include "gluTexture.hpp"
41 #include "gluTextureUtil.hpp"
42
43 using namespace glw;
44
45 namespace glcts
46 {
47
48 static const GLuint WIDTH  = 2;
49 static const GLuint HEIGHT = 2;
50
51 // Helper function used to set texture parameters
52 void setTexParameters(const Functions& gl, GLenum target, bool depthTexture)
53 {
54         gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
55         gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
56
57         if (depthTexture)
58         {
59                 gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
60                 gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
61         }
62 }
63
64 // Helper function used to create texture data
65 template <typename DATA_TYPE>
66 std::vector<DATA_TYPE> generateData(std::size_t width, std::size_t height, std::size_t components)
67 {
68         DE_ASSERT((components == 1) || (components == 4));
69         std::size_t                        size = width * height * components;
70         std::vector<DATA_TYPE> data(size, 0);
71         for (std::size_t i = 0; i < size; i += components)
72                 data[i]            = static_cast<DATA_TYPE>(255);
73         return data;
74 }
75
76 // Structure used to return id of created object it had to be defined to support
77 // GL_TEXTURE_BUFFER cases which require creation of both texture and buffer
78 struct ResultData
79 {
80         deUint32 textureId; // id of created texture
81         deUint32 bufferId;  // used only by GL_TEXTURE_BUFFER
82
83         ResultData(deUint32 tId) : textureId(tId), bufferId(0)
84         {
85         }
86
87         ResultData(deUint32 tId, deUint32 bId) : textureId(tId), bufferId(bId)
88         {
89         }
90 };
91
92 template <typename DATA_TYPE>
93 ResultData createTexture1D(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
94                                                    GLenum type)
95 {
96         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, 1, components);
97
98         deUint32 id;
99         gl.genTextures(1, &id);
100         gl.bindTexture(GL_TEXTURE_1D, id);
101         gl.texImage1D(GL_TEXTURE_1D, 0, internalFormat, WIDTH, 0, format, type, &data[0]);
102         setTexParameters(gl, GL_TEXTURE_1D, components == 1);
103         return id;
104 }
105
106 template <typename DATA_TYPE>
107 ResultData createTexture2D(const Functions& gl, std::size_t components, GLenum target, GLenum internalFormat,
108                                                    GLenum format, GLenum type)
109 {
110         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);
111
112         deUint32 id;
113         gl.genTextures(1, &id);
114         gl.bindTexture(target, id);
115         gl.texStorage2D(target, 1, internalFormat, WIDTH, HEIGHT);
116         gl.texSubImage2D(target, 0, 0, 0, WIDTH, HEIGHT, format, type, &data[0]);
117         setTexParameters(gl, target, components == 1);
118         return id;
119 }
120
121 template <typename DATA_TYPE>
122 ResultData createTexture3D(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
123                                                    GLenum type)
124 {
125         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);
126
127         deUint32 id;
128         gl.genTextures(1, &id);
129         gl.bindTexture(GL_TEXTURE_3D, id);
130         gl.texStorage3D(GL_TEXTURE_3D, 1, internalFormat, WIDTH, HEIGHT, 1);
131         gl.texSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, WIDTH, HEIGHT, 1, format, type, &data[0]);
132         setTexParameters(gl, GL_TEXTURE_3D, components == 1);
133         return id;
134 }
135
136 template <typename DATA_TYPE>
137 ResultData createCubeMap(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format, GLenum type)
138 {
139         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);
140
141         deUint32 id;
142         gl.genTextures(1, &id);
143         gl.bindTexture(GL_TEXTURE_CUBE_MAP, id);
144         GLenum faces[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
145                                            GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
146         gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalFormat, WIDTH, HEIGHT);
147         for (int i = 0; i < 6; ++i)
148                 gl.texSubImage2D(faces[i], 0, 0, 0, WIDTH, HEIGHT, format, type, &data[0]);
149         setTexParameters(gl, GL_TEXTURE_CUBE_MAP, components == 1);
150         return id;
151 }
152
153 template <typename DATA_TYPE>
154 ResultData createTexture2DArray(const Functions& gl, std::size_t components, GLenum internalFormat, GLenum format,
155                                                                 GLenum type)
156 {
157         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, components);
158
159         deUint32 id;
160         gl.genTextures(1, &id);
161         gl.bindTexture(GL_TEXTURE_2D_ARRAY, id);
162         gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalFormat, WIDTH, HEIGHT, 1);
163         gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, WIDTH, HEIGHT, 1, format, type, &data[0]);
164         setTexParameters(gl, GL_TEXTURE_2D_ARRAY, components == 1);
165         return id;
166 }
167
168 template <typename DATA_TYPE>
169 ResultData createTextureBuffer(const Functions& gl, GLenum internalFormat)
170 {
171         std::vector<DATA_TYPE> data = generateData<DATA_TYPE>(WIDTH, HEIGHT, 4);
172
173         deUint32 bufferId;
174         gl.genBuffers(1, &bufferId);
175         gl.bindBuffer(GL_TEXTURE_BUFFER, bufferId);
176         gl.bufferData(GL_TEXTURE_BUFFER, WIDTH * HEIGHT * 4 * sizeof(DATA_TYPE), &data[0], GL_STATIC_DRAW);
177
178         deUint32 textureId;
179         gl.genTextures(1, &textureId);
180         gl.bindTexture(GL_TEXTURE_BUFFER, textureId);
181         gl.texBuffer(GL_TEXTURE_BUFFER, internalFormat, bufferId);
182         return ResultData(textureId, bufferId);
183 }
184
185 // create function was implemented for convinience. Specializations of this
186 // template simplify definition of test data by reducting the number of
187 // attributes which were moved to create fn implementation. This aproach
188 // also simplyfies texture creation in the test as create takes just a single
189 // parameter for all test cases.
190 template <GLenum, GLenum>
191 ResultData create(const Functions& gl)
192 {
193         (void)gl;
194         TCU_FAIL("Missing specialization implementation.");
195 }
196
197 template <>
198 ResultData create<GL_TEXTURE_2D, GL_RGBA8>(const Functions& gl)
199 {
200         return createTexture2D<unsigned char>(gl, 4, GL_TEXTURE_2D, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
201 }
202
203 template <>
204 ResultData create<GL_TEXTURE_3D, GL_RGBA8>(const Functions& gl)
205 {
206         return createTexture3D<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
207 }
208
209 template <>
210 ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>(const Functions& gl)
211 {
212         return createCubeMap<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
213 }
214
215 template <>
216 ResultData create<GL_TEXTURE_CUBE_MAP, GL_DEPTH_COMPONENT16>(const Functions& gl)
217 {
218         return createCubeMap<short>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
219 }
220
221 template <>
222 ResultData create<GL_TEXTURE_2D, GL_DEPTH_COMPONENT16>(const Functions& gl)
223 {
224         return createTexture2D<short>(gl, 1, GL_TEXTURE_2D, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
225 }
226
227 template <>
228 ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>(const Functions& gl)
229 {
230         return createTexture2DArray<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
231 }
232
233 template <>
234 ResultData create<GL_TEXTURE_2D_ARRAY, GL_DEPTH_COMPONENT16>(const Functions& gl)
235 {
236         return createTexture2DArray<short>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
237 }
238
239 template <>
240 ResultData create<GL_TEXTURE_2D, GL_RGBA32I>(const Functions& gl)
241 {
242         return createTexture2D<int>(gl, 4, GL_TEXTURE_2D, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
243 }
244
245 template <>
246 ResultData create<GL_TEXTURE_3D, GL_RGBA32I>(const Functions& gl)
247 {
248         return createTexture3D<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
249 }
250
251 template <>
252 ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>(const Functions& gl)
253 {
254         return createCubeMap<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
255 }
256
257 template <>
258 ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>(const Functions& gl)
259 {
260         return createTexture2DArray<int>(gl, 4, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT);
261 }
262
263 template <>
264 ResultData create<GL_TEXTURE_2D, GL_RGBA32UI>(const Functions& gl)
265 {
266         return createTexture2D<unsigned int>(gl, 4, GL_TEXTURE_2D, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
267 }
268
269 template <>
270 ResultData create<GL_TEXTURE_3D, GL_RGBA32UI>(const Functions& gl)
271 {
272         return createTexture3D<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
273 }
274
275 template <>
276 ResultData create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>(const Functions& gl)
277 {
278         return createCubeMap<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
279 }
280
281 template <>
282 ResultData create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>(const Functions& gl)
283 {
284         return createTexture2DArray<unsigned int>(gl, 4, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
285 }
286
287 template <>
288 ResultData create<GL_TEXTURE_1D, GL_RGBA8>(const Functions& gl)
289 {
290         return createTexture1D<unsigned char>(gl, 4, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
291 }
292
293 template <>
294 ResultData create<GL_TEXTURE_1D, GL_DEPTH_COMPONENT16>(const Functions& gl)
295 {
296         return createTexture1D<unsigned short>(gl, 1, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
297 }
298
299 template <>
300 ResultData create<GL_TEXTURE_1D_ARRAY, GL_RGBA8>(const Functions& gl)
301 {
302         return createTexture2D<unsigned char>(gl, 4, GL_TEXTURE_1D_ARRAY, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
303 }
304
305 template <>
306 ResultData create<GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16>(const Functions& gl)
307 {
308         return createTexture2D<short>(gl, 1, GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
309                                                                   GL_UNSIGNED_SHORT);
310 }
311
312 template <>
313 ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32F>(const Functions& gl)
314 {
315         return createTextureBuffer<float>(gl, GL_RGBA32F);
316 }
317
318 template <>
319 ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32I>(const Functions& gl)
320 {
321         return createTextureBuffer<int>(gl, GL_RGBA32I);
322 }
323
324 template <>
325 ResultData create<GL_TEXTURE_BUFFER, GL_RGBA32UI>(const Functions& gl)
326 {
327         return createTextureBuffer<unsigned int>(gl, GL_RGBA32UI);
328 }
329
330 // Structure used to define all test case data
331 struct SamplerCaseData
332 {
333         typedef ResultData (*CreateFnPtr)(const Functions& gl);
334
335         CreateFnPtr     create;                                         // pointer to function that will create texture
336         const char*     name;                                           // test case name
337         const char*     opaqueType;                                     // sampler or image
338         const char*     outAssignment;                          // operation that determines fragment color
339         const int       num_frag_image_uniforms;        // the number of required fragment image uniform
340 };
341
342 class SpecifiedLocationCase : public deqp::TestCase
343 {
344 public:
345         SpecifiedLocationCase(deqp::Context& context, const SamplerCaseData& data);
346         virtual ~SpecifiedLocationCase();
347
348         tcu::TestNode::IterateResult iterate();
349
350 private:
351         ResultData (*m_createFn)(const Functions& gl);
352         std::map<std::string, std::string> m_specializationMap;
353
354         bool            m_isImageCase;
355         GLenum          m_imageFormat;
356         std::string     m_imageFormatQualifier;
357         int                     m_num_frag_image_uniform;
358 };
359
360 SpecifiedLocationCase::SpecifiedLocationCase(deqp::Context& context, const SamplerCaseData& data)
361         : deqp::TestCase(context, data.name, ""), m_createFn(data.create)
362 {
363         std::string type(data.opaqueType);
364         m_specializationMap["OPAQUE_TYPE"]      = type;
365         m_specializationMap["OUT_ASSIGNMENT"] = data.outAssignment;
366
367         m_isImageCase = (type.find("sampler") == std::string::npos);
368         if (m_isImageCase)
369         {
370                 m_specializationMap["OPAQUE_TYPE_NAME"] = "image";
371                 m_specializationMap["ACCESS"]                   = "readonly";
372
373                 if (type.find("iimage") != std::string::npos)
374                 {
375                         m_imageFormatQualifier = "rgba32i";
376                         m_imageFormat              = GL_RGBA32I;
377                 }
378                 else if (type.find("uimage") != std::string::npos)
379                 {
380                         m_imageFormatQualifier = "rgba32ui";
381                         m_imageFormat              = GL_RGBA32UI;
382                 }
383                 else
384                 {
385                         m_imageFormatQualifier = "rgba8";
386                         m_imageFormat              = GL_RGBA8;
387                 }
388         }
389         else
390         {
391                 m_specializationMap["OPAQUE_TYPE_NAME"] = "sampler";
392                 m_specializationMap["ACCESS"]                   = "";
393         }
394         m_num_frag_image_uniform = data.num_frag_image_uniforms;
395 }
396
397 SpecifiedLocationCase::~SpecifiedLocationCase()
398 {
399 }
400
401 tcu::TestNode::IterateResult SpecifiedLocationCase::iterate(void)
402 {
403         static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
404         static const float      positions[]   = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };
405
406         static const char* vsTemplate = "${VERSION}\n"
407                                                                         "precision highp float;\n"
408                                                                         "layout(location=0) in highp vec2 inPosition;\n"
409                                                                         "layout(location=0) out highp vec2 coords;\n"
410                                                                         "void main(void)\n"
411                                                                         "{\n"
412                                                                         "  coords = vec2(max(0.0, inPosition.x), max(0.0, inPosition.y));\n"
413                                                                         "  gl_Position = vec4(inPosition, 0.0, 1.0);\n"
414                                                                         "}\n";
415
416         static const char* fsTemplate =
417                 "${VERSION}\n"
418                 "precision highp float;\n"
419                 "layout(location=0) in vec2 coords;\n"
420                 "layout(location=0) out vec4 fragColor;\n"
421                 "layout(${OPAQUE_TYPE_QUALIFIERS}) ${ACCESS} uniform highp ${OPAQUE_TYPE} ${OPAQUE_TYPE_NAME};\n"
422                 "void main(void)\n"
423                 "{\n"
424                 "  fragColor = ${OUT_ASSIGNMENT};\n"
425                 "}\n";
426
427         glu::RenderContext& renderContext = m_context.getRenderContext();
428         glu::ContextType        contextType   = renderContext.getType();
429         glu::GLSLVersion        glslVersion   = glu::getContextTypeGLSLVersion(contextType);
430         const Functions&        gl                        = renderContext.getFunctions();
431         bool                            contextTypeES = glu::isContextTypeES(contextType);
432         bool                            contextES32       = glu::contextSupports(contextType, glu::ApiType::es(3, 2));
433         if (contextTypeES && !contextES32 && !m_context.getContextInfo().isExtensionSupported("GL_ANDROID_extension_pack_es31a"))
434                 if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < m_num_frag_image_uniform)
435                         throw tcu::NotSupportedError("The number of required fragment image uniform is larger than GL_MAX_FRAGMENT_IMAGE_UNIFORMS");
436
437         const int expectedLocation = 2;
438         const int definedBinding   = 1;
439
440         std::ostringstream layoutSpecification;
441         layoutSpecification << "location=" << expectedLocation;
442         if (m_isImageCase)
443         {
444                 if (contextTypeES)
445                         layoutSpecification << ", binding=" << definedBinding;
446                 layoutSpecification << ", " << m_imageFormatQualifier;
447         }
448
449         m_specializationMap["VERSION"]                            = glu::getGLSLVersionDeclaration(glslVersion);
450         m_specializationMap["OPAQUE_TYPE_QUALIFIERS"] = layoutSpecification.str();
451
452         std::string                vs = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
453         std::string                fs = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
454         glu::ShaderProgram program(gl, glu::makeVtxFragSources(vs.c_str(), fs.c_str()));
455
456         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
457         if (!program.isOk())
458         {
459                 m_testCtx.getLog() << program << tcu::TestLog::Message << "Creation of program failed."
460                                                    << tcu::TestLog::EndMessage;
461                 return STOP;
462         }
463
464         deUint32 programId = program.getProgram();
465         int              location  = gl.getUniformLocation(programId, m_specializationMap["OPAQUE_TYPE_NAME"].c_str());
466         if (location != expectedLocation)
467         {
468                 m_testCtx.getLog() << tcu::TestLog::Message << "Expected uniform to be at location " << expectedLocation
469                                                    << ", not at " << location << "." << tcu::TestLog::EndMessage;
470                 return STOP;
471         }
472
473         gl.useProgram(programId);
474         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
475
476         // Prepare texture/buffer
477         gl.activeTexture(GL_TEXTURE1);
478         ResultData resultData = (*m_createFn)(gl);
479         GLU_EXPECT_NO_ERROR(gl.getError(), "GL object creation failed.");
480
481         if (m_isImageCase)
482         {
483                 gl.bindImageTexture(definedBinding, resultData.textureId, 0, GL_TRUE, 0, GL_READ_ONLY, m_imageFormat);
484                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
485         }
486
487         // in ES image uniforms cannot be updated
488         // through any of the glUniform* commands
489         if (!(contextTypeES && m_isImageCase))
490         {
491                 gl.uniform1i(expectedLocation, definedBinding);
492                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
493         }
494
495         // Create FBO with RBO
496         deUint32 rboId;
497         deUint32 fboId;
498         gl.genRenderbuffers(1, &rboId);
499         gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
500         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, WIDTH, HEIGHT);
501         gl.genFramebuffers(1, &fboId);
502         gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
503         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);
504
505         // Render
506         gl.viewport(0, 0, WIDTH, HEIGHT);
507         const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, positions) };
508         glu::draw(renderContext, programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
509                           glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
510
511         // Grab surface
512         tcu::Surface resultFrame(WIDTH, HEIGHT);
513         glu::readPixels(renderContext, 0, 0, resultFrame.getAccess());
514
515         // Verify color of just first pixel
516         const tcu::RGBA expectedColor(255, 0, 0, 0);
517         tcu::RGBA               pixel = resultFrame.getPixel(0, 0);
518         if (pixel != expectedColor)
519         {
520                 m_testCtx.getLog() << tcu::TestLog::Message << "Incorrect color was generated, expected: ["
521                                                    << expectedColor.getRed() << ", " << expectedColor.getGreen() << ", "
522                                                    << expectedColor.getBlue() << ", " << expectedColor.getAlpha() << "], got ["
523                                                    << pixel.getRed() << ", " << pixel.getGreen() << ", " << pixel.getBlue() << ", "
524                                                    << pixel.getAlpha() << "]" << tcu::TestLog::EndMessage;
525         }
526         else
527                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
528
529         // Cleanup
530         if (resultData.bufferId)
531                 gl.deleteBuffers(1, &resultData.bufferId);
532         gl.deleteFramebuffers(1, &fboId);
533         gl.deleteRenderbuffers(1, &rboId);
534         gl.deleteTextures(1, &resultData.textureId);
535
536         return STOP;
537 }
538
539 class NegativeLocationCase : public deqp::TestCase
540 {
541 public:
542         NegativeLocationCase(deqp::Context& context);
543         virtual ~NegativeLocationCase();
544
545         tcu::TestNode::IterateResult iterate();
546 };
547
548 NegativeLocationCase::NegativeLocationCase(deqp::Context& context) : deqp::TestCase(context, "invalid_cases", "")
549 {
550 }
551
552 NegativeLocationCase::~NegativeLocationCase()
553 {
554 }
555
556 tcu::TestNode::IterateResult NegativeLocationCase::iterate()
557 {
558         glu::RenderContext& renderContext = m_context.getRenderContext();
559         glu::ContextType        contextType   = renderContext.getType();
560         glu::GLSLVersion        glslVersion   = glu::getContextTypeGLSLVersion(contextType);
561         const Functions&        gl                        = renderContext.getFunctions();
562
563         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
564
565         static const char* csTemplate = "${VERSION}\n"
566                                                                         "layout(location=2, binding=0) uniform atomic_uint u_atomic;\n"
567                                                                         "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
568                                                                         "layout(binding=0) buffer Output {\n  uint value;\n} sb_out;\n\n"
569                                                                         "void main (void) {\n"
570                                                                         "  sb_out.value = atomicCounterIncrement(u_atomic);\n"
571                                                                         "}";
572
573         std::map<std::string, std::string> specializationMap;
574         specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
575         std::string cs                           = tcu::StringTemplate(csTemplate).specialize(specializationMap);
576
577         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
578
579         glu::ProgramSources sourcesCompute;
580         sourcesCompute.sources[glu::SHADERTYPE_COMPUTE].push_back(cs);
581         glu::ShaderProgram program(gl, sourcesCompute);
582         if (program.isOk())
583         {
584                 m_testCtx.getLog() << program << tcu::TestLog::Message
585                                                    << "layout(location = N) is not allowed for atomic counters" << tcu::TestLog::EndMessage;
586                 return STOP;
587         }
588
589         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
590         return STOP;
591 }
592
593 LayoutLocationTests::LayoutLocationTests(Context& context) : TestCaseGroup(context, "layout_location", "")
594 {
595 }
596
597 LayoutLocationTests::~LayoutLocationTests(void)
598 {
599 }
600
601 void LayoutLocationTests::init(void)
602 {
603         const SamplerCaseData commonArguments[] =
604         {
605                 { &create<GL_TEXTURE_2D, GL_RGBA8>,                                             "sampler_2d",                           "sampler2D",                    "texture(sampler, coords)",                                                                                     0 },
606                 { &create<GL_TEXTURE_3D, GL_RGBA8>,                                             "sampler_3d",                           "sampler3D",                    "texture(sampler, vec3(coords, 0.0))",                                                          0 },
607                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>,                               "sampler_cube",                         "samplerCube",                  "texture(sampler, vec3(coords, 0.0))",                                                          0 },
608                 { &create<GL_TEXTURE_CUBE_MAP, GL_DEPTH_COMPONENT16>,   "sampler_cube_shadow",          "samplerCubeShadow",    "vec4(texture(sampler, vec4(coords, 0.0, 0.0)), 0.0, 0.0, 0.0)",        0 },
609                 { &create<GL_TEXTURE_2D, GL_DEPTH_COMPONENT16>,                 "sampler_2d_shadow",            "sampler2DShadow",              "vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",                     0 },
610                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>,                               "sampler_2d_array",                     "sampler2DArray",               "texture(sampler, vec3(coords, 0.0))",                                                          0 },
611                 { &create<GL_TEXTURE_2D_ARRAY, GL_DEPTH_COMPONENT16>,   "sampler_2d_array_shadow",      "sampler2DArrayShadow", "vec4(texture(sampler, vec4(coords, 0.0, 0.0)), 0.0, 0.0, 0.0)",        0 },
612                 { &create<GL_TEXTURE_2D, GL_RGBA32I>,                                   "isampler_2d",                          "isampler2D",                   "vec4(texture(sampler, coords))/255.0",                                                         0 },
613                 { &create<GL_TEXTURE_3D, GL_RGBA32I>,                                   "isampler_3d",                          "isampler3D",                   "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
614                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>,                             "isampler_cube",                        "isamplerCube",                 "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
615                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>,                             "isampler_2d_array",            "isampler2DArray",              "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
616                 { &create<GL_TEXTURE_2D, GL_RGBA32UI>,                                  "usampler_2d",                          "usampler2D",                   "vec4(texture(sampler, coords))/255.0",                                                         0 },
617                 { &create<GL_TEXTURE_3D, GL_RGBA32UI>,                                  "usampler_3d",                          "usampler3D",                   "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
618                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>,                    "usampler_cube",                        "usamplerCube",                 "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
619                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>,                    "usampler_2d_array",            "usampler2DArray",              "vec4(texture(sampler, vec3(coords, 0.0)))/255.0",                                      0 },
620
621                 { &create<GL_TEXTURE_2D, GL_RGBA8>,                                             "image_2d",                                     "image2D",                              "imageLoad(image, ivec2(0, 0))",                                                                        1 },
622                 { &create<GL_TEXTURE_2D, GL_RGBA32I>,                                   "iimage_2d",                            "iimage2D",                             "vec4(imageLoad(image, ivec2(0, 0)))/255.0",                                            1 },
623                 { &create<GL_TEXTURE_2D, GL_RGBA32UI>,                                  "uimage_2d",                            "uimage2D",                             "vec4(imageLoad(image, ivec2(0, 0)))/255.0",                                            1 },
624                 { &create<GL_TEXTURE_3D, GL_RGBA8>,                                             "image_3d",                                     "image3D",                              "imageLoad(image, ivec3(0, 0, 0))",                                                                     1 },
625                 { &create<GL_TEXTURE_3D, GL_RGBA32I>,                                   "iimage_3d",                            "iimage3D",                             "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
626                 { &create<GL_TEXTURE_3D, GL_RGBA32UI>,                                  "uimage_3d",                            "uimage3D",                             "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
627                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA8>,                               "image_cube",                           "imageCube",                    "imageLoad(image, ivec3(0, 0, 0))",                                                                     1 },
628                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32I>,                             "iimage_cube",                          "iimageCube",                   "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
629                 { &create<GL_TEXTURE_CUBE_MAP, GL_RGBA32UI>,                    "uimage_cube",                          "uimageCube",                   "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
630                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA8>,                               "image_2d_array",                       "image2DArray",                 "imageLoad(image, ivec3(0, 0, 0))",                                                                     1 },
631                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32I>,                             "iimage_2d_array",                      "iimage2DArray",                "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
632                 { &create<GL_TEXTURE_2D_ARRAY, GL_RGBA32UI>,                    "uimage_2d_array",                      "uimage2DArray",                "vec4(imageLoad(image, ivec3(0, 0, 0)))/255.0",                                         1 },
633         };
634
635         // Additional array containing entries for core gl
636         const SamplerCaseData coreArguments[] =
637         {
638                 { &create<GL_TEXTURE_BUFFER, GL_RGBA32F>,                               "sampler_buffer",                       "samplerBuffer",                "texelFetch(sampler, 1)",                                                                                       0 },
639                 { &create<GL_TEXTURE_BUFFER, GL_RGBA32I>,                               "isampler_buffer",                      "isamplerBuffer",               "vec4(texelFetch(sampler, 1))/255.0",                                                           0 },
640                 { &create<GL_TEXTURE_BUFFER, GL_RGBA32UI>,                              "usampler_buffer",                      "usamplerBuffer",               "vec4(texelFetch(sampler, 1))/255.0",                                                           0 },
641                 { &create<GL_TEXTURE_1D, GL_RGBA8>,                                             "sampler_1d",                           "sampler1D",                    "texture(sampler, coords.x)",                                                                           0 },
642                 { &create<GL_TEXTURE_1D, GL_DEPTH_COMPONENT16>,                 "sampler_1d_shadow",            "sampler1DShadow",              "vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",                     0 },
643                 { &create<GL_TEXTURE_1D_ARRAY, GL_RGBA8>,                               "sampler_1d_array",                     "sampler1DArray",               "texture(sampler, coords, 0.0)",                                                                        0 },
644                 { &create<GL_TEXTURE_1D_ARRAY, GL_DEPTH_COMPONENT16>,   "sampler_1d_array_shadow",      "sampler1DArrayShadow", "vec4(texture(sampler, vec3(coords, 0.0)), 0.0, 0.0, 0.0)",                     0 },
645         };
646
647         for (int i = 0; i < DE_LENGTH_OF_ARRAY(commonArguments); ++i)
648                 addChild(new SpecifiedLocationCase(m_context, commonArguments[i]));
649
650         glu::RenderContext& renderContext = m_context.getRenderContext();
651         glu::ContextType        contextType   = renderContext.getType();
652         if (!glu::isContextTypeES(contextType))
653         {
654                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreArguments); ++i)
655                         addChild(new SpecifiedLocationCase(m_context, coreArguments[i]));
656         }
657
658         addChild(new NegativeLocationCase(m_context));
659 }
660
661 } // glcts