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 glcTexSubImageTests.cpp
22 * \brief Texture compatibility tests
23 */ /*-------------------------------------------------------------------*/
24
25 #include "glcTextureCompatibilityTests.hpp"
26
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29
30 #include "tcuImageCompare.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuTestLog.hpp"
34 #include "tcuTextureUtil.hpp"
35
36 #include "gluDefs.hpp"
37 #include "gluDrawUtil.hpp"
38 #include "gluPixelTransfer.hpp"
39 #include "gluShaderProgram.hpp"
40 #include "gluStrUtil.hpp"
41 #include "gluTextureUtil.hpp"
42
43 #include <map>
44 #include <memory>
45 #include <vector>
46
47 namespace glcts
48 {
49 namespace
50 {
51 const float vertexPositions[] =
52 {
53 -1.0f, -1.0f,
54 1.0f, -1.0f,
55 -1.0f, 1.0f,
56 1.0f, 1.0f,
57 };
58
59 const float vertexTexCoords[] =
60 {
61 0.0f, 0.0f,
62 1.0f, 0.0f,
63 0.0f, 1.0f,
64 1.0f, 1.0f,
65 };
66
67 const char* vertShader =
68 "${VERSION}\n"
69 "in highp vec4 in_position;\n"
70 "in highp vec2 in_texCoord;\n"
71 "out highp vec2 v_texCoord;\n"
72 "void main (void)\n"
73 "{\n"
74 " gl_Position = in_position;\n"
75 " v_texCoord = in_texCoord;\n"
76 "}\n";
77
78 const char* fragShader =
79 "${VERSION}\n"
80 "precision mediump float;\n"
81 "uniform sampler2D texture0;\n"
82 "in vec2 v_texCoord;\n"
83 "out vec4 color;\n"
84 "void main(void)\n"
85 "{\n"
86 " color = texture(texture0, v_texCoord);\n"
87 "}";
88
89 struct TestParameters
90 {
91 std::string testName;
92 glw::GLenum internalFormat;
93 glw::GLenum format;
94 glw::GLenum testType;
95 };
96
97 static const TestParameters testParameters[] =
98 {
99 { "rgba4_unsigned_byte", GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE },
100 { "rgb5_a1_unsigned_byte", GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE },
101 { "rgb5_a1_unsigned_int_10_a2", GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV },
102 { "r16f_float", GL_R16F, GL_RED, GL_FLOAT },
103 { "rg16f_float", GL_RG16F, GL_RG, GL_FLOAT },
104 { "rgb16f_float", GL_RGB16F, GL_RGB, GL_FLOAT },
105 { "rgba16f_float", GL_RGBA16F, GL_RGBA, GL_FLOAT },
106 { "r11f_g11f_b10f_half_float", GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT },
107 { "r11f_g11f_b10f_float", GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT },
108 { "rgb9_e5_half_float", GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT },
109 { "rgb9_e5_float", GL_RGB9_E5, GL_RGB, GL_FLOAT },
110 { "rgb565_unsigned_byte", GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE },
111 { "depth_component16_uint", GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }
112 };
113
114 class SubImageFormatTest : public deqp::TestCase
115 {
116 public:
117 SubImageFormatTest(deqp::Context& context, const TestParameters testParam, glw::GLsizei textureSize);
118
119 virtual ~SubImageFormatTest();
120
121 virtual void init (void);
122 virtual void deinit (void);
123
124 virtual IterateResult iterate (void);
125
126 private:
127 void setTextureParameters (glw::GLenum target);
128 void drawTexture (void);
129
130 void initializeProgram();
131 void setVertexBufferObjects();
132 void setVertexArrayObjects();
133
134 std::shared_ptr<glu::ShaderProgram> m_program;
135
136 TestParameters m_testParams;
137 glw::GLsizei m_textureSize;
138 glw::GLuint m_texId;
139 glw::GLuint m_vaoId;
140 glw::GLenum m_vboIds[2];
141 };
142
SubImageFormatTest(deqp::Context & context,const TestParameters testParams,glw::GLsizei textureSize)143 SubImageFormatTest::SubImageFormatTest (deqp::Context& context, const TestParameters testParams, glw::GLsizei textureSize)
144 : deqp::TestCase (context, ("texsubimage_format_" + testParams.testName).c_str(), "Pass glTexSubImage with different client format to glTexImage")
145 , m_testParams (testParams)
146 , m_textureSize (textureSize)
147 , m_texId (0)
148 , m_vaoId (0)
149 , m_vboIds { 0, 0 }
150 {
151 }
152
~SubImageFormatTest()153 SubImageFormatTest::~SubImageFormatTest()
154 {
155 }
156
init(void)157 void SubImageFormatTest::init(void)
158 {
159 initializeProgram();
160 setVertexBufferObjects();
161 setVertexArrayObjects();
162 }
163
deinit(void)164 void SubImageFormatTest::deinit(void)
165 {
166 const auto& gl = m_context.getRenderContext().getFunctions();
167
168 gl.deleteTextures(1, &m_texId);
169 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
170
171 gl.deleteBuffers(1, &m_vaoId);
172 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed");
173
174 gl.deleteBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds);
175 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers() failed");
176 }
177
iterate(void)178 SubImageFormatTest::IterateResult SubImageFormatTest::iterate(void)
179 {
180 const auto& gl = m_context.getRenderContext().getFunctions();
181
182 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
183
184 // Render buffer
185 glw::GLuint rboId;
186 gl.genRenderbuffers(1, &rboId);
187 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers() failed");
188 gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
189 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
190 gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, m_textureSize, m_textureSize);
191 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage() failed");
192 gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
193
194 // Frame buffer
195 glw::GLuint fboId;
196 gl.genFramebuffers(1, &fboId);
197 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed");
198 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
199 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed");
200 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);
201 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer() failed");
202
203 gl.viewport(0, 0, m_textureSize, m_textureSize);
204 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed");
205
206 gl.disable(GL_BLEND);
207
208 gl.bindTexture(GL_TEXTURE_2D, m_texId);
209 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
210
211 gl.bindVertexArray(m_vaoId);
212 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
213
214 // Create main texture.
215 tcu::TextureFormat refTexFormat (glu::mapGLInternalFormat(m_testParams.internalFormat));
216 glu::TransferFormat refTransferFormat = glu::getTransferFormat(refTexFormat);
217 tcu::Texture2D refTexture (refTexFormat, m_textureSize, m_textureSize, 1);
218
219 refTexture.allocLevel(0);
220 tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
221
222 // Create variables for reference sub texture.
223 tcu::TextureFormat refTexFormatSub = glu::mapGLInternalFormat(m_testParams.internalFormat);
224 tcu::Texture2D refSubTexture (refTexFormatSub, m_textureSize / 2, m_textureSize / 2, 1);
225 tcu::Surface refSurface (m_textureSize, m_textureSize);
226
227 refSubTexture.allocLevel(0);
228 tcu::fillWithComponentGradients(refSubTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
229
230 // Upload the main texture data.
231 gl.texImage2D(GL_TEXTURE_2D, 0, m_testParams.internalFormat, m_textureSize, m_textureSize, 0, refTransferFormat.format, refTransferFormat.dataType, refTexture.getLevel(0).getDataPtr());
232 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str());
233
234 // Update the content of a previously allocated texture with reference sub texture.
235 // Reference sub texture is using the same format and data type than main texture.
236 gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_textureSize / 2, m_textureSize / 2, refTransferFormat.format, refTransferFormat.dataType, refSubTexture.getLevel(0).getDataPtr());
237 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexSubImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str());
238
239 setTextureParameters(GL_TEXTURE_2D);
240
241 drawTexture();
242
243 m_context.getTestContext().getLog() << tcu::TestLog::Message << m_testParams.testName.c_str() << " ("
244 << m_textureSize << " x " << m_textureSize << ")" << tcu::TestLog::EndMessage;
245
246 // Read rendered pixels to reference surface.
247 glu::readPixels(m_context.getRenderContext(), 0, 0, refSurface.getAccess());
248
249 // Create variables for test sub texture.
250 tcu::TextureFormat testTexFormatSub = glu::mapGLTransferFormat(m_testParams.format, m_testParams.testType);
251 tcu::Texture2D testSubTexture (testTexFormatSub, m_textureSize / 2, m_textureSize / 2, 1);
252 tcu::Surface testSurface (m_textureSize, m_textureSize);
253
254 testSubTexture.allocLevel(0);
255 tcu::fillWithComponentGradients(testSubTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
256
257 // Upload the main texture data again.
258 gl.texImage2D(GL_TEXTURE_2D, 0, m_testParams.internalFormat, m_textureSize, m_textureSize, 0, refTransferFormat.format, refTransferFormat.dataType, refTexture.getLevel(0).getDataPtr());
259 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str());
260
261 // Update the content of a previously allocated texture with sub texture but different data type.
262 gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_textureSize / 2, m_textureSize / 2, m_testParams.format, m_testParams.testType, testSubTexture.getLevel(0).getDataPtr());
263 GLU_EXPECT_NO_ERROR(gl.getError(), ("gltexSubImage2D() failed" + glu::getTextureFormatStr(m_testParams.internalFormat).toString()).c_str());
264
265 setTextureParameters(GL_TEXTURE_2D);
266
267 drawTexture();
268
269 // Read rendered pixels to test surface.
270 readPixels(m_context.getRenderContext(), 0, 0, testSurface.getAccess());
271
272 // Execute the comparison.
273 if (tcu::fuzzyCompare(m_testCtx.getLog(), "texsubimage_format_", "Pass glTexSubImage with different client format to glTexImage",
274 refSurface, testSurface, 0.001f, tcu::COMPARE_LOG_RESULT))
275 {
276 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
277 }
278
279 // Cleanup
280 gl.bindTexture(GL_TEXTURE_2D, 0);
281 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
282 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
283 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
284 gl.deleteFramebuffers(1, &fboId);
285
286 return IterateResult::STOP;
287 }
288
setTextureParameters(glw::GLenum target)289 void SubImageFormatTest::setTextureParameters(glw::GLenum target)
290 {
291 const auto& gl = m_context.getRenderContext().getFunctions();
292
293 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
294 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
295
296 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
297 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
298
299 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
300 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
301
302 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
303 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
304
305 gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
306 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
307
308 gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
309 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
310
311 gl.texParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
312 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
313 }
314
drawTexture(void)315 void SubImageFormatTest::drawTexture(void)
316 {
317 const auto& gl = m_context.getRenderContext().getFunctions();
318
319 gl.useProgram(m_program->getProgram());
320 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed");
321
322 gl.clearColor(1.0f, 0.0f, 1.0f, 1.0f);
323 gl.clear(GL_COLOR_BUFFER_BIT);
324 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() failed");
325
326 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
327 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed");
328
329 gl.finish();
330 }
331
setVertexBufferObjects()332 void SubImageFormatTest::setVertexBufferObjects()
333 {
334 const auto& gl = m_context.getRenderContext().getFunctions();
335
336 gl.genBuffers(DE_LENGTH_OF_ARRAY(m_vboIds), m_vboIds);
337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
338
339 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
340 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
341
342 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
343 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
344
345 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
346 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
347
348 gl.bufferData(GL_ARRAY_BUFFER, sizeof(vertexTexCoords), vertexTexCoords, GL_STATIC_DRAW);
349 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed");
350
351 gl.bindBuffer(GL_ARRAY_BUFFER, 0);
352 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
353 }
354
setVertexArrayObjects()355 void SubImageFormatTest::setVertexArrayObjects()
356 {
357 const auto& gl = m_context.getRenderContext().getFunctions();
358 const auto program = m_program->getProgram();
359 const auto positionLoc = gl.getAttribLocation(program, "in_position");
360 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
361
362 const auto texCoordLoc = gl.getAttribLocation(program, "in_texCoord");
363 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation() failed");
364
365 gl.genVertexArrays(1, &m_vaoId);
366 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed");
367
368 gl.bindVertexArray(m_vaoId);
369 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
370
371 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
372 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
373
374 gl.enableVertexAttribArray(positionLoc);
375 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed");
376
377 gl.vertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
378 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed");
379
380 gl.bindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
381 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed");
382
383 gl.enableVertexAttribArray(texCoordLoc);
384 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray() failed");
385
386 gl.vertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
387 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer() failed");
388
389 gl.bindVertexArray(0);
390 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed");
391 }
392
initializeProgram()393 void SubImageFormatTest::initializeProgram()
394 {
395 const auto& gl = m_context.getRenderContext().getFunctions();
396
397 gl.genTextures(1, &m_texId);
398 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
399
400 const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
401 const auto glslVersion = glu::getGLSLVersionDeclaration(supportsES32 ? glu::GLSLVersion::GLSL_VERSION_320_ES : glu::GLSLVersion::GLSL_VERSION_310_ES);
402 const auto args = std::map<std::string, std::string>{ { "VERSION", glslVersion } };
403 const auto vs = tcu::StringTemplate(vertShader).specialize(args);
404 const auto fs = tcu::StringTemplate(fragShader).specialize(args);
405
406 m_program = std::make_shared<glu::ShaderProgram>(m_context.getRenderContext(),
407 glu::ProgramSources() << glu::VertexSource(vs) << glu::FragmentSource(fs));
408
409 if (!m_program->isOk())
410 throw std::runtime_error("Compiling shader program failed.");
411 }
412
413 } // <anonymous>
414
TextureCompatibilityTests(deqp::Context & context)415 TextureCompatibilityTests::TextureCompatibilityTests(deqp::Context& context)
416 : deqp::TestCaseGroup(context, "texture_compatibility", "Tests for texture format compatibility")
417 {
418 }
419
~TextureCompatibilityTests(void)420 TextureCompatibilityTests::~TextureCompatibilityTests(void)
421 {
422 }
423
init(void)424 void TextureCompatibilityTests::init(void)
425 {
426 for (const auto& test : testParameters)
427 addChild(new SubImageFormatTest(m_context, test, 32));
428 }
429
430 } // glcts
431