• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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