1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2021 Google Inc.
6 * Copyright (c) 2021 The Khronos Group Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */ /*!
21 * \file glcCompressedFormatTests.cpp
22 * \brief Tests for OpenGL ES 3.1 and 3.2 compressed image formats
23 */ /*-------------------------------------------------------------------*/
24
25 #include "glcCompressedFormatTests.hpp"
26
27 #include "gluDefs.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30
31 #include "gluShaderProgram.hpp"
32 #include "gluPixelTransfer.hpp"
33 #include "gluStrUtil.hpp"
34
35 #include "tcuResource.hpp"
36 #include "tcuSurface.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuStringTemplate.hpp"
40
41 #include "deUniquePtr.hpp"
42
43 #include <algorithm>
44 #include <map>
45 #include <vector>
46 #include <memory>
47 #include <functional>
48 #include <fstream>
49
50 namespace glcts
51 {
52 namespace
53 {
54 using namespace glw;
55 using namespace glu;
56 using namespace tcu;
57 using namespace std;
58
59 struct FormatInfo
60 {
61 ApiType minApi;
62 const char* name;
63 GLenum internalFormat;
64 GLenum format;
65 GLenum sizedFormat;
66 bool issRGB;
67 IVec2 blockSize;
68 };
69
70 const ApiType gles31 = ApiType::es(3, 1);
71 const ApiType gles32 = ApiType::es(3, 2);
72
73 // List of compressed texture formats (table 8.17)
74 const FormatInfo compressedFormats[] =
75 {
76 // ETC (table C.2)
77 // minApi, name , internalFormat , format , sizedFormat , issRGB , blockSize
78 { gles31, "r11_eac" , GL_COMPRESSED_R11_EAC , GL_RED , GL_R8 , false , { 4, 4 } },
79 { gles31, "signed_r11_eac" , GL_COMPRESSED_SIGNED_R11_EAC , GL_RED , GL_R8 , false , { 4, 4 } },
80 { gles31, "rg11_eac" , GL_COMPRESSED_RG11_EAC , GL_RG , GL_RG8 , false , { 4, 4 } },
81 { gles31, "signed_rg11_eac" , GL_COMPRESSED_SIGNED_RG11_EAC , GL_RG , GL_RG8 , false , { 4, 4 } },
82 { gles31, "rgb8_etc2" , GL_COMPRESSED_RGB8_ETC2 , GL_RGB , GL_RGB8 , false , { 4, 4 } },
83 { gles31, "srgb8_etc2" , GL_COMPRESSED_SRGB8_ETC2 , GL_RGB , GL_SRGB8 , true , { 4, 4 } },
84 { gles31, "rgb8_punchthrough_alpha1_etc2" , GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , GL_RGBA , GL_RGBA8 , false , { 4, 4 } },
85 { gles31, "srgb8_punchthrough_alpha1_etc2" , GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 4, 4 } },
86 { gles31, "rgba8_etc2_eac" , GL_COMPRESSED_RGBA8_ETC2_EAC , GL_RGBA , GL_RGBA8 , false , { 4, 4 } },
87 { gles31, "srgb8_alpha8_etc2_eac" , GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 4, 4 } },
88 // ASTC (table C.1)
89 // minApi, name , internalFormat , format , sizedFormat , issRGB , blockSize
90 { gles32, "rgba_astc_4x4" , GL_COMPRESSED_RGBA_ASTC_4x4 , GL_RGBA , GL_RGBA8 , false , { 4, 4 } },
91 { gles32, "rgba_astc_5x4" , GL_COMPRESSED_RGBA_ASTC_5x4 , GL_RGBA , GL_RGBA8 , false , { 5, 4 } },
92 { gles32, "rgba_astc_5x5" , GL_COMPRESSED_RGBA_ASTC_5x5 , GL_RGBA , GL_RGBA8 , false , { 5, 5 } },
93 { gles32, "rgba_astc_6x5" , GL_COMPRESSED_RGBA_ASTC_6x5 , GL_RGBA , GL_RGBA8 , false , { 6, 5 } },
94 { gles32, "rgba_astc_6x6" , GL_COMPRESSED_RGBA_ASTC_6x6 , GL_RGBA , GL_RGBA8 , false , { 6, 6 } },
95 { gles32, "rgba_astc_8x5" , GL_COMPRESSED_RGBA_ASTC_8x5 , GL_RGBA , GL_RGBA8 , false , { 8, 5 } },
96 { gles32, "rgba_astc_8x6" , GL_COMPRESSED_RGBA_ASTC_8x6 , GL_RGBA , GL_RGBA8 , false , { 8, 6 } },
97 { gles32, "rgba_astc_8x8" , GL_COMPRESSED_RGBA_ASTC_8x8 , GL_RGBA , GL_RGBA8 , false , { 8, 8 } },
98 { gles32, "rgba_astc_10x5" , GL_COMPRESSED_RGBA_ASTC_10x5 , GL_RGBA , GL_RGBA8 , false , { 10, 5 } },
99 { gles32, "rgba_astc_10x6" , GL_COMPRESSED_RGBA_ASTC_10x6 , GL_RGBA , GL_RGBA8 , false , { 10, 6 } },
100 { gles32, "rgba_astc_10x8" , GL_COMPRESSED_RGBA_ASTC_10x8 , GL_RGBA , GL_RGBA8 , false , { 10, 8 } },
101 { gles32, "rgba_astc_10x10" , GL_COMPRESSED_RGBA_ASTC_10x10 , GL_RGBA , GL_RGBA8 , false , { 10, 10 } },
102 { gles32, "rgba_astc_12x10" , GL_COMPRESSED_RGBA_ASTC_12x10 , GL_RGBA , GL_RGBA8 , false , { 12, 10 } },
103 { gles32, "rgba_astc_12x12" , GL_COMPRESSED_RGBA_ASTC_12x12 , GL_RGBA , GL_RGBA8 , false , { 12, 12 } },
104 { gles32, "srgb8_alpha8_astc_4x4" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 4, 4 } },
105 { gles32, "srgb8_alpha8_astc_5x4" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 5, 4 } },
106 { gles32, "srgb8_alpha8_astc_5x5" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 5, 5 } },
107 { gles32, "srgb8_alpha8_astc_6x5" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 6, 5 } },
108 { gles32, "srgb8_alpha8_astc_6x6" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 6, 6 } },
109 { gles32, "srgb8_alpha8_astc_8x5" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 8, 5 } },
110 { gles32, "srgb8_alpha8_astc_8x6" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 8, 6 } },
111 { gles32, "srgb8_alpha8_astc_8x8" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 8, 8 } },
112 { gles32, "srgb8_alpha8_astc_10x5" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 10, 5 } },
113 { gles32, "srgb8_alpha8_astc_10x6" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 10, 6 } },
114 { gles32, "srgb8_alpha8_astc_10x8" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 10, 8 } },
115 { gles32, "srgb8_alpha8_astc_10x10" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 10, 10 } },
116 { gles32, "srgb8_alpha8_astc_12x10" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 12, 10 } },
117 { gles32, "srgb8_alpha8_astc_12x12" , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 , GL_RGBA , GL_SRGB8_ALPHA8 , true , { 12, 12 } },
118 };
119
120 struct UnsizedFormatInfo
121 {
122 GLenum format;
123 GLenum dataType;
124 };
125
126 const map<GLenum, UnsizedFormatInfo>
127 unsizedFormats =
128 {
129 { GL_RGBA32UI , { GL_RGBA_INTEGER , GL_UNSIGNED_INT } },
130 { GL_RGBA32I , { GL_RGBA_INTEGER , GL_INT } },
131 { GL_RGBA32F , { GL_RGBA , GL_FLOAT } },
132 { GL_RGBA16F , { GL_RGBA , GL_FLOAT } },
133 { GL_RG32F , { GL_RG , GL_FLOAT } },
134 { GL_RGBA16UI , { GL_RGBA_INTEGER , GL_UNSIGNED_SHORT } },
135 { GL_RG32UI , { GL_RG_INTEGER , GL_UNSIGNED_INT } },
136 { GL_RGBA16I , { GL_RGBA_INTEGER , GL_SHORT } },
137 { GL_RG32I , { GL_RG_INTEGER , GL_INT } }
138 };
139
140 const vector<pair<vector<GLenum>, vector<GLenum>>>
141 copyFormats =
142 {
143 // Table 16.3 - copy between compressed and uncompressed
144 // 128bit texel / block size
145 {
146 { GL_RGBA32UI, GL_RGBA32I, GL_RGBA32F },
147 {
148 GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_RG11_EAC,
149 GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4,
150 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6,
151 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8,
152 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8,
153 GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12,
154 }
155 },
156 // 64bit texel / block size
157 {
158 { GL_RGBA16F, GL_RG32F, GL_RGBA16UI, GL_RG32UI, GL_RGBA16I, GL_RG32I },
159 {
160 GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC,
161 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
162 }
163 },
164 // Table 16.4 - only entries for compressed formats are included
165 { { GL_COMPRESSED_R11_EAC , GL_COMPRESSED_SIGNED_R11_EAC }, {} },
166 { { GL_COMPRESSED_RG11_EAC , GL_COMPRESSED_SIGNED_RG11_EAC }, {} },
167 { { GL_COMPRESSED_RGB8_ETC2 , GL_COMPRESSED_SRGB8_ETC2 }, {} },
168 { { GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 }, {} },
169 { { GL_COMPRESSED_RGBA8_ETC2_EAC , GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC }, {} },
170 { { GL_COMPRESSED_RGBA_ASTC_4x4 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 }, {} },
171 { { GL_COMPRESSED_RGBA_ASTC_5x4 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 }, {} },
172 { { GL_COMPRESSED_RGBA_ASTC_5x5 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 }, {} },
173 { { GL_COMPRESSED_RGBA_ASTC_6x5 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 }, {} },
174 { { GL_COMPRESSED_RGBA_ASTC_6x6 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 }, {} },
175 { { GL_COMPRESSED_RGBA_ASTC_8x5 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 }, {} },
176 { { GL_COMPRESSED_RGBA_ASTC_8x6 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 }, {} },
177 { { GL_COMPRESSED_RGBA_ASTC_8x8 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 }, {} },
178 { { GL_COMPRESSED_RGBA_ASTC_10x5 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 }, {} },
179 { { GL_COMPRESSED_RGBA_ASTC_10x6 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 }, {} },
180 { { GL_COMPRESSED_RGBA_ASTC_10x8 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 }, {} },
181 { { GL_COMPRESSED_RGBA_ASTC_10x10 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 }, {} },
182 { { GL_COMPRESSED_RGBA_ASTC_12x10 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 }, {} },
183 { { GL_COMPRESSED_RGBA_ASTC_12x12 , GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 }, {} }
184 };
185
186 #include "glcCompressedFormatTests_data.inl"
187
188 const float vertexPositions[] =
189 {
190 -1.0f, -1.0f,
191 1.0f, -1.0f,
192 -1.0f, 1.0f,
193 1.0f, 1.0f,
194 };
195
196 const float vertexTexCoords[] =
197 {
198 0.0f, 0.0f,
199 1.0f, 0.0f,
200 0.0f, 1.0f,
201 1.0f, 1.0f,
202 };
203
204 const char* vertexShader =
205 "${VERSION}\n"
206 "in highp vec4 in_position;\n"
207 "in highp vec2 in_texCoord;\n"
208 "out highp vec2 v_texCoord;\n"
209 "void main (void)\n"
210 "{\n"
211 " gl_Position = in_position;\n"
212 " v_texCoord = in_texCoord;\n"
213 "}\n";
214
215 const char* fragmentShader =
216 "${VERSION}\n"
217 "uniform highp vec4 offset;\n"
218 "uniform highp vec4 scale;\n"
219 "uniform highp sampler2D sampler;\n"
220 "in highp vec2 v_texCoord;\n"
221 "layout(location = 0) out highp vec4 out_color;\n"
222 "void main (void)\n"
223 "{\n"
224 " out_color = texture(sampler, v_texCoord) * scale + offset;\n"
225 "}\n";
226
227 struct OffsetInfo
228 {
229 Vec4 offset;
230 Vec4 scale;
231 };
232
233 const OffsetInfo defaultOffset { { 0.0f, 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } };
234 const map<GLenum, OffsetInfo> offsets =
235 {
236 { GL_COMPRESSED_SIGNED_R11_EAC , { { 0.5f, 0.0f, 0.0f, 0.0f }, { 0.5f, 0.0f, 0.0f, 1.0f } } },
237 { GL_COMPRESSED_SIGNED_RG11_EAC , { { 0.5f, 0.5f, 0.0f, 0.0f }, { 0.5f, 0.5f, 0.0f, 1.0f } } }
238 };
239
240 class SharedData
241 {
242 public:
243 explicit SharedData (deqp::Context& context);
244 virtual ~SharedData ();
245
246 void init();
247 void deinit();
248
249 GLuint programId() const;
250 GLuint texId(int index) const;
251 GLuint vaoId() const;
252 GLuint offsetLoc() const;
253 GLuint scaleLoc() const;
254
255 private:
256 deqp::Context& m_context;
257 size_t m_initCount;
258 vector<GLuint> m_texIds;
259 shared_ptr<ShaderProgram> m_program;
260 GLuint m_vaoId;
261 GLuint m_vboIds[2];
262 GLuint m_offsetLoc;
263 GLuint m_scaleLoc;
264
265 SharedData (const SharedData& other) = delete;
266 SharedData& operator= (const SharedData& other) = delete;
267 };
268
SharedData(deqp::Context & context)269 SharedData::SharedData (deqp::Context& context)
270 : m_context(context)
271 , m_initCount(0)
272 {
273 }
274
~SharedData()275 SharedData::~SharedData ()
276 {
277 DE_ASSERT(m_initCount <= 0);
278 }
279
init()280 void SharedData::init ()
281 {
282 ++m_initCount;
283 if (m_initCount > 1)
284 return;
285
286 const auto& gl = m_context.getRenderContext().getFunctions();
287 // program
288 const bool supportsES32 = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
289 const auto glslVersion = getGLSLVersionDeclaration(supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES);
290 const auto args = map<string, string> { { "VERSION", glslVersion } };
291 const auto vs = StringTemplate(vertexShader).specialize(args);
292 const auto fs = StringTemplate(fragmentShader).specialize(args);
293 m_program = make_shared<ShaderProgram>(m_context.getRenderContext(), ProgramSources() << glu::VertexSource(vs) << glu::FragmentSource(fs));
294 if (!m_program->isOk())
295 throw runtime_error("Compiling shader program failed");
296
297 const auto program = m_program->getProgram();
298 const auto positionLoc = gl.getAttribLocation(program, "in_position");
299 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
300 const auto texCoordLoc = gl.getAttribLocation(program, "in_texCoord");
301 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
302 m_offsetLoc = gl.getUniformLocation(program, "offset");
303 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
304 m_scaleLoc = gl.getUniformLocation(program, "scale");
305 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
306
307 // buffers
308 gl.genBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds);
309 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
310
311 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
312 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
313
314 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
315 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
316
317 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
318 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
319
320 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexTexCoords), vertexTexCoords, GL_STATIC_DRAW);
321 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
322
323 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
324 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
325
326 // vertex array objects
327 gl.genVertexArrays(1, &m_vaoId);
328 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed");
329
330 gl.bindVertexArray(m_vaoId);
331 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
332
333 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
334 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
335
336 gl.enableVertexAttribArray(positionLoc);
337 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed");
338
339 gl.vertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
340 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed");
341
342 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
343 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
344
345 gl.enableVertexAttribArray(texCoordLoc);
346 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed");
347
348 gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
349 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed");
350
351 gl.bindVertexArray(0);
352 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
353 }
354
deinit()355 void SharedData::deinit ()
356 {
357 DE_ASSERT(m_initCount > 0);
358 --m_initCount;
359
360 if (m_initCount > 0)
361 return;
362
363 const auto& gl = m_context.getRenderContext().getFunctions();
364 gl.deleteBuffers(1, &m_vaoId);
365 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed");
366
367 gl.deleteBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds);
368 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed");
369
370 gl.deleteTextures(m_texIds.size(), m_texIds.data());
371 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
372 }
373
programId() const374 GLuint SharedData::programId () const
375 {
376 return m_program->getProgram();
377 }
378
texId(int index) const379 GLuint SharedData::texId (int index) const
380 {
381 return m_texIds[index];
382 }
383
vaoId() const384 GLuint SharedData::vaoId () const
385 {
386 return m_vaoId;
387 }
388
offsetLoc() const389 GLuint SharedData::offsetLoc () const
390 {
391 return m_offsetLoc;
392 }
393
scaleLoc() const394 GLuint SharedData::scaleLoc () const
395 {
396 return m_scaleLoc;
397 }
398
399 struct {
400 const GLsizei width = 8;
401 const GLsizei height = 8;
402 const GLsizei depth = 6;
403 const vector<deUint8> data =
404 {
405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
407 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
408 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
409 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
410 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
411 };
412 } invalidTexture;
413
414 struct ApiTestContext
415 {
416 TestLog& log;
417 const glw::Functions& gl;
418 vector<GLuint>& texIds;
419 vector<GLuint>& bufferIds;
420 const Archive& archive;
421
422 void bindTexture(GLenum target, GLuint texId);
423 };
424
bindTexture(GLenum target,GLuint texId)425 void ApiTestContext::bindTexture (GLenum target, GLuint texId)
426 {
427 gl.bindTexture(target, texId);
428 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
429 }
430
431 typedef function<void (ApiTestContext&)> ApiCaseFn;
432
433 struct ApiCaseStep
434 {
435 ApiCaseFn code;
436 GLenum expectedError;
437 };
438
439 typedef function<void (deqp::Context&, vector<ApiCaseStep>&)> ApiCaseStepGeneratorFn;
440
441 struct ApiCaseParams
442 {
443 ApiType minApi;
444 string name;
445 string description;
446 size_t texIdsCount;
447 size_t bufferIdsCount;
448 vector<ApiCaseStep> steps;
449 ApiCaseStepGeneratorFn stepsGenerator;
450 };
451
452 const GLenum cubemapFaces[] =
453 {
454 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
455 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
456 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
457 };
458
459 struct ImageInfo
460 {
461 GLuint width;
462 GLuint height;
463 vector<GLubyte> data;
464 };
465
loadImage(const Archive & archive,GLenum format,size_t imageIndex)466 ImageInfo loadImage (const Archive& archive, GLenum format, size_t imageIndex)
467 {
468 const auto data = imageData.find(format);
469 if (data == imageData.end())
470 {
471 ostringstream msg;
472 msg << "No image data found for format: " << format;
473 TCU_FAIL(msg.str().c_str());
474 }
475 if (imageIndex >= data->second.size())
476 {
477 ostringstream msg;
478 msg << "Image index out of range for format: " << format << " index: " << imageIndex;
479 TCU_FAIL(msg.str().c_str());
480 }
481 const de::UniquePtr<Resource> resource (archive.getResource(data->second[imageIndex].path.c_str()));
482 if (!resource || resource->getSize() <= 0)
483 TCU_FAIL("Failed to read file: "+data->second[imageIndex].path);
484 ImageInfo result;
485 result.width = data->second[imageIndex].width;
486 result.height = data->second[imageIndex].height;
487 const auto size = resource->getSize();
488 result.data.resize(size);
489 resource->setPosition(0);
490 resource->read(result.data.data(), size);
491 return result;
492 }
493
setTextureParameters(const glw::Functions & gl,GLenum target)494 void setTextureParameters (const glw::Functions& gl, GLenum target)
495 {
496 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
497 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
498 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
499 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
500 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
501 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
502 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
503 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
504 const auto repeatMode = GL_CLAMP_TO_EDGE;
505 gl.texParameteri(target, GL_TEXTURE_WRAP_S, repeatMode);
506 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
507 gl.texParameteri(target, GL_TEXTURE_WRAP_T, repeatMode);
508 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
509 gl.texParameteri(target, GL_TEXTURE_WRAP_R, repeatMode);
510 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
511 }
512
513 ApiCaseParams apiTests[] =
514 {
515 {
516 gles31, // ApiType minApi;
517 "invalid_target", // string name;
518 "Invalid texture target for compressed format", // string description;
519 1, // size_t texIdsCount;
520 0, // size_t bufferIdsCount;
521 { // vector<ApiCaseStep> steps;
522 {
523 [](ApiTestContext& context)
__anon27e7ac530302() 524 {
525 context.bindTexture(GL_TEXTURE_3D, context.texIds[0]);
526 },
527 GL_NO_ERROR
528 },
529 {
530 [](ApiTestContext& context)
__anon27e7ac530402() 531 {
532 context.gl.compressedTexImage2D(GL_TEXTURE_3D, 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width, invalidTexture.height, 0, invalidTexture.data.size(), invalidTexture.data.data());
533 },
534 GL_INVALID_ENUM
535 },
536 {
537 [](ApiTestContext& context)
__anon27e7ac530502() 538 {
539 context.gl.compressedTexSubImage2D(GL_TEXTURE_3D, 0, 0, 0, invalidTexture.width, invalidTexture.height, GL_COMPRESSED_RGB8_ETC2, invalidTexture.data.size(), invalidTexture.data.data());
540 },
541 GL_INVALID_ENUM
542 },
543 },
544 DE_NULL, // ApiCaseStepGeneratorFn stepsGenerator;
545 },
546 {
547 gles31, // ApiType minApi;
548 "invalid_width_or_height", // string name;
549 "Different values for width and height for cubemap texture target", // string description;
550 1, // size_t texIdsCount;
551 0, // size_t bufferIdsCount;
552 { // vector<ApiCaseStep> steps;
553 {
554 [](ApiTestContext& context)
__anon27e7ac530602() 555 {
556 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
557 },
558 GL_NO_ERROR
559 }
560 },
561 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac530702() 562 {
563 steps.push_back(
564 {
565 [](ApiTestContext& context)
566 {
567 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
568 },
569 GL_NO_ERROR
570 });
571 for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapFaces); ++i)
572 {
573 steps.push_back(
574 {
575 [i](ApiTestContext& context)
576 {
577 context.gl.compressedTexImage2D(cubemapFaces[i], 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width - i % 2, invalidTexture.height - (i + 1) % 2, 0, invalidTexture.data.size(), invalidTexture.data.data());
578 },
579 GL_INVALID_VALUE
580 });
581 steps.push_back(
582 {
583 [i](ApiTestContext& context)
584 {
585 const auto format = GL_COMPRESSED_RGB8_ETC2;
586 const GLsizei blockSize = 4;
587 const GLsizei blockDataSize = 8;
588 const auto data = loadImage(context.archive, format, 0);
589 const auto& gl = context.gl;
590 gl.compressedTexImage2D(cubemapFaces[i], 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
591 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
592
593 const auto updateWidth = invalidTexture.width - (i % 2) * blockSize;
594 const auto updateHeight = invalidTexture.height - ((i + 1) % 2) * blockSize;
595 const auto updateDataSize = (updateWidth / blockSize) * (updateHeight / blockSize) * blockDataSize;
596 DE_ASSERT(updateDataSize <= invalidTexture.data.size());
597 context.gl.compressedTexSubImage2D(cubemapFaces[i], 0, 0, 0, updateWidth, updateHeight, format, updateDataSize, invalidTexture.data.data());
598 },
599 GL_NO_ERROR
600 });
601 }
602 }
603 },
604 {
605 gles32, // ApiType minApi;
606 "invalid_width_or_height_array", // string name;
607 "Different values for width and height for cubemap texture target", // string description;
608 1, // size_t texIdsCount;
609 0, // size_t bufferIdsCount;
610 { // vector<ApiCaseStep> steps;
611 {
612 [](ApiTestContext& context)
__anon27e7ac530b02() 613 {
614 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
615 },
616 GL_NO_ERROR
617 },
618 {
619 [](ApiTestContext& context)
__anon27e7ac530c02() 620 {
621 context.gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width - 1, invalidTexture.height, 6, 0, invalidTexture.data.size(), invalidTexture.data.data());
622 },
623 GL_INVALID_VALUE
624 }
625 },
626 DE_NULL, // ApiCaseStepGeneratorFn stepsGenerator;
627 },
628 {
629 gles31, // ApiType minApi;
630 "invalid_size_value_negative", // string name;
631 "Negative width, height or imageSize for compressed texture image", // string description;
632 3, // size_t texIdsCount;
633 0, // size_t bufferIdsCount;
634 {}, // vector<ApiCaseStep> steps;
635 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac530d02() 636 {
637 auto format = GL_COMPRESSED_RGB8_ETC2;
638 const auto data = loadImage(testContext.getTestContext().getArchive(), format, 0);
639 steps.push_back(
640 {
641 [format, data](ApiTestContext& context)
642 {
643 DE_ASSERT(context.texIds.size() >= 3);
644 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
645 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, -1, 0, data.data.size(), data.data.data());
646 },
647 GL_INVALID_VALUE
648 });
649 steps.push_back(
650 {
651 [format, data](ApiTestContext& context)
652 {
653 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
654 },
655 GL_NO_ERROR
656 });
657 steps.push_back(
658 {
659 [format, data](ApiTestContext& context)
660 {
661 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, data.width, -1, format, data.data.size(), data.data.data());
662 },
663 GL_INVALID_VALUE
664 });
665 steps.push_back(
666 {
667 [format, data](ApiTestContext& context)
668 {
669 DE_ASSERT(context.texIds.size() >= 3);
670 context.bindTexture(GL_TEXTURE_2D, context.texIds[1]);
671 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, -276, data.height, 0, data.data.size(), data.data.data());
672 },
673 GL_INVALID_VALUE
674 });
675 steps.push_back(
676 {
677 [format, data](ApiTestContext& context)
678 {
679 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
680 },
681 GL_NO_ERROR
682 });
683 steps.push_back(
684 {
685 [format, data](ApiTestContext& context)
686 {
687 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, -276, data.height, format, data.data.size(), data.data.data());
688 },
689 GL_INVALID_VALUE
690 });
691 steps.push_back(
692 {
693 [format, data](ApiTestContext& context)
694 {
695 DE_ASSERT(context.texIds.size() >= 3);
696 context.bindTexture(GL_TEXTURE_2D, context.texIds[2]);
697 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, -66543, data.data.data());
698 },
699 GL_INVALID_VALUE
700 });
701 steps.push_back(
702 {
703 [format, data](ApiTestContext& context)
704 {
705 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
706 },
707 GL_NO_ERROR
708 });
709 steps.push_back(
710 {
711 [format, data](ApiTestContext& context)
712 {
713 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, data.width, data.height, format, -66543, data.data.data());
714 },
715 GL_INVALID_VALUE
716 });
717 }
718 },
719 {
720 gles31, // ApiType minApi;
721 "invalid_border_nonzero", // string name;
722 "Non zero border values are not supported", // string description;
723 2, // size_t texIdsCount;
724 0, // size_t bufferIdsCount;
725 { // vector<ApiCaseStep> steps;
726 {
727 [](ApiTestContext& context)
__anon27e7ac531702() 728 {
729 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
730 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width, invalidTexture.height, 1, invalidTexture.data.size(), invalidTexture.data.data());
731 },
732 GL_INVALID_VALUE
733 },
734 },
735 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac531802() 736 {
737 for(size_t j = 0; j < DE_LENGTH_OF_ARRAY(cubemapFaces); ++j)
738 steps.push_back(
739 {
740 [j](ApiTestContext& context)
741 {
742 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[1]);
743 context.gl.compressedTexImage2D(cubemapFaces[j], 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width, invalidTexture.height, 1, invalidTexture.data.size(), invalidTexture.data.data());
744 },
745 GL_INVALID_VALUE
746 });
747 },
748 },
749 {
750 gles32, // ApiType minApi;
751 "invalid_border_nonzero_array", // string name;
752 "Non zero border values are not supported", // string description;
753 1, // size_t texIdsCount;
754 0, // size_t bufferIdsCount;
755 { // vector<ApiCaseStep> steps;
756 {
757 [](ApiTestContext& context)
__anon27e7ac531a02() 758 {
759 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
760 context.gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_RGB8_ETC2, invalidTexture.width, invalidTexture.height, invalidTexture.depth, 1, invalidTexture.data.size(), invalidTexture.data.data());
761 },
762 GL_INVALID_VALUE
763 },
764 },
765 DE_NULL, // ApiCaseStepGeneratorFn stepsGenerator;
766 },
767 {
768 gles31, // ApiType minApi;
769 "invalid_format_mismatch", // string name;
770 "Subimage format differs from previously specified texture format", // string description;
771 1, // size_t texIdsCount;
772 0, // size_t bufferIdsCount;
773 { // vector<ApiCaseStep> steps;
774 {
775 [](ApiTestContext& context)
__anon27e7ac531b02() 776 {
777 const auto& gl = context.gl;
778 const auto format0 = GL_COMPRESSED_RGB8_ETC2;
779 const auto data0 = loadImage(context.archive, format0, 0);
780 const auto format1 = GL_COMPRESSED_R11_EAC;
781 const auto data1 = loadImage(context.archive, format1, 0);
782 DE_ASSERT(data0.width == data1.width && data0.height == data1.height);
783
784 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
785
786 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format0, data0.width, data0.height, 0, data0.data.size(), data0.data.data());
787 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
788 gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, data1.width, data1.height, format1, data1.data.size(), data1.data.data());
789 },
790 GL_INVALID_OPERATION
791 },
792 },
793 DE_NULL, // ApiCaseStepGeneratorFn stepsGenerator;
794 },
795 {
796 gles31, // ApiType minApi;
797 "invalid_target_3d", // string name;
798 "Invalid texture target for compressed texture", // string description;
799 1, // size_t texIdsCount;
800 0, // size_t bufferIdsCount;
801 {}, // vector<ApiCaseStep> steps;
802 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac531c02() 803 {
804 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
805 {
806 if (!contextSupports(testContext.getRenderContext().getType(), compressedFormats[i].minApi))
807 continue;
808
809 const auto data = loadImage(testContext.getTestContext().getArchive(), compressedFormats[i].internalFormat, 0);
810 steps.push_back(
811 {
812 [](ApiTestContext& context)
813 {
814 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
815 },
816 GL_NO_ERROR
817 });
818 steps.push_back(
819 {
820 [i, data](ApiTestContext& context)
821 {
822 context.gl.compressedTexImage3D(GL_TEXTURE_2D, 0, compressedFormats[i].internalFormat, data.width, data.height, 1, 0, data.data.size(), data.data.data());
823 },
824 GL_INVALID_ENUM
825 });
826 steps.push_back(
827 {
828 [i, data](ApiTestContext& context)
829 {
830 context.gl.compressedTexSubImage3D(GL_TEXTURE_2D, 0, 0, 0, 0, data.width, data.height, 1, compressedFormats[i].internalFormat, data.data.size(), data.data.data());
831 },
832 GL_INVALID_ENUM
833 });
834 }
835 }
836 },
837 {
838 gles31, // ApiType minApi;
839 "texstorage_accepts_compressed_format", // string name;
840 "TexStorage should accept compressed format", // string description;
841 DE_LENGTH_OF_ARRAY(compressedFormats), // size_t texIdsCount;
842 0, // size_t bufferIdsCount;
843 {}, // vector<ApiCaseStep> steps;
844 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac532002() 845 {
846 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
847 {
848 if (!contextSupports(testContext.getRenderContext().getType(), compressedFormats[i].minApi))
849 continue;
850
851 steps.push_back(
852 {
853 [i](ApiTestContext& context)
854 {
855 const auto& gl = context.gl;
856 const size_t textureWidth = 240;
857 const size_t textureHeight = 240;
858 context.bindTexture(GL_TEXTURE_2D, context.texIds[i]);
859 gl.texStorage2D(GL_TEXTURE_2D, 1, compressedFormats[i].internalFormat, textureWidth, textureHeight);
860 },
861 GL_NO_ERROR
862 });
863 }
864 }
865 },
866 {
867 gles31, // ApiType minApi;
868 "invalid_teximage_with_compressed_format", // string name;
869 "TexImage should not accept compressed format", // string description;
870 2, // size_t texIdsCount;
871 0, // size_t bufferIdsCount;
872 {}, // vector<ApiCaseStep> steps;
873 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac532202() 874 {
875 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
876 {
877 const auto format = compressedFormats[i];
878 if (!contextSupports(testContext.getRenderContext().getType(), format.minApi))
879 continue;
880
881 const auto data = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 0);
882 steps.push_back(
883 {
884 [format, data](ApiTestContext& context)
885 {
886 const auto& gl = context.gl;
887 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
888 gl.texImage2D(GL_TEXTURE_2D, 0, format.internalFormat, data.width, data.height, 0, format.format, GL_UNSIGNED_BYTE, data.data.data());
889 },
890 GL_INVALID_VALUE
891 });
892 steps.push_back(
893 {
894 [format, data](ApiTestContext& context)
895 {
896 const auto& gl = context.gl;
897 context.bindTexture(GL_TEXTURE_3D, context.texIds[1]);
898 gl.texImage3D(GL_TEXTURE_3D, 0, format.internalFormat, data.width, data.height, 1, 0, format.format, GL_UNSIGNED_BYTE, data.data.data());
899 },
900 GL_INVALID_VALUE
901 });
902 }
903 }
904 },
905 {
906 gles31, // ApiType minApi;
907 "invalid_format", // string name;
908 "Uncompressed internal format for compressed texture", // string description;
909 2, // size_t texIdsCount;
910 0, // size_t bufferIdsCount;
911 { // vector<ApiCaseStep> steps;
912 {
913 [](ApiTestContext& context)
__anon27e7ac532502() 914 {
915 context.bindTexture(GL_TEXTURE_2D, context.texIds[1]);
916 },
917 GL_NO_ERROR
918 },
919 {
920 [](ApiTestContext& context)
__anon27e7ac532602() 921 {
922 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, invalidTexture.width, invalidTexture.height, 0, invalidTexture.data.size(), invalidTexture.data.data());
923 },
924 GL_INVALID_ENUM
925 },
926 {
927 [](ApiTestContext& context)
__anon27e7ac532702() 928 {
929 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, invalidTexture.width, invalidTexture.height, GL_RGB, invalidTexture.data.size(), invalidTexture.data.data());
930 },
931 GL_INVALID_OPERATION
932 },
933 {
934 [](ApiTestContext& context)
__anon27e7ac532802() 935 {
936 const GLenum format = GL_COMPRESSED_RGB8_ETC2;
937 const auto data = loadImage(context.archive, format, 0);
938 const auto& gl = context.gl;
939 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
940 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
941
942 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, invalidTexture.width, invalidTexture.height, GL_RGB, invalidTexture.data.size(), invalidTexture.data.data());
943 },
944 GL_INVALID_OPERATION
945 },
946 {
947 [](ApiTestContext& context)
__anon27e7ac532902() 948 {
949 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
950 },
951 GL_NO_ERROR
952 }
953 },
954 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac532a02() 955 {
956 for(size_t j = 0; j < DE_LENGTH_OF_ARRAY(cubemapFaces); ++j)
957 {
958 steps.push_back(
959 {
960 [j](ApiTestContext& context)
961 {
962 context.gl.compressedTexImage2D(cubemapFaces[j], 0, GL_RGB, invalidTexture.width, invalidTexture.height, 0, invalidTexture.data.size(), invalidTexture.data.data());
963 },
964 GL_INVALID_ENUM
965 });
966 steps.push_back(
967 {
968 [j](ApiTestContext& context)
969 {
970 const GLenum format = GL_COMPRESSED_RGB8_ETC2;
971 const auto data = loadImage(context.archive, format, 0);
972 const auto& gl = context.gl;
973 gl.compressedTexImage2D(cubemapFaces[j], 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
974 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
975
976 context.gl.compressedTexSubImage2D(cubemapFaces[j], 0, 0, 0, invalidTexture.width, invalidTexture.height, GL_RGB, invalidTexture.data.size(), invalidTexture.data.data());
977 },
978 GL_INVALID_OPERATION
979 });
980 }
981 }
982 },
983 {
984 gles32, // ApiType minApi;
985 "invalid_format_array", // string name;
986 "Uncompressed internal format for compressed texture", // string description;
987 1, // size_t texIdsCount;
988 0, // size_t bufferIdsCount;
989 { // vector<ApiCaseStep> steps;
990 {
991 [](ApiTestContext& context)
__anon27e7ac532d02() 992 {
993 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
994 },
995 GL_NO_ERROR
996 },
997 {
998 [](ApiTestContext& context)
__anon27e7ac532e02() 999 {
1000 context.gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGB, invalidTexture.width, invalidTexture.height, 6, 0, invalidTexture.data.size(), invalidTexture.data.data());
1001 },
1002 GL_INVALID_ENUM
1003 },
1004 {
1005 [](ApiTestContext& context)
__anon27e7ac532f02() 1006 {
1007 const GLenum format = GL_COMPRESSED_RGB8_ETC2;
1008 const auto data = loadImage(context.archive, format, 0);
1009 const auto& gl = context.gl;
1010 vector<GLubyte> arrayData;
1011 arrayData.reserve(6 * data.data.size());
1012 for(size_t k = 0; k < 6; ++k)
1013 std::copy(data.data.begin(), data.data.end(), std::back_inserter(arrayData));
1014
1015 context.gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, format, data.width, data.height, 6, 0, arrayData.size(), arrayData.data());
1016 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D() failed");
1017
1018 context.gl.compressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, invalidTexture.width, invalidTexture.height, 6, GL_RGB, invalidTexture.data.size(), invalidTexture.data.data());context.gl.compressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, invalidTexture.width, invalidTexture.height, 6, GL_RGB, invalidTexture.data.size(), invalidTexture.data.data());
1019 },
1020 GL_INVALID_OPERATION
1021 }
1022 },
1023 DE_NULL // ApiCaseStepGeneratorFn stepsGenerator;
1024 },
1025 {
1026 gles31, // ApiType minApi;
1027 "invalid_too_small_unpack_buffer", // string name;
1028 "Pixel unpack buffer with not enough space for required texture data", // string description;
1029 1, // size_t texIdsCount;
1030 1, // size_t bufferIdsCount;
1031 { // vector<ApiCaseStep> steps;
1032 {
1033 [](ApiTestContext& context)
__anon27e7ac533002() 1034 {
1035 const GLenum format = GL_COMPRESSED_RGB8_ETC2;
1036 const auto data = loadImage(context.archive, format, 0);
1037 const auto& gl = context.gl;
1038
1039 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1040 gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, context.bufferIds[0]);
1041 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
1042 gl.bufferData(GL_PIXEL_UNPACK_BUFFER, data.data.size() / 2, data.data.data(), GL_STATIC_READ);
1043 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
1044 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), 0);
1045 },
1046 GL_INVALID_OPERATION
1047 },
1048 {
1049 [](ApiTestContext& context)
__anon27e7ac533102() 1050 {
1051 const GLenum format = GL_COMPRESSED_RGB8_ETC2;
1052 const auto data = loadImage(context.archive, format, 0);
1053 const auto& gl = context.gl;
1054
1055 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1056 gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1057 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format, data.width, data.height, 0, data.data.size(), data.data.data());
1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1059 gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, context.bufferIds[0]);
1060 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
1061 gl.bufferData(GL_PIXEL_UNPACK_BUFFER, data.data.size() / 2, data.data.data(), GL_STATIC_READ);
1062 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
1063 gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, data.width, data.height, format, data.data.size(), 0);
1064 },
1065 GL_INVALID_OPERATION
1066 }
1067 },
1068 DE_NULL // ApiCaseStepGeneratorFn stepsGenerator;
1069 },
1070 {
1071 gles31, // ApiType minApi;
1072 "invalid_inconsistent_data_size", // string name;
1073 "Data size is not consistent with texture internal format and dimensions", // string description;
1074 1, // size_t texIdsCount;
1075 0, // size_t bufferIdsCount;
1076 {}, // vector<ApiCaseStep> steps;
1077 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac533202() 1078 {
1079 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
1080 {
1081 const auto& format = compressedFormats[i];
1082 if (!contextSupports(testContext.getRenderContext().getType(), format.minApi))
1083 continue;
1084
1085 const auto data0 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 0);
1086 const auto data1 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 1);
1087
1088 steps.push_back(
1089 {
1090 [format, data0](ApiTestContext& context)
1091 {
1092 const auto& gl = context.gl;
1093 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1094 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, data0.width - 12, data0.height - 12, 0, data0.data.size(), data0.data.data());
1095 },
1096 GL_INVALID_VALUE
1097 });
1098 }
1099 }
1100 },
1101 {
1102 gles32, // ApiType minApi;
1103 "invalid_inconsistent_data_size_array", // string name;
1104 "Data size is not consistent with texture internal format and dimensions", // string description;
1105 2, // size_t texIdsCount;
1106 0, // size_t bufferIdsCount;
1107 {}, // vector<ApiCaseStep> steps;
1108 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac533402() 1109 {
1110 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
1111 {
1112 const auto& format = compressedFormats[i];
1113 if (!contextSupports(testContext.getRenderContext().getType(), format.minApi))
1114 continue;
1115
1116 const auto data0 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 0);
1117 const auto data1 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 1);
1118 steps.push_back(
1119 {
1120 [format, data0](ApiTestContext& context)
1121 {
1122 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1123 },
1124 GL_NO_ERROR
1125 });
1126 for(size_t j = 0; j < DE_LENGTH_OF_ARRAY(cubemapFaces); ++j)
1127 steps.push_back(
1128 {
1129 [j, format, data0](ApiTestContext& context)
1130 {
1131 context.gl.compressedTexImage2D(cubemapFaces[j], 0, format.internalFormat, data0.width, data0.height, 0, data0.data.size(), data0.data.data());
1132 },
1133 GL_NO_ERROR
1134 });
1135 steps.push_back(
1136 {
1137 [format, data0](ApiTestContext& context)
1138 {
1139 vector<GLubyte> arrayData;
1140 arrayData.reserve(6 * data0.data.size());
1141 for(size_t k = 0; k < 6; ++k)
1142 std::copy(data0.data.begin(), data0.data.end(), std::back_inserter(arrayData));
1143 context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[1]);
1144 context.gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, format.internalFormat, data0.width, data0.height, 6, 0, arrayData.size(), arrayData.data());
1145 },
1146 GL_NO_ERROR
1147 });
1148 steps.push_back(
1149 {
1150 [format, data1](ApiTestContext& context)
1151 {
1152 context.gl.compressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, data1.width, data1.height, 1, format.internalFormat, data1.data.size() - 1, data1.data.data());
1153 },
1154 GL_INVALID_VALUE
1155 });
1156 }
1157 }
1158 },
1159 {
1160 gles31, // ApiType minApi;
1161 "invalid_offset_or_size", // string name;
1162 "Offset or image size not aligned with block size", // string description;
1163 1, // size_t texIdsCount;
1164 0, // size_t bufferIdsCount;
1165 {}, // vector<ApiCaseStep> steps;
1166 [](deqp::Context& testContext, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac533902() 1167 {
1168 for(auto i = 0; i < DE_LENGTH_OF_ARRAY(compressedFormats); ++i)
1169 {
1170 const auto& format = compressedFormats[i];
1171 if (!contextSupports(testContext.getRenderContext().getType(), format.minApi))
1172 continue;
1173
1174 const auto data0 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 0);
1175 const auto data1 = loadImage(testContext.getTestContext().getArchive(), format.internalFormat, 1);
1176 steps.push_back(
1177 {
1178 [format, data0](ApiTestContext& context)
1179 {
1180 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1181 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format.internalFormat, data0.width, data0.height, 0, data0.data.size(), data0.data.data());
1182 },
1183 GL_NO_ERROR
1184 });
1185 steps.push_back(
1186 {
1187 [format, data1](ApiTestContext& context)
1188 {
1189 context.gl.compressedTexImage2D(GL_TEXTURE_2D, 1, format.internalFormat, data1.width, data1.height, 0, data1.data.size(), data1.data.data());
1190 },
1191 GL_NO_ERROR
1192 });
1193 steps.push_back(
1194 {
1195 [format, data1](ApiTestContext& context)
1196 {
1197 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, format.blockSize.x() - 2, 0, data1.width, data1.height, format.internalFormat, data1.data.size(), data1.data.data());
1198 },
1199 GL_INVALID_OPERATION
1200 });
1201 steps.push_back(
1202 {
1203 [format, data1](ApiTestContext& context)
1204 {
1205 context.gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, format.blockSize.y() - 2, data1.width, data1.height, format.internalFormat, data1.data.size(), data1.data.data());
1206 },
1207 GL_INVALID_OPERATION
1208 });
1209 }
1210 }
1211 },
1212 {
1213 gles32, // ApiType minApi;
1214 "copy_compressed_to_uncompressed", // string name;
1215 "Copying pixels from compressed to uncompressed texture", // string description;
1216 2, // size_t texIdsCount;
1217 0, // size_t bufferIdsCount;
1218 {}, // vector<ApiCaseStep> steps;
1219 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac533e02() 1220 {
1221 for(const auto& format : copyFormats)
1222 {
1223 if (format.second.empty())
1224 continue;
1225 for(const auto& uncompressedFormat : format.first)
1226 {
1227 for(const auto& compressedFormat : format.second)
1228 {
1229 steps.push_back(
1230 {
1231 [uncompressedFormat, compressedFormat](ApiTestContext& context)
1232 {
1233 const auto& gl = context.gl;
1234 const auto& image = imageData.at(compressedFormat);
1235 const auto& unsizedInfo = unsizedFormats.at(uncompressedFormat);
1236 const auto textureData = loadImage(context.archive, compressedFormat, 0);
1237 const auto compressedInfo = find_if(begin(compressedFormats), end(compressedFormats), [compressedFormat](const FormatInfo& fmt) { return fmt.internalFormat == compressedFormat; });
1238
1239 DE_ASSERT((GLsizei)textureData.width == image[0].width && (GLsizei)textureData.height == image[0].height);
1240 DE_ASSERT(compressedInfo != end(compressedFormats));
1241
1242 const auto targetWidth = image[0].width / compressedInfo->blockSize[0];
1243 const auto targetHeight = image[0].height / compressedInfo->blockSize[1];
1244
1245 context.log
1246 << TestLog::Message
1247 << "Copying from " << getTextureFormatStr(compressedFormat).toString() << " " << image[0].width << "x" << image[0].height
1248 << " to " << getTextureFormatStr(uncompressedFormat).toString() << " " << targetWidth << "x" << targetHeight
1249 << TestLog::EndMessage;
1250
1251 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1252 gl.texImage2D(GL_TEXTURE_2D, 0, uncompressedFormat, targetWidth, targetHeight, 0, unsizedInfo.format, unsizedInfo.dataType, 0);
1253 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() failed");
1254 setTextureParameters(context.gl, GL_TEXTURE_2D);
1255
1256 context.bindTexture(GL_TEXTURE_2D, context.texIds[1]);
1257 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, compressedFormat, image[0].width, image[0].height, 0, textureData.data.size(), textureData.data.data());
1258 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1259 setTextureParameters(context.gl, GL_TEXTURE_2D);
1260
1261 context.bindTexture(GL_TEXTURE_2D, 0);
1262
1263 gl.copyImageSubData(context.texIds[1], GL_TEXTURE_2D, 0, 0, 0, 0, context.texIds[0], GL_TEXTURE_2D, 0, 0, 0, 0, image[0].width, image[0].height, 1);
1264 },
1265 GL_NO_ERROR
1266 });
1267 }
1268 }
1269 }
1270 }
1271 },
1272 {
1273 gles32, // ApiType minApi;
1274 "copy_uncompressed_to_compressed", // string name;
1275 "Copying pixels from uncompressed to compressed texture", // string description;
1276 2, // size_t texIdsCount;
1277 0, // size_t bufferIdsCount;
1278 {}, // vector<ApiCaseStep> steps;
1279 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac534102() 1280 {
1281 for(const auto& format : copyFormats)
1282 {
1283 if (format.second.empty())
1284 continue;
1285 for(const auto& uncompressedFormat : format.first)
1286 {
1287 for(const auto& compressedFormat : format.second)
1288 {
1289 steps.push_back(
1290 {
1291 [uncompressedFormat, compressedFormat](ApiTestContext& context)
1292 {
1293 const auto& gl = context.gl;
1294 const auto& image = imageData.at(compressedFormat);
1295 const auto& unsizedInfo = unsizedFormats.at(uncompressedFormat);
1296 const auto textureData = loadImage(context.archive, compressedFormat, 0);
1297 const auto compressedInfo = find_if(begin(compressedFormats), end(compressedFormats), [compressedFormat](const FormatInfo& fmt) { return fmt.internalFormat == compressedFormat; });
1298
1299 DE_ASSERT(compressedInfo != end(compressedFormats));
1300 const auto sourceWidth = image[0].width / compressedInfo->blockSize[0];
1301 const auto sourceHeight = image[0].height / compressedInfo->blockSize[1];
1302
1303 DE_ASSERT((GLsizei)textureData.width == image[0].width && (GLsizei)textureData.height == image[0].height);
1304
1305 context.log
1306 << TestLog::Message
1307 << "Copying from " << getTextureFormatStr(uncompressedFormat).toString() << " " << sourceWidth << "x" << sourceHeight
1308 << " to " << getTextureFormatStr(compressedFormat).toString() << " " << image[0].width << "x" << image[0].height
1309 << TestLog::EndMessage;
1310
1311 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1312 gl.texImage2D(GL_TEXTURE_2D, 0, uncompressedFormat, sourceWidth, sourceHeight, 0, unsizedInfo.format, unsizedInfo.dataType, 0);
1313 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() failed");
1314 setTextureParameters(context.gl, GL_TEXTURE_2D);
1315
1316 context.bindTexture(GL_TEXTURE_2D, context.texIds[1]);
1317 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, compressedFormat, image[0].width, image[0].height, 0, textureData.data.size(), textureData.data.data());
1318 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1319 setTextureParameters(context.gl, GL_TEXTURE_2D);
1320
1321 context.bindTexture(GL_TEXTURE_2D, 0);
1322 gl.copyImageSubData(context.texIds[0], GL_TEXTURE_2D, 0, 0, 0, 0, context.texIds[1], GL_TEXTURE_2D, 0, 0, 0, 0, sourceWidth, sourceHeight, 1);
1323 },
1324 GL_NO_ERROR
1325 });
1326 }
1327 }
1328 }
1329 }
1330 },
1331 {
1332 gles32, // ApiType minApi;
1333 "copy_compressed_to_compressed", // string name;
1334 "Copying of pixels between compatible compressed texture formats", // string description;
1335 2, // size_t texIdsCount;
1336 0, // size_t bufferIdsCount;
1337 {}, // vector<ApiCaseStep> steps;
1338 [](deqp::Context&, vector<ApiCaseStep>& steps) // ApiCaseStepGeneratorFn stepsGenerator;
__anon27e7ac534402() 1339 {
1340 for(const auto& format : copyFormats)
1341 {
1342 if (!format.second.empty())
1343 continue;
1344 for(const auto& format0 : format.first)
1345 {
1346 for(const auto& format1 : format.first)
1347 {
1348 steps.push_back(
1349 {
1350 [format0, format1](ApiTestContext& context)
1351 {
1352 const auto& gl = context.gl;
1353 const auto image0 = loadImage(context.archive, format0, 0);
1354 const auto image1 = loadImage(context.archive, format1, 1);
1355
1356 DE_ASSERT(image0.width == 2 * image1.width && image0.height == 2 * image1.height);
1357
1358 context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1359 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format0, image0.width, image0.height, 0, image0.data.size(), image0.data.data());
1360 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1361 setTextureParameters(context.gl, GL_TEXTURE_2D);
1362
1363 context.bindTexture(GL_TEXTURE_2D, context.texIds[1]);
1364 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, format1, image1.width, image1.height, 0, image1.data.size(), image1.data.data());
1365 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1366 setTextureParameters(context.gl, GL_TEXTURE_2D);
1367
1368 context.bindTexture(GL_TEXTURE_2D, 0);
1369
1370 gl.copyImageSubData(context.texIds[1], GL_TEXTURE_2D, 0, 0, 0, 0, context.texIds[0], GL_TEXTURE_2D, 0, 0, 0, 0, image1.width, image1.height, 1);
1371 },
1372 GL_NO_ERROR
1373 });
1374 }
1375 }
1376 }
1377 }
1378 }
1379 };
1380
1381 class CompressedApiTest : public deqp::TestCase
1382 {
1383 public:
1384 explicit CompressedApiTest (deqp::Context& context, const ApiCaseParams& params);
1385 virtual ~CompressedApiTest ();
1386
1387 virtual void init (void) override;
1388 virtual void deinit (void) override;
1389
1390 virtual IterateResult iterate (void) override;
1391 private:
1392 ApiCaseParams m_params;
1393 vector<GLuint> m_texIds;
1394 vector<GLuint> m_bufferIds;
1395 };
1396
CompressedApiTest(deqp::Context & context,const ApiCaseParams & params)1397 CompressedApiTest::CompressedApiTest (deqp::Context& context, const ApiCaseParams& params)
1398 : deqp::TestCase(context, params.name.c_str(), params.description.c_str())
1399 , m_params(params)
1400 {
1401 }
1402
~CompressedApiTest()1403 CompressedApiTest::~CompressedApiTest ()
1404 {
1405 }
1406
init(void)1407 void CompressedApiTest::init (void)
1408 {
1409 const auto& gl = m_context.getRenderContext().getFunctions();
1410 if (m_params.texIdsCount > 0)
1411 {
1412 m_texIds.resize(m_params.texIdsCount);
1413 gl.genTextures(m_texIds.size(), m_texIds.data());
1414 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
1415 m_bufferIds.resize(m_params.bufferIdsCount);
1416 gl.genBuffers(m_bufferIds.size(), m_bufferIds.data());
1417 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
1418 }
1419 }
1420
deinit(void)1421 void CompressedApiTest::deinit (void)
1422 {
1423 const auto& gl = m_context.getRenderContext().getFunctions();
1424 if (!m_bufferIds.empty())
1425 {
1426 gl.deleteBuffers(m_bufferIds.size(), m_bufferIds.data());
1427 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed");
1428 m_bufferIds.erase(m_bufferIds.begin(), m_bufferIds.end());
1429 }
1430 if (!m_texIds.empty())
1431 {
1432 gl.deleteTextures(m_texIds.size(), m_texIds.data());
1433 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
1434 m_texIds.erase(m_texIds.begin(), m_texIds.end());
1435 }
1436 }
1437
iterate(void)1438 CompressedApiTest::IterateResult CompressedApiTest::iterate (void)
1439 {
1440 const auto& gl = m_context.getRenderContext().getFunctions();
1441 ApiTestContext caseContext =
1442 {
1443 m_context.getTestContext().getLog(),
1444 gl,
1445 m_texIds,
1446 m_bufferIds,
1447 m_context.getTestContext().getArchive()
1448 };
1449 vector<ApiCaseStep> steps (m_params.steps);
1450 if (m_params.stepsGenerator)
1451 m_params.stepsGenerator(m_context, steps);
1452 size_t stepIndex = 0;
1453 for(const auto& step : steps)
1454 {
1455 step.code(caseContext);
1456 const auto errorCode = gl.getError();
1457 if (errorCode != step.expectedError)
1458 {
1459 ostringstream msg;
1460 msg << "Got wrong error code: " << glu::getErrorStr(errorCode)
1461 << ", expected: " << glu::getErrorStr(step.expectedError)
1462 << " after step " << stepIndex;
1463 TCU_FAIL(msg.str().c_str());
1464 }
1465 ++stepIndex;
1466 }
1467 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1468 return IterateResult::STOP;
1469 }
1470
1471 class CompressedFormatTest : public deqp::TestCase
1472 {
1473 public:
1474 CompressedFormatTest (deqp::Context& context, shared_ptr<SharedData> data, const FormatInfo& format);
1475 virtual ~CompressedFormatTest ();
1476
1477 virtual void init (void);
1478 virtual void deinit (void);
1479 virtual IterateResult iterate (void);
1480 private:
1481 Surface drawTestImage (const glw::Functions& gl, GLuint texId, GLsizei width, GLsizei height);
1482
1483 shared_ptr<SharedData> m_data;
1484 const FormatInfo& formatInfo;
1485 };
1486
CompressedFormatTest(deqp::Context & context,shared_ptr<SharedData> data,const FormatInfo & format)1487 CompressedFormatTest::CompressedFormatTest (deqp::Context& context, shared_ptr<SharedData> data, const FormatInfo& format)
1488 : deqp::TestCase(context, format.name, "Test rendering of compressed format ")
1489 , m_data(data)
1490 , formatInfo(format)
1491 {
1492 }
1493
~CompressedFormatTest()1494 CompressedFormatTest::~CompressedFormatTest ()
1495 {
1496 }
1497
init(void)1498 void CompressedFormatTest::init (void)
1499 {
1500 m_data->init();
1501 }
1502
deinit(void)1503 void CompressedFormatTest::deinit (void)
1504 {
1505 m_data->deinit();
1506 }
1507
drawTestImage(const glw::Functions & gl,GLuint texId,GLsizei width,GLsizei height)1508 Surface CompressedFormatTest::drawTestImage (const glw::Functions& gl, GLuint texId, GLsizei width, GLsizei height)
1509 {
1510 gl.clearColor(1.0f, 0.2f, 1.0f, 1.0f);
1511 gl.clear(GL_COLOR_BUFFER_BIT);
1512 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() failed");
1513
1514 gl.disable(GL_BLEND);
1515 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() failed");
1516
1517 gl.bindTexture(GL_TEXTURE_2D, texId);
1518 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1519
1520 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1521 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed");
1522
1523 gl.bindTexture(GL_TEXTURE_2D, 0);
1524 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1525
1526 Surface result(width, height);
1527 readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1528 return result;
1529 }
1530
iterate(void)1531 CompressedFormatTest::IterateResult CompressedFormatTest::iterate (void)
1532 {
1533 const auto& archive = m_context.getTestContext().getArchive();
1534 const auto image0 = loadImage(archive, formatInfo.internalFormat, 0);
1535 const auto image1 = loadImage(archive, formatInfo.internalFormat, 1);
1536 const auto image2 = loadImage(archive, formatInfo.internalFormat, 2);
1537
1538 DE_ASSERT(image0.width == 2 * image1.width &&
1539 image0.height == 2 * image1.height &&
1540 image0.width % 4 == 0 &&
1541 image0.height % 4 == 0 &&
1542 image0.width == image2.width &&
1543 image0.height == image2.height);
1544
1545 const auto& gl = m_context.getRenderContext().getFunctions();
1546
1547 GLuint texIds[2];
1548 gl.genTextures(DE_LENGTH_OF_ARRAY(texIds), texIds);
1549 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
1550
1551 GLuint fboId;
1552 gl.genFramebuffers(1, &fboId);
1553 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed");
1554
1555 GLuint rboId;
1556 gl.genRenderbuffers(1, &rboId);
1557 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers() failed");
1558
1559 gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
1560 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
1561
1562 const GLenum bufferFormats[2][2] = {
1563 { GL_RGB8 , GL_SRGB8_ALPHA8 },
1564 { GL_RGBA8 , GL_SRGB8_ALPHA8 }
1565 };
1566 const bool hasAlpha = formatInfo.format == GL_RGBA;
1567 gl.renderbufferStorage(GL_RENDERBUFFER, bufferFormats[hasAlpha][formatInfo.issRGB], image0.width, image0.height);
1568 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage() failed");
1569
1570 gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
1571
1572 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
1573 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed");
1574
1575 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);
1576 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer() failed");
1577
1578 gl.viewport(0,0, image0.width, image0.height);
1579 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed");
1580
1581 gl.useProgram(m_data->programId());
1582 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed");
1583
1584 gl.uniform4fv(m_data->offsetLoc(), 1, defaultOffset.offset.getPtr());
1585 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1586 gl.uniform4fv(m_data->scaleLoc(), 1, defaultOffset.scale.getPtr());
1587 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1588
1589 gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1590 GLU_EXPECT_NO_ERROR(gl.getError(), "glBlendFunc() failed");
1591 gl.disable(GL_BLEND);
1592 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() failed");
1593
1594 // reference image
1595 gl.bindTexture(GL_TEXTURE_2D, texIds[0]);
1596 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1597 gl.texImage2D(GL_TEXTURE_2D, 0, formatInfo.sizedFormat, image2.width, image2.height, 0, formatInfo.format, GL_UNSIGNED_BYTE, image2.data.data());
1598 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() failed");
1599 setTextureParameters(gl, GL_TEXTURE_2D);
1600
1601 // compressed image
1602 gl.bindTexture(GL_TEXTURE_2D, texIds[1]);
1603 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1604 gl.compressedTexImage2D(GL_TEXTURE_2D, 0, formatInfo.internalFormat, image0.width, image0.height, 0, image0.data.size(), image0.data.data());
1605 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1606 gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image1.width, image1.height, formatInfo.internalFormat, image1.data.size(), image1.data.data());
1607 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexSubImage2D() failed");
1608 setTextureParameters(gl, GL_TEXTURE_2D);
1609
1610 gl.bindTexture(GL_TEXTURE_2D, 0);
1611 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1612
1613 gl.bindVertexArray(m_data->vaoId());
1614 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
1615
1616 gl.useProgram(m_data->programId());
1617 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed");
1618
1619 gl.uniform4fv(m_data->offsetLoc(), 1, defaultOffset.offset.getPtr());
1620 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1621 gl.uniform4fv(m_data->scaleLoc(), 1, defaultOffset.scale.getPtr());
1622 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1623 const auto referenceImage = drawTestImage(gl, texIds[0], image0.width, image0.height);
1624
1625 const auto& offsetIt = offsets.find(formatInfo.internalFormat);
1626 const auto& offset = offsetIt != offsets.end() ? offsetIt->second : defaultOffset;
1627 gl.uniform4fv(m_data->offsetLoc(), 1, offset.offset.getPtr());
1628 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1629 gl.uniform4fv(m_data->scaleLoc(), 1, offset.scale.getPtr());
1630 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() failed");
1631 const auto compressedImage = drawTestImage(gl, texIds[1], image0.width, image0.height);
1632
1633 gl.disable(GL_BLEND);
1634 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() failed");
1635
1636 gl.bindTexture(GL_TEXTURE_2D, 0);
1637 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindtexture() failed");
1638
1639 gl.deleteRenderbuffers(1, &rboId);
1640 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers() failed");
1641
1642 gl.deleteTextures(DE_LENGTH_OF_ARRAY(texIds), texIds);
1643 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
1644
1645 gl.deleteFramebuffers(1, &fboId);
1646 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers() failed");
1647
1648 if (!fuzzyCompare(m_testCtx.getLog(), "compressed_vs_uncompressed", "Image comparison result", referenceImage, compressedImage, 0.0f, CompareLogMode::COMPARE_LOG_ON_ERROR))
1649 TCU_FAIL("Rendered image comparison failed.");
1650
1651 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1652 return IterateResult::STOP;
1653 }
1654
1655 } //
1656
CompressedFormatTests(deqp::Context & context)1657 CompressedFormatTests::CompressedFormatTests (deqp::Context& context)
1658 : deqp::TestCaseGroup(context, "compressed_format", "Tests for compressed image formats")
1659 {
1660 }
1661
~CompressedFormatTests(void)1662 CompressedFormatTests::~CompressedFormatTests (void)
1663 {
1664 }
1665
init(void)1666 void CompressedFormatTests::init (void)
1667 {
1668 const auto apiGroup = new TestCaseGroup(m_context, "api", "Api call return values");
1669 addChild(apiGroup);
1670 for(const auto& apiCase : apiTests)
1671 if (glu::contextSupports(m_context.getRenderContext().getType(), apiCase.minApi))
1672 apiGroup->addChild(new CompressedApiTest(m_context, apiCase));
1673
1674 const auto formatGroup = new TestCaseGroup(m_context, "format", "Compressed format textures");
1675 addChild(formatGroup);
1676 const auto sharedData = make_shared<SharedData>(m_context);
1677 for(const auto& formatInfo : compressedFormats)
1678 if (glu::contextSupports(m_context.getRenderContext().getType(), formatInfo.minApi))
1679 formatGroup->addChild(new CompressedFormatTest(m_context, sharedData, formatInfo));
1680 }
1681
1682 } // glcts
1683