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