1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 /**
25 */ /*!
26 * \file gl4cSparseTexture2Tests.cpp
27 * \brief Conformance tests for the GL_ARB_sparse_texture2 functionality.
28 */ /*-------------------------------------------------------------------*/
29
30 #include "gl4cSparseTexture2Tests.hpp"
31 #include "deStringUtil.hpp"
32 #include "gl4cSparseTextureTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38
39 #include <cmath>
40 #include <stdio.h>
41 #include <string.h>
42 #include <vector>
43
44 using namespace glw;
45 using namespace glu;
46
47 namespace gl4cts
48 {
49
50 const char* st2_compute_textureFill = "#version 430 core\n"
51 "\n"
52 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
53 "\n"
54 "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n"
55 "\n"
56 "void main()\n"
57 "{\n"
58 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
59 " memoryBarrier();\n"
60 " <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
61 " imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
62 "}\n";
63
64 const char* st2_compute_textureVerify = "#version 430 core\n"
65 "\n"
66 "#extension GL_ARB_sparse_texture2 : enable\n"
67 "\n"
68 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
69 "\n"
70 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n"
71 "layout (location = 2, <FORMAT>) readonly uniform <INPUT_TYPE> uni_in_image;\n"
72 "\n"
73 "void main()\n"
74 "{\n"
75 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
76 " memoryBarrier();\n"
77 " highp <RETURN_TYPE> color,\n"
78 " expected,\n"
79 " epsilon;\n"
80 " color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
81 " expected = <RETURN_TYPE><RESULT_EXPECTED>;\n"
82 " epsilon = <RETURN_TYPE>(<EPSILON>);\n"
83 "\n"
84 " if (all(lessThanEqual(color, expected + epsilon)) &&\n"
85 " all(greaterThanEqual(color, expected - epsilon)))\n"
86 " {\n"
87 " imageStore(uni_out_image, point, uvec4(255));\n"
88 " }\n"
89 " else {\n"
90 " imageStore(uni_out_image, point, uvec4(0));\n"
91 " }\n"
92 "}\n";
93
94 const char* st2_compute_atomicVerify = "#version 430 core\n"
95 "\n"
96 "#extension GL_ARB_sparse_texture2 : enable\n"
97 "\n"
98 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
99 "\n"
100 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n"
101 "layout (location = 2, <FORMAT>) uniform <INPUT_TYPE> uni_in_image;\n"
102 "\n"
103 "layout (location = 3) uniform int widthCommitted;\n"
104 "\n"
105 "void main()\n"
106 "{\n"
107 " <POINT_TYPE> point,\n"
108 " offset;\n"
109 " point = <POINT_TYPE>(<POINT_DEF>);\n"
110 " offset = <POINT_TYPE>(0);\n"
111 " offset.x = widthCommitted;\n"
112 " memoryBarrier();\n"
113 " if (point.x >= widthCommitted) {\n"
114 " uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n"
115 " <DATA_TYPE> value = 127;\n"
116 " if (index == 0)\n"
117 " value = imageAtomicExchange(uni_in_image, point<SAMPLE_DEF>,\n"
118 " <DATA_TYPE>(0x0F));\n"
119 " else if (index == 1)\n"
120 " value = imageAtomicCompSwap(uni_in_image, point<SAMPLE_DEF>,\n"
121 " <DATA_TYPE>(0), <DATA_TYPE>(0x0F));\n"
122 " else if (index == 2)\n"
123 " value = imageAtomicAdd(uni_in_image, point<SAMPLE_DEF>,\n"
124 " <DATA_TYPE>(0x0F));\n"
125 " else if (index == 3)\n"
126 " value = imageAtomicAnd(uni_in_image, point<SAMPLE_DEF>,\n"
127 " <DATA_TYPE>(0x0F));\n"
128 " else if (index == 4)\n"
129 " value = imageAtomicOr(uni_in_image, point<SAMPLE_DEF>,\n"
130 " <DATA_TYPE>(0x0F));\n"
131 " else if (index == 5)\n"
132 " value = imageAtomicXor(uni_in_image, point<SAMPLE_DEF>,\n"
133 " <DATA_TYPE>(0x0F));\n"
134 " else if (index == 6)\n"
135 " value = imageAtomicMin(uni_in_image, point<SAMPLE_DEF>,\n"
136 " <DATA_TYPE>(0x0F));\n"
137 " else if (index == 7)\n"
138 " value = imageAtomicMax(uni_in_image, point<SAMPLE_DEF>,\n"
139 " <DATA_TYPE>(0x0F));\n"
140 "\n"
141 " <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
142 "\n"
143 " if (value == 0)\n"
144 " imageStore(uni_out_image, point - offset, uvec4(0));\n"
145 " else\n"
146 " imageStore(uni_out_image, point - offset, uvec4(value));\n"
147 "\n"
148 " if (color.r == 0)\n"
149 " imageStore(uni_out_image, point, uvec4(0));\n"
150 " else\n"
151 " imageStore(uni_out_image, point, uvec4(1));\n"
152 " }\n"
153 "}\n";
154
155 const char* st2_vertex_drawBuffer = "#version 430 core\n"
156 "\n"
157 "#extension GL_ARB_sparse_texture2 : enable\n"
158 "\n"
159 "in vec3 vertex;\n"
160 "in vec2 inTexCoord;\n"
161 "out vec2 texCoord;\n"
162 "\n"
163 "void main()\n"
164 "{\n"
165 " texCoord = inTexCoord;\n"
166 " gl_Position = vec4(vertex, 1);\n"
167 "}\n";
168
169 const char* st2_fragment_drawBuffer = "#version 430 core\n"
170 "\n"
171 "#extension GL_ARB_sparse_texture2 : enable\n"
172 "\n"
173 "layout (location = 1) uniform sampler2D uni_sampler;\n"
174 "\n"
175 "in vec2 texCoord;\n"
176 "out vec4 fragColor;\n"
177 "\n"
178 "void main()\n"
179 "{\n"
180 " fragColor = texture(uni_sampler, texCoord);\n"
181 "}\n";
182
183 const char* st2_compute_extensionCheck = "#version 450 core\n"
184 "\n"
185 "#extension <EXTENSION> : require\n"
186 "\n"
187 "#ifndef <EXTENSION>\n"
188 " #error <EXTENSION> not defined\n"
189 "#else\n"
190 " #if (<EXTENSION> != 1)\n"
191 " #error <EXTENSION> wrong value\n"
192 " #endif\n"
193 "#endif // <EXTENSION>\n"
194 "\n"
195 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
196 "\n"
197 "void main()\n"
198 "{\n"
199 "}\n";
200
201 const char* st2_compute_lookupVerify = "#version 450 core\n"
202 "\n"
203 "#extension GL_ARB_sparse_texture2 : enable\n"
204 "#extension GL_ARB_sparse_texture_clamp : enable\n"
205 "\n"
206 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
207 "\n"
208 "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out;\n"
209 "layout (location = 2<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
210 "layout (location = 3) uniform int widthCommitted;\n"
211 "\n"
212 "void main()\n"
213 "{\n"
214 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
215 " <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n"
216 " <ICOORD_TYPE> icoord = <ICOORD_TYPE>(<COORD_DEF>);\n"
217 " <COORD_TYPE> coord = <COORD_TYPE>(<COORD_DEF>) / <COORD_TYPE>(texSize);\n"
218 " <RETURN_TYPE> retValue,\n"
219 " expValue,\n"
220 " epsilon;\n"
221 " retValue = <RETURN_TYPE>(0);\n"
222 " expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
223 " epsilon = <RETURN_TYPE>(<EPSILON>);\n"
224 "\n"
225 "<CUBE_MAP_COORD_DEF>\n"
226 "<OFFSET_ARRAY_DEF>\n"
227 "\n"
228 " ivec2 corner1 = ivec2(1, 1);\n"
229 " ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
230 "\n"
231 " int code = <FUNCTION>(uni_in,\n"
232 " <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
233 " retValue<COMPONENT_DEF>);\n"
234 " memoryBarrier();\n"
235 "\n"
236 " imageStore(uni_out, point, uvec4(255));\n"
237 "\n"
238 " if (point.x > corner1.x && point.y > corner1.y &&\n"
239 " point.x < corner2.x && point.y < corner2.y &&\n"
240 " point.x < widthCommitted - 1)\n"
241 " {\n"
242 " if (!sparseTexelsResidentARB(code) ||\n"
243 " any(greaterThan(retValue, expValue + epsilon)) ||\n"
244 " any(lessThan(retValue, expValue - epsilon)))\n"
245 " {\n"
246 " imageStore(uni_out, point, uvec4(0));\n"
247 " }\n"
248 " }\n"
249 "\n"
250 " if (point.x > corner1.x && point.y > corner1.y &&\n"
251 " point.x < corner2.x && point.y < corner2.y &&\n"
252 " point.x >= widthCommitted + 1)\n"
253 " {\n"
254 " if (sparseTexelsResidentARB(code))\n"
255 " {\n"
256 " imageStore(uni_out, point, uvec4(0));\n"
257 " }\n"
258 " }\n"
259 "}\n";
260
261 /** Replace all occurance of <token> with <text> in <string>
262 *
263 * @param token Token string
264 * @param text String that will be used as replacement for <token>
265 * @param string String to work on
266 **/
replaceToken(const GLchar * token,const GLchar * text,std::string & string)267 void replaceToken(const GLchar* token, const GLchar* text, std::string& string)
268 {
269 const size_t text_length = strlen(text);
270 const size_t token_length = strlen(token);
271
272 size_t token_position;
273 while ((token_position = string.find(token, 0)) != std::string::npos)
274 {
275 string.replace(token_position, token_length, text, text_length);
276 }
277 }
278
279 /** Constructor.
280 *
281 * @param context Rendering context
282 */
ShaderExtensionTestCase(deqp::Context & context,const std::string extension)283 ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context, const std::string extension)
284 : TestCase(context, "ShaderExtension", "Verifies if extension is available for GLSL"), mExtension(extension)
285 {
286 /* Left blank intentionally */
287 }
288
289 /** Executes test iteration.
290 *
291 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
292 */
iterate()293 tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate()
294 {
295 if (!m_context.getContextInfo().isExtensionSupported(mExtension.c_str()))
296 {
297 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
298 return STOP;
299 }
300
301 const Functions& gl = m_context.getRenderContext().getFunctions();
302
303 std::string shader = st2_compute_extensionCheck;
304 replaceToken("<EXTENSION>", mExtension.c_str(), shader);
305
306 ProgramSources sources;
307 sources << ComputeSource(shader);
308 ShaderProgram program(gl, sources);
309
310 if (!program.isOk())
311 {
312 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
313 m_testCtx.getLog() << tcu::TestLog::Message << "Checking shader preprocessor directives failed. Source:\n"
314 << shader.c_str() << "InfoLog:\n"
315 << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
316 << tcu::TestLog::EndMessage;
317 return STOP;
318 }
319
320 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
321 return STOP;
322 }
323
324 /** Constructor.
325 *
326 * @param context Rendering context
327 */
StandardPageSizesTestCase(deqp::Context & context)328 StandardPageSizesTestCase::StandardPageSizesTestCase(deqp::Context& context)
329 : TestCase(context, "StandardPageSizesTestCase",
330 "Verifies if values returned by GetInternalFormativ query matches Standard Virtual Page Sizes")
331 {
332 /* Left blank intentionally */
333 }
334
335 /** Stub init method */
init()336 void StandardPageSizesTestCase::init()
337 {
338 mSupportedTargets.push_back(GL_TEXTURE_1D);
339 mSupportedTargets.push_back(GL_TEXTURE_1D_ARRAY);
340 mSupportedTargets.push_back(GL_TEXTURE_2D);
341 mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
342 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
343 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
344 mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
345 mSupportedTargets.push_back(GL_TEXTURE_BUFFER);
346 mSupportedTargets.push_back(GL_RENDERBUFFER);
347
348 mStandardVirtualPageSizesTable[GL_R8] = PageSizeStruct(256, 256, 1);
349 mStandardVirtualPageSizesTable[GL_R8_SNORM] = PageSizeStruct(256, 256, 1);
350 mStandardVirtualPageSizesTable[GL_R8I] = PageSizeStruct(256, 256, 1);
351 mStandardVirtualPageSizesTable[GL_R8UI] = PageSizeStruct(256, 256, 1);
352 mStandardVirtualPageSizesTable[GL_R16] = PageSizeStruct(256, 128, 1);
353 mStandardVirtualPageSizesTable[GL_R16_SNORM] = PageSizeStruct(256, 128, 1);
354 mStandardVirtualPageSizesTable[GL_RG8] = PageSizeStruct(256, 128, 1);
355 mStandardVirtualPageSizesTable[GL_RG8_SNORM] = PageSizeStruct(256, 128, 1);
356 mStandardVirtualPageSizesTable[GL_RGB565] = PageSizeStruct(256, 128, 1);
357 mStandardVirtualPageSizesTable[GL_R16F] = PageSizeStruct(256, 128, 1);
358 mStandardVirtualPageSizesTable[GL_R16I] = PageSizeStruct(256, 128, 1);
359 mStandardVirtualPageSizesTable[GL_R16UI] = PageSizeStruct(256, 128, 1);
360 mStandardVirtualPageSizesTable[GL_RG8I] = PageSizeStruct(256, 128, 1);
361 mStandardVirtualPageSizesTable[GL_RG8UI] = PageSizeStruct(256, 128, 1);
362 mStandardVirtualPageSizesTable[GL_RG16] = PageSizeStruct(128, 128, 1);
363 mStandardVirtualPageSizesTable[GL_RG16_SNORM] = PageSizeStruct(128, 128, 1);
364 mStandardVirtualPageSizesTable[GL_RGBA8] = PageSizeStruct(128, 128, 1);
365 mStandardVirtualPageSizesTable[GL_RGBA8_SNORM] = PageSizeStruct(128, 128, 1);
366 mStandardVirtualPageSizesTable[GL_RGB10_A2] = PageSizeStruct(128, 128, 1);
367 mStandardVirtualPageSizesTable[GL_RGB10_A2UI] = PageSizeStruct(128, 128, 1);
368 mStandardVirtualPageSizesTable[GL_RG16F] = PageSizeStruct(128, 128, 1);
369 mStandardVirtualPageSizesTable[GL_R32F] = PageSizeStruct(128, 128, 1);
370 mStandardVirtualPageSizesTable[GL_R11F_G11F_B10F] = PageSizeStruct(128, 128, 1);
371 mStandardVirtualPageSizesTable[GL_RGB9_E5] = PageSizeStruct(128, 128, 1);
372 mStandardVirtualPageSizesTable[GL_R32I] = PageSizeStruct(128, 128, 1);
373 mStandardVirtualPageSizesTable[GL_R32UI] = PageSizeStruct(128, 128, 1);
374 mStandardVirtualPageSizesTable[GL_RG16I] = PageSizeStruct(128, 128, 1);
375 mStandardVirtualPageSizesTable[GL_RG16UI] = PageSizeStruct(128, 128, 1);
376 mStandardVirtualPageSizesTable[GL_RGBA8I] = PageSizeStruct(128, 128, 1);
377 mStandardVirtualPageSizesTable[GL_RGBA8UI] = PageSizeStruct(128, 128, 1);
378 mStandardVirtualPageSizesTable[GL_RGBA16] = PageSizeStruct(128, 64, 1);
379 mStandardVirtualPageSizesTable[GL_RGBA16_SNORM] = PageSizeStruct(128, 64, 1);
380 mStandardVirtualPageSizesTable[GL_RGBA16F] = PageSizeStruct(128, 64, 1);
381 mStandardVirtualPageSizesTable[GL_RG32F] = PageSizeStruct(128, 64, 1);
382 mStandardVirtualPageSizesTable[GL_RG32I] = PageSizeStruct(128, 64, 1);
383 mStandardVirtualPageSizesTable[GL_RG32UI] = PageSizeStruct(128, 64, 1);
384 mStandardVirtualPageSizesTable[GL_RGBA16I] = PageSizeStruct(128, 64, 1);
385 mStandardVirtualPageSizesTable[GL_RGBA16UI] = PageSizeStruct(128, 64, 1);
386 mStandardVirtualPageSizesTable[GL_RGBA32F] = PageSizeStruct(64, 64, 1);
387 mStandardVirtualPageSizesTable[GL_RGBA32I] = PageSizeStruct(64, 64, 1);
388 mStandardVirtualPageSizesTable[GL_RGBA32UI] = PageSizeStruct(64, 64, 1);
389 }
390
391 /** Executes test iteration.
392 *
393 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
394 */
iterate()395 tcu::TestNode::IterateResult StandardPageSizesTestCase::iterate()
396 {
397 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
398 {
399 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
400 return STOP;
401 }
402
403 const Functions& gl = m_context.getRenderContext().getFunctions();
404
405 m_testCtx.getLog() << tcu::TestLog::Message << "Testing getInternalformativ" << tcu::TestLog::EndMessage;
406
407 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
408 ++iter)
409 {
410 const GLint& target = *iter;
411
412 for (std::map<glw::GLint, PageSizeStruct>::const_iterator formIter = mStandardVirtualPageSizesTable.begin();
413 formIter != mStandardVirtualPageSizesTable.end(); ++formIter)
414 {
415 const PageSizePair& format = *formIter;
416 const PageSizeStruct& page = format.second;
417
418 GLint pageSizeX;
419 GLint pageSizeY;
420 GLint pageSizeZ;
421 SparseTextureUtils::getTexturePageSizes(gl, target, format.first, pageSizeX, pageSizeY, pageSizeZ);
422
423 if (pageSizeX != page.xSize || pageSizeY != page.ySize || pageSizeZ != page.zSize)
424 {
425 m_testCtx.getLog() << tcu::TestLog::Message << "Standard Virtual Page Size mismatch, target: " << target
426 << ", format: " << format.first << ", returned: " << pageSizeX << "/" << pageSizeY
427 << "/" << pageSizeZ << ", expected: " << page.xSize << "/" << page.ySize << "/"
428 << page.zSize << tcu::TestLog::EndMessage;
429
430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
431 return STOP;
432 }
433 }
434 }
435
436 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
437
438 return STOP;
439 }
440
441 /** Constructor.
442 *
443 * @param context Rendering context
444 */
SparseTexture2AllocationTestCase(deqp::Context & context)445 SparseTexture2AllocationTestCase::SparseTexture2AllocationTestCase(deqp::Context& context)
446 : SparseTextureAllocationTestCase(context, "SparseTexture2Allocation",
447 "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture2")
448 {
449 /* Left blank intentionally */
450 }
451
452 /** Initializes the test group contents. */
init()453 void SparseTexture2AllocationTestCase::init()
454 {
455 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
456 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
457
458 mFullArrayTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
459
460 mSupportedInternalFormats.push_back(GL_R8);
461 mSupportedInternalFormats.push_back(GL_R8_SNORM);
462 mSupportedInternalFormats.push_back(GL_R16);
463 mSupportedInternalFormats.push_back(GL_R16_SNORM);
464 mSupportedInternalFormats.push_back(GL_RG8);
465 mSupportedInternalFormats.push_back(GL_RG8_SNORM);
466 mSupportedInternalFormats.push_back(GL_RG16);
467 mSupportedInternalFormats.push_back(GL_RG16_SNORM);
468 mSupportedInternalFormats.push_back(GL_RGB565);
469 mSupportedInternalFormats.push_back(GL_RGBA8);
470 mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
471 mSupportedInternalFormats.push_back(GL_RGB10_A2);
472 mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
473 mSupportedInternalFormats.push_back(GL_RGBA16);
474 mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
475 mSupportedInternalFormats.push_back(GL_R16F);
476 mSupportedInternalFormats.push_back(GL_RG16F);
477 mSupportedInternalFormats.push_back(GL_RGBA16F);
478 mSupportedInternalFormats.push_back(GL_R32F);
479 mSupportedInternalFormats.push_back(GL_RG32F);
480 mSupportedInternalFormats.push_back(GL_RGBA32F);
481 mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
482 // RGB9_E5 isn't color renderable, and thus isn't valid for multisample
483 // textures.
484 //mSupportedInternalFormats.push_back(GL_RGB9_E5);
485 mSupportedInternalFormats.push_back(GL_R8I);
486 mSupportedInternalFormats.push_back(GL_R8UI);
487 mSupportedInternalFormats.push_back(GL_R16I);
488 mSupportedInternalFormats.push_back(GL_R16UI);
489 mSupportedInternalFormats.push_back(GL_R32I);
490 mSupportedInternalFormats.push_back(GL_R32UI);
491 mSupportedInternalFormats.push_back(GL_RG8I);
492 mSupportedInternalFormats.push_back(GL_RG8UI);
493 mSupportedInternalFormats.push_back(GL_RG16I);
494 mSupportedInternalFormats.push_back(GL_RG16UI);
495 mSupportedInternalFormats.push_back(GL_RG32I);
496 mSupportedInternalFormats.push_back(GL_RG32UI);
497 mSupportedInternalFormats.push_back(GL_RGBA8I);
498 mSupportedInternalFormats.push_back(GL_RGBA8UI);
499 mSupportedInternalFormats.push_back(GL_RGBA16I);
500 mSupportedInternalFormats.push_back(GL_RGBA16UI);
501 mSupportedInternalFormats.push_back(GL_RGBA32I);
502 }
503
504 /** Executes test iteration.
505 *
506 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
507 */
iterate()508 tcu::TestNode::IterateResult SparseTexture2AllocationTestCase::iterate()
509 {
510 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
511 {
512 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
513 return STOP;
514 }
515
516 return SparseTextureAllocationTestCase::iterate();
517 }
518
519 /** Constructor.
520 *
521 * @param context Rendering context
522 * @param name Test name
523 * @param description Test description
524 */
SparseTexture2CommitmentTestCase(deqp::Context & context,const char * name,const char * description)525 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context, const char* name,
526 const char* description)
527 : SparseTextureCommitmentTestCase(context, name, description)
528 {
529 /* Left blank intentionally */
530 }
531
532 /** Constructor.
533 *
534 * @param context Rendering context
535 */
SparseTexture2CommitmentTestCase(deqp::Context & context)536 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context)
537 : SparseTextureCommitmentTestCase(
538 context, "SparseTexture2Commitment",
539 "Verifies glTexPageCommitmentARB functionality added by ARB_sparse_texture2 extension")
540 {
541 /* Left blank intentionally */
542 }
543
544 /** Initializes the test group contents. */
init()545 void SparseTexture2CommitmentTestCase::init()
546 {
547 SparseTextureCommitmentTestCase::init();
548
549 //Verify all targets once again and multisample targets as it was added in ARB_sparse_texture2 extension
550 mSupportedTargets.clear();
551 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
552 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
553 }
554
555 /** Executes test iteration.
556 *
557 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
558 */
iterate()559 tcu::TestNode::IterateResult SparseTexture2CommitmentTestCase::iterate()
560 {
561 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
562 {
563 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
564 return STOP;
565 }
566
567 return SparseTextureCommitmentTestCase::iterate();
568 }
569
570 /** Create set of token strings fit to texture verifying shader
571 *
572 * @param target Target for which texture is binded
573 * @param format Texture internal format
574 * @param sample Texture sample number
575
576 * @return target Structure of token strings
577 */
createShaderTokens(GLint target,GLint format,GLint sample,const std::string outputBase,const std::string inputBase)578 SparseTexture2CommitmentTestCase::TokenStrings SparseTexture2CommitmentTestCase::createShaderTokens(
579 GLint target, GLint format, GLint sample, const std::string outputBase, const std::string inputBase)
580 {
581 TokenStrings s;
582 std::string prefix;
583
584 if (format == GL_R8)
585 {
586 s.format = "r8";
587 s.resultExpected = "(1, 0, 0, 1)";
588 s.resultDefault = "(0, 0, 0, 1)";
589 }
590 else if (format == GL_R8_SNORM)
591 {
592 s.format = "r8_snorm";
593 s.resultExpected = "(1, 0, 0, 1)";
594 s.resultDefault = "(0, 0, 0, 1)";
595 }
596 else if (format == GL_R16)
597 {
598 s.format = "r16";
599 s.resultExpected = "(1, 0, 0, 1)";
600 s.resultDefault = "(0, 0, 0, 1)";
601 }
602 else if (format == GL_R16_SNORM)
603 {
604 s.format = "r16_snorm";
605 s.resultExpected = "(1, 0, 0, 1)";
606 s.resultDefault = "(0, 0, 0, 1)";
607 }
608 else if (format == GL_RG8)
609 {
610 s.format = "rg8";
611 s.resultExpected = "(1, 1, 0, 1)";
612 s.resultDefault = "(0, 0, 0, 1)";
613 }
614 else if (format == GL_RG8_SNORM)
615 {
616 s.format = "rg8_snorm";
617 s.resultExpected = "(1, 1, 0, 1)";
618 s.resultDefault = "(0, 0, 0, 1)";
619 }
620 else if (format == GL_RG16)
621 {
622 s.format = "rg16";
623 s.resultExpected = "(1, 1, 0, 1)";
624 s.resultDefault = "(0, 0, 0, 1)";
625 }
626 else if (format == GL_RG16_SNORM)
627 {
628 s.format = "rg16_snorm";
629 s.resultExpected = "(1, 1, 0, 1)";
630 s.resultDefault = "(0, 0, 0, 1)";
631 }
632 else if (format == GL_RGBA8)
633 {
634 s.format = "rgba8";
635 s.resultExpected = "(1, 1, 1, 1)";
636 s.resultDefault = "(0, 0, 0, 0)";
637 }
638 else if (format == GL_RGBA8_SNORM)
639 {
640 s.format = "rgba8_snorm";
641 s.resultExpected = "(1, 1, 1, 1)";
642 s.resultDefault = "(0, 0, 0, 0)";
643 }
644 else if (format == GL_RGB10_A2)
645 {
646 s.format = "rgb10_a2";
647 s.resultExpected = "(1, 1, 1, 1)";
648 s.resultDefault = "(0, 0, 0, 0)";
649 }
650 else if (format == GL_RGB10_A2UI)
651 {
652 s.format = "rgb10_a2ui";
653 s.resultExpected = "(1, 1, 1, 1)";
654 s.resultDefault = "(0, 0, 0, 0)";
655 prefix = "u";
656 }
657 else if (format == GL_RGBA16)
658 {
659 s.format = "rgba16";
660 s.resultExpected = "(1, 1, 1, 1)";
661 s.resultDefault = "(0, 0, 0, 0)";
662 }
663 else if (format == GL_RGBA16_SNORM)
664 {
665 s.format = "rgba16_snorm";
666 s.resultExpected = "(1, 1, 1, 1)";
667 s.resultDefault = "(0, 0, 0, 0)";
668 }
669 else if (format == GL_R16F)
670 {
671 s.format = "r16f";
672 s.resultExpected = "(1, 0, 0, 1)";
673 s.resultDefault = "(0, 0, 0, 1)";
674 }
675 else if (format == GL_RG16F)
676 {
677 s.format = "rg16f";
678 s.resultExpected = "(1, 1, 0, 1)";
679 s.resultDefault = "(0, 0, 0, 1)";
680 }
681 else if (format == GL_RGBA16F)
682 {
683 s.format = "rgba16f";
684 s.resultExpected = "(1, 1, 1, 1)";
685 s.resultDefault = "(0, 0, 0, 0)";
686 }
687 else if (format == GL_R32F)
688 {
689 s.format = "r32f";
690 s.resultExpected = "(1, 0, 0, 1)";
691 s.resultDefault = "(0, 0, 0, 1)";
692 }
693 else if (format == GL_RG32F)
694 {
695 s.format = "rg32f";
696 s.resultExpected = "(1, 1, 0, 1)";
697 s.resultDefault = "(0, 0, 0, 1)";
698 }
699 else if (format == GL_RGBA32F)
700 {
701 s.format = "rgba32f";
702 s.resultExpected = "(1, 1, 1, 1)";
703 s.resultDefault = "(0, 0, 0, 0)";
704 }
705 else if (format == GL_R11F_G11F_B10F)
706 {
707 s.format = "r11f_g11f_b10f";
708 s.resultExpected = "(1, 1, 1, 1)";
709 s.resultDefault = "(0, 0, 0, 1)";
710 }
711 else if (format == GL_R8I)
712 {
713 s.format = "r8i";
714 s.resultExpected = "(1, 0, 0, 1)";
715 s.resultDefault = "(0, 0, 0, 1)";
716 prefix = "i";
717 }
718 else if (format == GL_R8UI)
719 {
720 s.format = "r8ui";
721 s.resultExpected = "(1, 0, 0, 1)";
722 s.resultDefault = "(0, 0, 0, 1)";
723 prefix = "u";
724 }
725 else if (format == GL_R16I)
726 {
727 s.format = "r16i";
728 s.resultExpected = "(1, 0, 0, 1)";
729 s.resultDefault = "(0, 0, 0, 1)";
730 prefix = "i";
731 }
732 else if (format == GL_R16UI)
733 {
734 s.format = "r16ui";
735 s.resultExpected = "(1, 0, 0, 1)";
736 s.resultDefault = "(0, 0, 0, 1)";
737 prefix = "u";
738 }
739 else if (format == GL_R32I)
740 {
741 s.format = "r32i";
742 s.resultExpected = "(1, 0, 0, 1)";
743 s.resultDefault = "(0, 0, 0, 1)";
744 prefix = "i";
745 }
746 else if (format == GL_R32UI)
747 {
748 s.format = "r32ui";
749 s.resultExpected = "(1, 0, 0, 1)";
750 s.resultDefault = "(0, 0, 0, 1)";
751 prefix = "u";
752 }
753 else if (format == GL_RG8I)
754 {
755 s.format = "rg8i";
756 s.resultExpected = "(1, 1, 0, 1)";
757 s.resultDefault = "(0, 0, 0, 1)";
758 prefix = "i";
759 }
760 else if (format == GL_RG8UI)
761 {
762 s.format = "rg8ui";
763 s.resultExpected = "(1, 1, 0, 1)";
764 s.resultDefault = "(0, 0, 0, 1)";
765 prefix = "u";
766 }
767 else if (format == GL_RG16I)
768 {
769 s.format = "rg16i";
770 s.resultExpected = "(1, 1, 0, 1)";
771 s.resultDefault = "(0, 0, 0, 1)";
772 prefix = "i";
773 }
774 else if (format == GL_RG16UI)
775 {
776 s.format = "rg16ui";
777 s.resultExpected = "(1, 1, 0, 1)";
778 s.resultDefault = "(0, 0, 0, 1)";
779 prefix = "u";
780 }
781 else if (format == GL_RG32I)
782 {
783 s.format = "rg32i";
784 s.resultExpected = "(1, 1, 0, 1)";
785 s.resultDefault = "(0, 0, 0, 1)";
786 prefix = "i";
787 }
788 else if (format == GL_RG32UI)
789 {
790 s.format = "rg32ui";
791 s.resultExpected = "(1, 1, 0, 1)";
792 s.resultDefault = "(0, 0, 0, 1)";
793 prefix = "u";
794 }
795 else if (format == GL_RGBA8I)
796 {
797 s.format = "rgba8i";
798 s.resultExpected = "(1, 1, 1, 1)";
799 s.resultDefault = "(0, 0, 0, 0)";
800 prefix = "i";
801 }
802 else if (format == GL_RGBA8UI)
803 {
804 s.format = "rgba8ui";
805 s.resultExpected = "(1, 1, 1, 1)";
806 s.resultDefault = "(0, 0, 0, 0)";
807 prefix = "u";
808 }
809 else if (format == GL_RGBA16I)
810 {
811 s.format = "rgba16i";
812 s.resultExpected = "(1, 1, 1, 1)";
813 s.resultDefault = "(0, 0, 0, 0)";
814 prefix = "i";
815 }
816 else if (format == GL_RGBA16UI)
817 {
818 s.format = "rgba16ui";
819 s.resultExpected = "(1, 1, 1, 1)";
820 s.resultDefault = "(0, 0, 0, 0)";
821 prefix = "u";
822 }
823 else if (format == GL_RGBA32I)
824 {
825 s.format = "rgba32i";
826 s.resultExpected = "(1, 1, 1, 1)";
827 s.resultDefault = "(0, 0, 0, 0)";
828 prefix = "i";
829 }
830 else if (format == GL_DEPTH_COMPONENT16)
831 {
832 s.format = "r16";
833 s.resultExpected = "(1, 0, 0, 0)";
834 s.resultDefault = "(0, 0, 0, 0)";
835 }
836
837 s.returnType = prefix + "vec4";
838 s.outputType = "u" + outputBase + "2D";
839 s.inputType = prefix + inputBase + "2D";
840 s.pointType = "ivec2";
841 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y";
842
843 if (s.returnType == "vec4")
844 s.epsilon = "0.008";
845 else
846 s.epsilon = "0";
847
848 if (target == GL_TEXTURE_1D)
849 {
850 s.outputType = "u" + outputBase + "2D";
851 s.inputType = prefix + inputBase + "1D";
852 s.pointType = "int";
853 s.pointDef = "gl_WorkGroupID.x";
854 }
855 else if (target == GL_TEXTURE_1D_ARRAY)
856 {
857 s.outputType = "u" + outputBase + "2D_ARRAY";
858 s.inputType = prefix + inputBase + "1DArray";
859 s.pointType = "ivec2";
860 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.z";
861 }
862 else if (target == GL_TEXTURE_2D_ARRAY)
863 {
864 s.outputType = "u" + outputBase + "2DArray";
865 s.inputType = prefix + inputBase + "2DArray";
866 s.pointType = "ivec3";
867 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
868 }
869 else if (target == GL_TEXTURE_3D)
870 {
871 s.outputType = "u" + outputBase + "2DArray";
872 s.inputType = prefix + inputBase + "3D";
873 s.pointType = "ivec3";
874 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
875 }
876 else if (target == GL_TEXTURE_CUBE_MAP)
877 {
878 s.outputType = "u" + outputBase + "2DArray";
879 s.inputType = prefix + inputBase + "Cube";
880 s.pointType = "ivec3";
881 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6";
882 }
883 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
884 {
885 s.outputType = "u" + outputBase + "2DArray";
886 s.inputType = prefix + inputBase + "CubeArray";
887 s.pointType = "ivec3";
888 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
889 }
890 else if (target == GL_TEXTURE_RECTANGLE)
891 {
892 s.inputType = prefix + inputBase + "2DRect";
893 }
894 else if (target == GL_TEXTURE_2D_MULTISAMPLE)
895 {
896 s.inputType = prefix + inputBase + "2DMS";
897 s.sampleDef = ", " + de::toString(sample);
898 }
899 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
900 {
901 s.outputType = "u" + outputBase + "2DArray";
902 s.inputType = prefix + inputBase + "2DMSArray";
903 s.pointType = "ivec3";
904 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
905 s.sampleDef = ", " + de::toString(sample);
906 }
907
908 return s;
909 }
910
911 /** Check if specific combination of target and format is allowed
912 *
913 * @param target Target for which texture is binded
914 * @param format Texture internal format
915 *
916 * @return Returns true if target/format combination is allowed, false otherwise.
917 */
caseAllowed(GLint target,GLint format)918 bool SparseTexture2CommitmentTestCase::caseAllowed(GLint target, GLint format)
919 {
920 // Multisample textures are filling with data and verifying using compute shader.
921 // As shaders do not support some texture formats it is necessary to exclude them.
922 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) &&
923 (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
924 {
925 return false;
926 }
927
928 return true;
929 }
930
931 /** Allocating sparse texture memory using texStorage* function
932 *
933 * @param gl GL API functions
934 * @param target Target for which texture is binded
935 * @param format Texture internal format
936 * @param texture Texture object
937 * @param levels Texture mipmaps level
938 *
939 * @return Returns true if no error occurred, otherwise throws an exception.
940 */
sparseAllocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)941 bool SparseTexture2CommitmentTestCase::sparseAllocateTexture(const Functions& gl, GLint target, GLint format,
942 GLuint& texture, GLint levels)
943 {
944 mLog << "Sparse Allocate [levels: " << levels << "] - ";
945
946 prepareTexture(gl, target, format, texture);
947
948 GLint maxLevels;
949 gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
950 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");
951 gl.getTexParameteriv(target, GL_NUM_SPARSE_LEVELS_ARB, &maxLevels);
952 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv");
953 if (levels > maxLevels)
954 levels = maxLevels;
955
956 //GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
957 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
958 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
959 {
960 mState.levels = levels;
961 }
962 else
963 mState.levels = 1;
964
965 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
966 {
967 mState.samples = 1;
968 }
969 else
970 mState.samples = 2;
971
972 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
973 mState.depth);
974 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
975
976 return true;
977 }
978
979 /** Allocating texture memory using texStorage* function
980 *
981 * @param gl GL API functions
982 * @param target Target for which texture is binded
983 * @param format Texture internal format
984 * @param texture Texture object
985 * @param levels Texture mipmaps level
986 *
987 * @return Returns true if no error occurred, otherwise throws an exception.
988 */
allocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)989 bool SparseTexture2CommitmentTestCase::allocateTexture(const Functions& gl, GLint target, GLint format, GLuint& texture,
990 GLint levels)
991 {
992 mLog << "Allocate [levels: " << levels << "] - ";
993
994 prepareTexture(gl, target, format, texture);
995
996 // GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
997 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
998 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
999 {
1000 mState.levels = levels;
1001 }
1002 else
1003 mState.levels = 1;
1004
1005 // GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can use multiple samples
1006 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1007 {
1008 mState.samples = 1;
1009 }
1010 else
1011 mState.samples = 2;
1012
1013 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
1014 mState.depth);
1015 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
1016
1017 return true;
1018 }
1019
1020 /** Writing data to generated texture
1021 *
1022 * @param gl GL API functions
1023 * @param target Target for which texture is binded
1024 * @param format Texture internal format
1025 * @param texture Texture object
1026 *
1027 * @return Returns true if no error occurred, otherwise throws an exception.
1028 */
writeDataToTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1029 bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format,
1030 GLuint& texture, GLint level)
1031 {
1032 mLog << "Fill Texture [level: " << level << "] - ";
1033
1034 if (level > mState.levels - 1)
1035 TCU_FAIL("Invalid level");
1036
1037 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1038
1039 GLint width;
1040 GLint height;
1041 GLint depth;
1042 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1043
1044 if (width > 0 && height > 0 && depth >= mState.minDepth)
1045 {
1046 if (target == GL_TEXTURE_CUBE_MAP)
1047 depth = depth * 6;
1048
1049 GLint texSize = width * height * depth * mState.format.getPixelSize();
1050
1051 std::vector<GLubyte> vecData;
1052 vecData.resize(texSize);
1053 GLubyte* data = vecData.data();
1054
1055 deMemset(data, 255, texSize);
1056
1057 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1058 {
1059 Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
1060 transferFormat.dataType, (GLvoid*)data);
1061 GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
1062 }
1063 // For multisample texture use compute shader to store image data
1064 else
1065 {
1066 for (GLint sample = 0; sample < mState.samples; ++sample)
1067 {
1068 std::string shader = st2_compute_textureFill;
1069
1070 // Adjust shader source to texture format
1071 TokenStrings s = createShaderTokens(target, format, sample);
1072
1073 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1074 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1075 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1076 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1077 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1078 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1079
1080 ProgramSources sources;
1081 sources << ComputeSource(shader);
1082
1083 // Build and run shader
1084 ShaderProgram program(m_context.getRenderContext(), sources);
1085 if (program.isOk())
1086 {
1087 gl.useProgram(program.getProgram());
1088 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1089 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */,
1090 GL_WRITE_ONLY, format);
1091 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1092 gl.uniform1i(1, 0 /* image_unit */);
1093 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1094 gl.dispatchCompute(width, height, depth);
1095 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1096 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1097 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1098 }
1099 else
1100 {
1101 mLog << "Compute shader compilation failed (writing) for target: " << target
1102 << ", format: " << format << ", sample: " << sample
1103 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1104 << ", shaderSource: " << shader.c_str() << " - ";
1105 }
1106 }
1107 }
1108 }
1109
1110 return true;
1111 }
1112
1113 /** Verify if data stored in texture is as expected
1114 *
1115 * @param gl GL API functions
1116 * @param target Target for which texture is binded
1117 * @param format Texture internal format
1118 * @param texture Texture object
1119 * @param level Texture mipmap level
1120 *
1121 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1122 */
verifyTextureData(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1123 bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions& gl, GLint target, GLint format,
1124 GLuint& texture, GLint level)
1125 {
1126 mLog << "Verify Texture [level: " << level << "] - ";
1127
1128 if (level > mState.levels - 1)
1129 TCU_FAIL("Invalid level");
1130
1131 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1132
1133 GLint width;
1134 GLint height;
1135 GLint depth;
1136 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1137
1138 //Committed region is limited to 1/2 of width
1139 GLint widthCommitted = width / 2;
1140
1141 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1142 return true;
1143
1144 bool result = true;
1145
1146 if (target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1147 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1148 {
1149 GLint texSize = width * height * depth * mState.format.getPixelSize();
1150
1151 std::vector<GLubyte> vecExpData;
1152 std::vector<GLubyte> vecOutData;
1153 vecExpData.resize(texSize);
1154 vecOutData.resize(texSize);
1155 GLubyte* exp_data = vecExpData.data();
1156 GLubyte* out_data = vecOutData.data();
1157
1158 deMemset(exp_data, 255, texSize);
1159 deMemset(out_data, 127, texSize);
1160
1161 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1162 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1163
1164 //Verify only committed region
1165 for (GLint x = 0; x < widthCommitted; ++x)
1166 for (GLint y = 0; y < height; ++y)
1167 for (GLint z = 0; z < depth; ++z)
1168 {
1169 int pixelSize = mState.format.getPixelSize();
1170 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1171 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1172 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1173 result = false;
1174 }
1175 }
1176 else if (target == GL_TEXTURE_CUBE_MAP)
1177 {
1178 std::vector<GLint> subTargets;
1179
1180 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1181 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1182 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1183 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1184 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1185 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1186
1187 GLint texSize = width * height * mState.format.getPixelSize();
1188
1189 std::vector<GLubyte> vecExpData;
1190 std::vector<GLubyte> vecOutData;
1191 vecExpData.resize(texSize);
1192 vecOutData.resize(texSize);
1193 GLubyte* exp_data = vecExpData.data();
1194 GLubyte* out_data = vecOutData.data();
1195
1196 deMemset(exp_data, 255, texSize);
1197
1198 for (size_t i = 0; i < subTargets.size(); ++i)
1199 {
1200 GLint subTarget = subTargets[i];
1201
1202 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1203
1204 deMemset(out_data, 127, texSize);
1205
1206 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1207 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1208
1209 //Verify only committed region
1210 for (GLint x = 0; x < widthCommitted; ++x)
1211 for (GLint y = 0; y < height; ++y)
1212 for (GLint z = 0; z < depth; ++z)
1213 {
1214 int pixelSize = mState.format.getPixelSize();
1215 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1216 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1217 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1218 result = false;
1219 }
1220
1221 if (!result)
1222 break;
1223 }
1224 }
1225 // For multisample texture use compute shader to verify image data
1226 else if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1227 {
1228 GLint texSize = width * height * depth;
1229
1230 std::vector<GLubyte> vecExpData;
1231 std::vector<GLubyte> vecOutData;
1232 vecExpData.resize(texSize);
1233 vecOutData.resize(texSize);
1234 GLubyte* exp_data = vecExpData.data();
1235 GLubyte* out_data = vecOutData.data();
1236
1237 deMemset(exp_data, 255, texSize);
1238
1239 // Create verifying texture
1240 GLint verifyTarget;
1241 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1242 verifyTarget = GL_TEXTURE_2D;
1243 else
1244 verifyTarget = GL_TEXTURE_2D_ARRAY;
1245
1246 GLuint verifyTexture;
1247 Texture::Generate(gl, verifyTexture);
1248 Texture::Bind(gl, verifyTexture, verifyTarget);
1249 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1250 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1251
1252 for (int sample = 0; sample < mState.samples; ++sample)
1253 {
1254 deMemset(out_data, 0, texSize);
1255
1256 Texture::Bind(gl, verifyTexture, verifyTarget);
1257 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1258 (GLvoid*)out_data);
1259 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1260
1261 std::string shader = st2_compute_textureVerify;
1262
1263 // Adjust shader source to texture format
1264 TokenStrings s = createShaderTokens(target, format, sample);
1265
1266 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1267 replaceToken("<FORMAT>", s.format.c_str(), shader);
1268 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1269 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1270 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1271 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1272 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1273 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1274 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1275
1276 ProgramSources sources;
1277 sources << ComputeSource(shader);
1278
1279 // Build and run shader
1280 ShaderProgram program(m_context.getRenderContext(), sources);
1281 if (program.isOk())
1282 {
1283 gl.useProgram(program.getProgram());
1284 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1285 gl.bindImageTexture(0, //unit
1286 verifyTexture,
1287 0, //level
1288 GL_FALSE, //layered
1289 0, //layer
1290 GL_WRITE_ONLY, GL_R8UI);
1291 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1292 gl.bindImageTexture(1, //unit
1293 texture,
1294 level, //level
1295 GL_FALSE, //layered
1296 0, //layer
1297 GL_READ_ONLY, format);
1298 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1299 gl.uniform1i(1, 0 /* image_unit */);
1300 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1301 gl.uniform1i(2, 1 /* image_unit */);
1302 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1303 gl.dispatchCompute(width, height, depth);
1304 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1305 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1306 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1307
1308 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
1309 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1310
1311 //Verify only committed region
1312 for (GLint x = 0; x < widthCommitted; ++x)
1313 for (GLint y = 0; y < height; ++y)
1314 for (GLint z = 0; z < depth; ++z)
1315 {
1316 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
1317 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
1318 if (dataRegion[0] != outDataRegion[0])
1319 result = false;
1320 }
1321 }
1322 else
1323 {
1324 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1325 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1326 << ", shaderSource: " << shader.c_str() << " - ";
1327
1328 result = false;
1329 }
1330 }
1331
1332 Texture::Delete(gl, verifyTexture);
1333 }
1334
1335 return result;
1336 }
1337
1338 const GLfloat texCoord[] = {
1339 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1340 };
1341
1342 const GLfloat vertices[] = {
1343 -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1344 };
1345
1346 const GLuint indices[] = { 0, 1, 2, 1, 2, 3 };
1347
1348 /** Constructor.
1349 *
1350 * @param context Rendering context
1351 */
UncommittedRegionsAccessTestCase(deqp::Context & context)1352 UncommittedRegionsAccessTestCase::UncommittedRegionsAccessTestCase(deqp::Context& context)
1353 : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccess",
1354 "Verifies if access to uncommitted regions of sparse texture works as expected")
1355 {
1356 /* Left blank intentionally */
1357 }
1358
1359 /** Stub init method */
init()1360 void UncommittedRegionsAccessTestCase::init()
1361 {
1362 SparseTextureCommitmentTestCase::init();
1363
1364 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
1365 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
1366 }
1367
1368 /** Executes test iteration.
1369 *
1370 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1371 */
iterate()1372 tcu::TestNode::IterateResult UncommittedRegionsAccessTestCase::iterate()
1373 {
1374 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
1375 {
1376 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1377 return STOP;
1378 }
1379
1380 const Functions& gl = m_context.getRenderContext().getFunctions();
1381
1382 bool result = true;
1383
1384 GLuint texture;
1385
1386 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
1387 ++iter)
1388 {
1389 const GLint& target = *iter;
1390
1391 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1392 formIter != mSupportedInternalFormats.end(); ++formIter)
1393 {
1394 const GLint& format = *formIter;
1395
1396 if (!caseAllowed(target, format))
1397 continue;
1398
1399 mLog.str("");
1400 mLog << "Testing uncommitted regions access for target: " << target << ", format: " << format << " - ";
1401
1402 sparseAllocateTexture(gl, target, format, texture, 3);
1403 for (int l = 0; l < mState.levels; ++l)
1404 {
1405 if (commitTexturePage(gl, target, format, texture, l))
1406 {
1407 writeDataToTexture(gl, target, format, texture, l);
1408 result = result && UncommittedReads(gl, target, format, texture, l);
1409 result = result && UncommittedAtomicOperations(gl, target, format, texture, l);
1410 }
1411
1412 if (!result)
1413 break;
1414 }
1415
1416 Texture::Delete(gl, texture);
1417
1418 if (!result)
1419 {
1420 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1421 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1422 return STOP;
1423 }
1424 }
1425 }
1426
1427 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1428 return STOP;
1429 }
1430
1431 /** Check if reads from uncommitted regions are allowed
1432 *
1433 * @param target Target for which texture is binded
1434 * @param format Texture internal format
1435 *
1436 * @return Returns true if allowed, false otherwise.
1437 */
readsAllowed(GLint target,GLint format,bool shaderOnly)1438 bool UncommittedRegionsAccessTestCase::readsAllowed(GLint target, GLint format, bool shaderOnly)
1439 {
1440 DE_UNREF(target);
1441
1442 if (shaderOnly && (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
1443 {
1444 return false;
1445 }
1446
1447 return true;
1448 }
1449
1450 /** Check if atomic operations on uncommitted regions are allowed
1451 *
1452 * @param target Target for which texture is binded
1453 * @param format Texture internal format
1454 *
1455 * @return Returns true if allowed, false otherwise.
1456 */
atomicAllowed(GLint target,GLint format)1457 bool UncommittedRegionsAccessTestCase::atomicAllowed(GLint target, GLint format)
1458 {
1459 DE_UNREF(target);
1460
1461 if (format == GL_R32I || format == GL_R32UI)
1462 {
1463 return true;
1464 }
1465
1466 return false;
1467 }
1468
1469 /** Check if depth and stencil test on uncommitted regions are allowed
1470 *
1471 * @param target Target for which texture is binded
1472 * @param format Texture internal format
1473 *
1474 * @return Returns true if allowed, false otherwise.
1475 */
depthStencilAllowed(GLint target,GLint format)1476 bool UncommittedRegionsAccessTestCase::depthStencilAllowed(GLint target, GLint format)
1477 {
1478 if (target == GL_TEXTURE_2D && format == GL_RGBA8)
1479 {
1480 return true;
1481 }
1482
1483 return false;
1484 }
1485
1486 /** Verify reads from uncommitted texture regions works as expected
1487 *
1488 * @param gl GL API functions
1489 * @param target Target for which texture is binded
1490 * @param format Texture internal format
1491 * @param texture Texture object
1492 * @param level Texture mipmap level
1493 *
1494 * @return Returns true if data is as expected, false otherwise.
1495 */
UncommittedReads(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1496 bool UncommittedRegionsAccessTestCase::UncommittedReads(const Functions& gl, GLint target, GLint format,
1497 GLuint& texture, GLint level)
1498 {
1499 bool result = true;
1500
1501 // Verify using API glGetTexImage*
1502 if (readsAllowed(target, format, false))
1503 {
1504 mLog << "API Reads - ";
1505 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1506 }
1507
1508 // Verify using shader imageLoad function
1509 if (result && readsAllowed(target, format, true))
1510 {
1511 mLog << "Shader Reads - ";
1512 result = result && verifyTextureDataExtended(gl, target, format, texture, level, true);
1513 }
1514
1515 // Verify mipmap generating
1516 if (result && level == 0 && target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
1517 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1518 {
1519 mLog << "Mipmap Generate - ";
1520 Texture::Bind(gl, texture, target);
1521 gl.generateMipmap(target);
1522 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap");
1523
1524 for (int l = 1; l < mState.levels; ++l)
1525 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1526 }
1527
1528 return result;
1529 }
1530
1531 /** Verify atomic operations on uncommitted texture pixels works as expected
1532 *
1533 * @param gl GL API functions
1534 * @param target Target for which texture is binded
1535 * @param format Texture internal format
1536 * @param texture Texture object
1537 * @param level Texture mipmap level
1538 *
1539 * @return Returns true if data is as expected, false otherwise.
1540 */
UncommittedAtomicOperations(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1541 bool UncommittedRegionsAccessTestCase::UncommittedAtomicOperations(const Functions& gl, GLint target, GLint format,
1542 GLuint& texture, GLint level)
1543 {
1544 bool result = true;
1545
1546 if (atomicAllowed(target, format))
1547 {
1548 mLog << "Atomic Operations - ";
1549 result = result && verifyAtomicOperations(gl, target, format, texture, level);
1550 }
1551
1552 return result;
1553 }
1554
1555 /** Verify depth and stencil tests on uncommitted texture pixels works as expected
1556 *
1557 * @param gl GL API functions
1558 * @param target Target for which texture is binded
1559 * @param format Texture internal format
1560 * @param texture Texture object
1561 * @param level Texture mipmap level
1562 *
1563 * @return Returns true if data is as expected, false otherwise.
1564 */
UncommittedDepthStencil(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1565 bool UncommittedRegionsAccessTestCase::UncommittedDepthStencil(const Functions& gl, GLint target, GLint format,
1566 GLuint& texture, GLint level)
1567 {
1568 if (!depthStencilAllowed(target, format))
1569 return true;
1570
1571 mLog << "Depth Stencil - ";
1572
1573 bool result = true;
1574
1575 GLint width;
1576 GLint height;
1577 GLint depth;
1578 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1579
1580 //Committed region is limited to 1/2 of width
1581 GLuint widthCommitted = width / 2;
1582
1583 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1584 return true;
1585
1586 //Prepare shaders
1587 std::string vertexSource = st2_vertex_drawBuffer;
1588 std::string fragmentSource = st2_fragment_drawBuffer;
1589
1590 ShaderProgram program(gl, glu::makeVtxFragSources(vertexSource, fragmentSource));
1591 if (!program.isOk())
1592 {
1593 mLog << "Shader compilation failed (depth_stencil) for target: " << target << ", format: " << format
1594 << ", vertex_infoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog
1595 << ", fragment_infoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog
1596 << ", vertexSource: " << vertexSource.c_str() << "\n"
1597 << ", fragmentSource: " << fragmentSource.c_str() << " - ";
1598
1599 return false;
1600 }
1601
1602 prepareDepthStencilFramebuffer(gl, width, height);
1603
1604 gl.useProgram(program.getProgram());
1605
1606 gl.activeTexture(GL_TEXTURE0);
1607 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
1608 Texture::Bind(gl, texture, target);
1609 gl.uniform1i(1, 0);
1610 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1611
1612 // Stencil test
1613 result = result && verifyStencilTest(gl, program, width, height, widthCommitted);
1614
1615 // Depth test
1616 result = result && verifyDepthTest(gl, program, width, height, widthCommitted);
1617
1618 // Depth bounds test
1619 if (m_context.getContextInfo().isExtensionSupported("GL_EXT_depth_bounds_test"))
1620 result = result && verifyDepthBoundsTest(gl, program, width, height, widthCommitted);
1621
1622 // Resources cleaning
1623 cleanupDepthStencilFramebuffer(gl);
1624
1625 return result;
1626 }
1627
1628 /** Prepare gl depth and stencil test resources
1629 *
1630 * @param gl GL API functions
1631 * @param width Framebuffer width
1632 * @param height Framebuffer height
1633 */
prepareDepthStencilFramebuffer(const Functions & gl,GLint width,GLint height)1634 void UncommittedRegionsAccessTestCase::prepareDepthStencilFramebuffer(const Functions& gl, GLint width, GLint height)
1635 {
1636 gl.genRenderbuffers(1, &mRenderbuffer);
1637 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers");
1638 gl.bindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
1639 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer");
1640 if (mState.samples == 1)
1641 {
1642 gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
1643 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage");
1644 }
1645 else
1646 {
1647 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, mState.samples, GL_DEPTH_STENCIL, width, height);
1648 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample");
1649 }
1650
1651 gl.genFramebuffers(1, &mFramebuffer);
1652 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
1653 gl.bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
1654 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1655 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer);
1656 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
1657 gl.viewport(0, 0, width, height);
1658 }
1659
1660 /** Cleanup gl depth and stencil test resources
1661 *
1662 * @param gl GL API functions
1663 */
cleanupDepthStencilFramebuffer(const Functions & gl)1664 void UncommittedRegionsAccessTestCase::cleanupDepthStencilFramebuffer(const Functions& gl)
1665 {
1666 gl.deleteFramebuffers(1, &mFramebuffer);
1667 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1668 gl.deleteRenderbuffers(1, &mRenderbuffer);
1669 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers");
1670
1671 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1672 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1673 }
1674
1675 /** Verify if data stored in texture in uncommitted regions is as expected
1676 *
1677 * @param gl GL API functions
1678 * @param target Target for which texture is binded
1679 * @param format Texture internal format
1680 * @param texture Texture object
1681 * @param level Texture mipmap level
1682 * @param shaderOnly Shader texture filling flag, default false
1683 *
1684 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1685 */
verifyTextureDataExtended(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level,bool shaderOnly)1686 bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions& gl, GLint target, GLint format,
1687 GLuint& texture, GLint level, bool shaderOnly)
1688 {
1689 mLog << "Verify Texture [level: " << level << "] - ";
1690
1691 if (level > mState.levels - 1)
1692 TCU_FAIL("Invalid level");
1693
1694 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1695
1696 GLint width;
1697 GLint height;
1698 GLint depth;
1699 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1700
1701 //Committed region is limited to 1/2 of width
1702 GLint widthCommitted = width / 2;
1703
1704 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1705 return true;
1706
1707 bool result = true;
1708
1709 // Verify texture using API glGetTexImage* (Skip multisample textures as it can not be verified using API)
1710 if (!shaderOnly && target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1711 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1712 {
1713 GLint texSize = width * height * depth * mState.format.getPixelSize();
1714
1715 std::vector<GLubyte> vecExpData;
1716 std::vector<GLubyte> vecOutData;
1717 vecExpData.resize(texSize);
1718 vecOutData.resize(texSize);
1719 GLubyte* exp_data = vecExpData.data();
1720 GLubyte* out_data = vecOutData.data();
1721
1722 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
1723 deMemset(exp_data, 0, texSize);
1724 deMemset(out_data, 255, texSize);
1725
1726 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1727 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1728
1729 //Verify only uncommitted region
1730 for (GLint x = widthCommitted; x < width; ++x)
1731 for (GLint y = 0; y < height; ++y)
1732 for (GLint z = 0; z < depth; ++z)
1733 {
1734 int pixelSize = mState.format.getPixelSize();
1735 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1736 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1737 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1738 result = false;
1739 }
1740 }
1741 // Verify texture using API glGetTexImage* (Only cube map as it has to be verified for subtargets)
1742 else if (!shaderOnly && target == GL_TEXTURE_CUBE_MAP)
1743 {
1744 std::vector<GLint> subTargets;
1745
1746 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1747 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1748 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1749 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1750 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1751 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1752
1753 GLint texSize = width * height * mState.format.getPixelSize();
1754
1755 std::vector<GLubyte> vecExpData;
1756 std::vector<GLubyte> vecOutData;
1757 vecExpData.resize(texSize);
1758 vecOutData.resize(texSize);
1759 GLubyte* exp_data = vecExpData.data();
1760 GLubyte* out_data = vecOutData.data();
1761
1762 deMemset(exp_data, 0, texSize);
1763
1764 for (size_t i = 0; i < subTargets.size(); ++i)
1765 {
1766 GLint subTarget = subTargets[i];
1767
1768 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1769
1770 deMemset(out_data, 255, texSize);
1771
1772 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1773 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1774
1775 //Verify only uncommitted region
1776 for (GLint x = widthCommitted; x < width; ++x)
1777 for (GLint y = 0; y < height; ++y)
1778 for (GLint z = 0; z < depth; ++z)
1779 {
1780 int pixelSize = mState.format.getPixelSize();
1781 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1782 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1783 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1784 result = false;
1785 }
1786
1787 if (!result)
1788 break;
1789 }
1790 }
1791 // Verify texture using shader imageLoad function
1792 else if (shaderOnly)
1793 {
1794 // Create verifying texture
1795 GLint verifyTarget;
1796 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1797 verifyTarget = GL_TEXTURE_2D;
1798 else
1799 verifyTarget = GL_TEXTURE_2D_ARRAY;
1800
1801 if (target == GL_TEXTURE_CUBE_MAP)
1802 depth = depth * 6;
1803
1804 GLint texSize = width * height * depth;
1805
1806 std::vector<GLubyte> vecExpData;
1807 std::vector<GLubyte> vecOutData;
1808 vecExpData.resize(texSize);
1809 vecOutData.resize(texSize);
1810 GLubyte* exp_data = vecExpData.data();
1811 GLubyte* out_data = vecOutData.data();
1812
1813 // Expected value in this case is 255 because shader fills output texture with 255 if in texture is filled with zeros
1814 deMemset(exp_data, 255, texSize);
1815
1816 GLuint verifyTexture;
1817 Texture::Generate(gl, verifyTexture);
1818 Texture::Bind(gl, verifyTexture, verifyTarget);
1819 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1820 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1821
1822 for (GLint sample = 0; sample < mState.samples; ++sample)
1823 {
1824 deMemset(out_data, 0, texSize);
1825
1826 Texture::Bind(gl, verifyTexture, verifyTarget);
1827 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1828 (GLvoid*)out_data);
1829 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1830
1831 std::string shader = st2_compute_textureVerify;
1832
1833 // Adjust shader source to texture format
1834 TokenStrings s = createShaderTokens(target, format, sample);
1835
1836 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1837 replaceToken("<FORMAT>", s.format.c_str(), shader);
1838 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1839 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1840 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1841 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1842 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1843 replaceToken("<RESULT_EXPECTED>", s.resultDefault.c_str(), shader);
1844 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1845
1846 ProgramSources sources;
1847 sources << ComputeSource(shader);
1848
1849 // Build and run shader
1850 ShaderProgram program(m_context.getRenderContext(), sources);
1851 if (program.isOk())
1852 {
1853 gl.useProgram(program.getProgram());
1854 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1855 gl.bindImageTexture(0, //unit
1856 verifyTexture,
1857 0, //level
1858 GL_FALSE, //layered
1859 0, //layer
1860 GL_WRITE_ONLY, GL_R8UI);
1861 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1862 gl.bindImageTexture(1, //unit
1863 texture,
1864 level, //level
1865 GL_FALSE, //layered
1866 0, //layer
1867 GL_READ_ONLY, format);
1868 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1869 gl.uniform1i(1, 0 /* image_unit */);
1870 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1871 gl.uniform1i(2, 1 /* image_unit */);
1872 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1873 gl.dispatchCompute(width, height, depth);
1874 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1875 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1876 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1877
1878 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
1879 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1880
1881 //Verify only committed region
1882 for (GLint x = widthCommitted; x < width; ++x)
1883 for (GLint y = 0; y < height; ++y)
1884 for (GLint z = 0; z < depth; ++z)
1885 {
1886 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
1887 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
1888 if (dataRegion[0] != outDataRegion[0])
1889 result = false;
1890 }
1891 }
1892 else
1893 {
1894 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1895 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1896 << ", shaderSource: " << shader.c_str() << " - ";
1897
1898 result = false;
1899 }
1900 }
1901
1902 Texture::Delete(gl, verifyTexture);
1903 }
1904
1905 return result;
1906 }
1907
1908 /** Verify if atomic operations on uncommitted regions returns zeros and has no effect on texture
1909 *
1910 * @param gl GL API functions
1911 * @param target Target for which texture is binded
1912 * @param format Texture internal format
1913 * @param texture Texture object
1914 * @param level Texture mipmap level
1915 *
1916 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1917 */
verifyAtomicOperations(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1918 bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& gl, GLint target, GLint format,
1919 GLuint& texture, GLint level)
1920 {
1921 mLog << "Verify Atomic Operations [level: " << level << "] - ";
1922
1923 if (level > mState.levels - 1)
1924 TCU_FAIL("Invalid level");
1925
1926 GLint width;
1927 GLint height;
1928 GLint depth;
1929 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1930
1931 //Committed region is limited to 1/2 of width
1932 GLint widthCommitted = width / 2;
1933
1934 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1935 return true;
1936
1937 bool result = true;
1938
1939 // Create verifying texture
1940 GLint verifyTarget;
1941 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1942 verifyTarget = GL_TEXTURE_2D;
1943 else
1944 verifyTarget = GL_TEXTURE_2D_ARRAY;
1945
1946 GLint texSize = width * height * depth;
1947
1948 std::vector<GLubyte> vecExpData;
1949 std::vector<GLubyte> vecOutData;
1950 vecExpData.resize(texSize);
1951 vecOutData.resize(texSize);
1952 GLubyte* exp_data = vecExpData.data();
1953 GLubyte* out_data = vecOutData.data();
1954
1955 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
1956 deMemset(exp_data, 0, texSize);
1957
1958 GLuint verifyTexture;
1959 Texture::Generate(gl, verifyTexture);
1960 Texture::Bind(gl, verifyTexture, verifyTarget);
1961 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1962 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1963
1964 for (GLint sample = 0; sample < mState.samples; ++sample)
1965 {
1966 deMemset(out_data, 255, texSize);
1967
1968 Texture::Bind(gl, verifyTexture, verifyTarget);
1969 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1970 (GLvoid*)out_data);
1971 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1972
1973 std::string shader = st2_compute_atomicVerify;
1974
1975 // Adjust shader source to texture format
1976 TokenStrings s = createShaderTokens(target, format, sample);
1977 std::string dataType = (s.returnType == "ivec4" ? "int" : "uint");
1978
1979 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1980 replaceToken("<FORMAT>", s.format.c_str(), shader);
1981 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1982 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1983 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1984 replaceToken("<DATA_TYPE>", dataType.c_str(), shader);
1985 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1986 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1987
1988 ProgramSources sources;
1989 sources << ComputeSource(shader);
1990
1991 // Build and run shader
1992 ShaderProgram program(m_context.getRenderContext(), sources);
1993 if (program.isOk())
1994 {
1995 gl.useProgram(program.getProgram());
1996 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1997 gl.bindImageTexture(0, //unit
1998 verifyTexture,
1999 0, //level
2000 GL_FALSE, //layered
2001 0, //layer
2002 GL_WRITE_ONLY, GL_R8UI);
2003 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2004 gl.bindImageTexture(1, //unit
2005 texture,
2006 level, //level
2007 GL_FALSE, //layered
2008 0, //layer
2009 GL_READ_ONLY, format);
2010 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2011 gl.uniform1i(1, 0 /* image_unit */);
2012 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2013 gl.uniform1i(2, 1 /* image_unit */);
2014 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2015 gl.uniform1i(3, widthCommitted /* committed width */);
2016 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2017 gl.dispatchCompute(width, height, depth);
2018 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2019 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2020 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2021
2022 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
2023 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
2024
2025 //Verify only committed region
2026 for (GLint x = 0; x < width; ++x)
2027 for (GLint y = 0; y < height; ++y)
2028 for (GLint z = 0; z < depth; ++z)
2029 {
2030 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
2031 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
2032 if (dataRegion[0] != outDataRegion[0])
2033 {
2034 printf("%d:%d ", dataRegion[0], outDataRegion[0]);
2035 result = false;
2036 }
2037 }
2038 }
2039 else
2040 {
2041 mLog << "Compute shader compilation failed (atomic) for target: " << target << ", format: " << format
2042 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2043 << ", shaderSource: " << shader.c_str() << " - ";
2044
2045 result = false;
2046 }
2047 }
2048
2049 Texture::Delete(gl, verifyTexture);
2050
2051 return result;
2052 }
2053
2054 /** Verify if stencil test on uncommitted texture region works as expected texture
2055 *
2056 * @param gl GL API functions
2057 * @param program Shader program
2058 * @param width Texture width
2059 * @param height Texture height
2060 * @param widthCommitted Committed region width
2061 *
2062 * @return Returns true if stencil data is as expected, false otherwise.
2063 */
verifyStencilTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2064 bool UncommittedRegionsAccessTestCase::verifyStencilTest(const Functions& gl, ShaderProgram& program, GLint width,
2065 GLint height, GLint widthCommitted)
2066 {
2067 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2068 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2069
2070 mLog << "Perform Stencil Test - ";
2071
2072 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2073 gl.enable(GL_STENCIL_TEST);
2074 gl.stencilFunc(GL_GREATER, 1, 0xFF);
2075 gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2076
2077 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2078 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2079
2080 std::vector<GLubyte> dataStencil;
2081 dataStencil.resize(width * height);
2082 GLubyte* dataStencilPtr = dataStencil.data();
2083
2084 gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, (GLvoid*)dataStencilPtr);
2085 for (int x = widthCommitted; x < width; ++x)
2086 for (int y = 0; y < height; ++y)
2087 {
2088 if (dataStencilPtr[x + y * width] != 0x00)
2089 {
2090 gl.disable(GL_STENCIL_TEST);
2091 return false;
2092 }
2093 }
2094
2095 gl.disable(GL_STENCIL_TEST);
2096 return true;
2097 }
2098
2099 /** Verify if depth test on uncommitted texture region works as expected texture
2100 *
2101 * @param gl GL API functions
2102 * @param program Shader program
2103 * @param width Texture width
2104 * @param height Texture height
2105 * @param widthCommitted Committed region width
2106 *
2107 * @return Returns true if depth data is as expected, false otherwise.
2108 */
verifyDepthTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2109 bool UncommittedRegionsAccessTestCase::verifyDepthTest(const Functions& gl, ShaderProgram& program, GLint width,
2110 GLint height, GLint widthCommitted)
2111 {
2112 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2113 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2114
2115 mLog << "Perform Depth Test - ";
2116
2117 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2118 gl.enable(GL_DEPTH_TEST);
2119 gl.depthFunc(GL_LESS);
2120
2121 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2122 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2123
2124 std::vector<GLuint> dataDepth;
2125 dataDepth.resize(width * height);
2126 GLuint* dataDepthPtr = dataDepth.data();
2127
2128 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr);
2129 for (int x = widthCommitted; x < width; ++x)
2130 for (int y = 0; y < height; ++y)
2131 {
2132 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2133 {
2134 gl.disable(GL_DEPTH_TEST);
2135 return false;
2136 }
2137 }
2138
2139 gl.disable(GL_DEPTH_TEST);
2140 return true;
2141 }
2142
2143 /** Verify if depth bounds test on uncommitted texture region works as expected texture
2144 *
2145 * @param gl GL API functions
2146 * @param program Shader program
2147 * @param width Texture width
2148 * @param height Texture height
2149 * @param widthCommitted Committed region width
2150 *
2151 * @return Returns true if depth data is as expected, false otherwise.
2152 */
verifyDepthBoundsTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2153 bool UncommittedRegionsAccessTestCase::verifyDepthBoundsTest(const Functions& gl, ShaderProgram& program, GLint width,
2154 GLint height, GLint widthCommitted)
2155 {
2156 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2157 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2158
2159 mLog << "Perform Depth Bounds Test - ";
2160
2161 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2162 gl.enable(GL_DEPTH_BOUNDS_TEST_EXT);
2163 gl.depthFunc(GL_LESS);
2164
2165 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2166 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2167
2168 std::vector<GLuint> dataDepth;
2169 dataDepth.resize(width * height);
2170 GLuint* dataDepthPtr = dataDepth.data();
2171
2172 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr);
2173 for (int x = widthCommitted; x < width; ++x)
2174 for (int y = 0; y < height; ++y)
2175 {
2176 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2177 {
2178 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2179 return false;
2180 }
2181 }
2182
2183 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2184 return true;
2185 }
2186
2187 /** Constructor.
2188 *
2189 * @param context Rendering context
2190 */
SparseTexture2LookupTestCase(deqp::Context & context)2191 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context)
2192 : SparseTexture2CommitmentTestCase(context, "SparseTexture2Lookup",
2193 "Verifies if sparse texture lookup functions for GLSL works as expected")
2194 {
2195 /* Left blank intentionally */
2196 }
2197
2198 /** Constructor.
2199 *
2200 * @param context Rendering context
2201 */
SparseTexture2LookupTestCase(deqp::Context & context,const char * name,const char * description)2202 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context, const char* name,
2203 const char* description)
2204 : SparseTexture2CommitmentTestCase(context, name, description)
2205 {
2206 /* Left blank intentionally */
2207 }
2208
2209 /** Initializes the test group contents. */
init()2210 void SparseTexture2LookupTestCase::init()
2211 {
2212 SparseTextureCommitmentTestCase::init();
2213 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
2214 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2215
2216 mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16);
2217
2218 FunctionToken f;
2219 f = FunctionToken("sparseTextureARB", "<CUBE_REFZ_DEF>");
2220 f.allowedTargets.insert(GL_TEXTURE_2D);
2221 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2222 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2223 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2224 f.allowedTargets.insert(GL_TEXTURE_3D);
2225 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2226 mFunctions.push_back(f);
2227
2228 f = FunctionToken("sparseTextureLodARB", ", <LOD>");
2229 f.allowedTargets.insert(GL_TEXTURE_2D);
2230 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2231 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2232 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2233 f.allowedTargets.insert(GL_TEXTURE_3D);
2234 mFunctions.push_back(f);
2235
2236 f = FunctionToken("sparseTextureOffsetARB", ", <OFFSET_TYPE><OFFSET_DIM>(0)");
2237 f.allowedTargets.insert(GL_TEXTURE_2D);
2238 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2239 f.allowedTargets.insert(GL_TEXTURE_3D);
2240 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2241 mFunctions.push_back(f);
2242
2243 f = FunctionToken("sparseTexelFetchARB", "<LOD_DEF>");
2244 f.allowedTargets.insert(GL_TEXTURE_2D);
2245 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2246 f.allowedTargets.insert(GL_TEXTURE_3D);
2247 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2248 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2249 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2250 mFunctions.push_back(f);
2251
2252 f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2253 f.allowedTargets.insert(GL_TEXTURE_2D);
2254 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2255 f.allowedTargets.insert(GL_TEXTURE_3D);
2256 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2257 mFunctions.push_back(f);
2258
2259 f = FunctionToken("sparseTextureLodOffsetARB", ", <LOD>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2260 f.allowedTargets.insert(GL_TEXTURE_2D);
2261 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2262 f.allowedTargets.insert(GL_TEXTURE_3D);
2263 mFunctions.push_back(f);
2264
2265 f = FunctionToken("sparseTextureGradARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0)");
2266 f.allowedTargets.insert(GL_TEXTURE_2D);
2267 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2268 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2269 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2270 f.allowedTargets.insert(GL_TEXTURE_3D);
2271 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2272 mFunctions.push_back(f);
2273
2274 f = FunctionToken("sparseTextureGradOffsetARB",
2275 ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0)");
2276 f.allowedTargets.insert(GL_TEXTURE_2D);
2277 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2278 f.allowedTargets.insert(GL_TEXTURE_3D);
2279 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2280 mFunctions.push_back(f);
2281
2282 f = FunctionToken("sparseTextureGatherARB", "<REFZ_DEF>");
2283 f.allowedTargets.insert(GL_TEXTURE_2D);
2284 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2285 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2286 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2287 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2288 mFunctions.push_back(f);
2289
2290 f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2291 f.allowedTargets.insert(GL_TEXTURE_2D);
2292 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2293 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2294 mFunctions.push_back(f);
2295
2296 f = FunctionToken("sparseTextureGatherOffsetsARB", "<REFZ_DEF>, offsetsArray");
2297 f.allowedTargets.insert(GL_TEXTURE_2D);
2298 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2299 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2300 mFunctions.push_back(f);
2301
2302 f = FunctionToken("sparseImageLoadARB", "");
2303 f.allowedTargets.insert(GL_TEXTURE_2D);
2304 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2305 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2306 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2307 f.allowedTargets.insert(GL_TEXTURE_3D);
2308 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2309 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2310 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2311 //mFunctions.push_back(f);
2312 }
2313
2314 /** Executes test iteration.
2315 *
2316 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2317 */
iterate()2318 tcu::TestNode::IterateResult SparseTexture2LookupTestCase::iterate()
2319 {
2320 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
2321 {
2322 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2323 return STOP;
2324 }
2325
2326 const Functions& gl = m_context.getRenderContext().getFunctions();
2327
2328 bool result = true;
2329
2330 GLuint texture;
2331
2332 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
2333 ++iter)
2334 {
2335 const GLint& target = *iter;
2336
2337 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
2338 formIter != mSupportedInternalFormats.end(); ++formIter)
2339 {
2340 const GLint& format = *formIter;
2341
2342 if (!caseAllowed(target, format))
2343 continue;
2344
2345 for (std::vector<FunctionToken>::const_iterator tokIter = mFunctions.begin(); tokIter != mFunctions.end();
2346 ++tokIter)
2347 {
2348 // Check if target is allowed for current lookup function
2349 FunctionToken funcToken = *tokIter;
2350 if (!funcAllowed(target, format, funcToken))
2351 continue;
2352
2353 mLog.str("");
2354 mLog << "Testing sparse texture lookup functions for target: " << target << ", format: " << format
2355 << " - ";
2356
2357 sparseAllocateTexture(gl, target, format, texture, 3);
2358 if (format == GL_DEPTH_COMPONENT16)
2359 setupDepthMode(gl, target, texture);
2360
2361 for (int l = 0; l < mState.levels; ++l)
2362 {
2363 if (commitTexturePage(gl, target, format, texture, l))
2364 {
2365 writeDataToTexture(gl, target, format, texture, l);
2366 result = result && verifyLookupTextureData(gl, target, format, texture, l, funcToken);
2367 }
2368
2369 if (!result)
2370 break;
2371 }
2372
2373 Texture::Delete(gl, texture);
2374
2375 if (!result)
2376 {
2377 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
2378 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2379 return STOP;
2380 }
2381 }
2382 }
2383 }
2384
2385 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2386 return STOP;
2387 }
2388
2389 /** Create set of token strings fit to lookup functions verifying shader
2390 *
2391 * @param target Target for which texture is binded
2392 * @param format Texture internal format
2393 * @param level Texture mipmap level
2394 * @param sample Texture sample number
2395 * @param funcToken Texture lookup function structure
2396 *
2397 * @return Returns extended token strings structure.
2398 */
createLookupShaderTokens(GLint target,GLint format,GLint level,GLint sample,FunctionToken & funcToken)2399 SparseTexture2LookupTestCase::TokenStringsExt SparseTexture2LookupTestCase::createLookupShaderTokens(
2400 GLint target, GLint format, GLint level, GLint sample, FunctionToken& funcToken)
2401 {
2402 std::string funcName = funcToken.name;
2403
2404 TokenStringsExt s;
2405
2406 std::string inputType;
2407 std::string samplerSufix;
2408
2409 if (funcName == "sparseImageLoadARB")
2410 inputType = "image";
2411 else
2412 inputType = "sampler";
2413
2414 // Copy data from TokenStrings to TokenStringsExt
2415 TokenStrings ss = createShaderTokens(target, format, sample, "image", inputType);
2416 s.epsilon = ss.epsilon;
2417 s.format = ss.format;
2418 s.inputType = ss.inputType;
2419 s.outputType = ss.outputType;
2420 s.pointDef = ss.pointDef;
2421 s.pointType = ss.pointType;
2422 s.resultDefault = ss.resultDefault;
2423 s.resultExpected = ss.resultExpected;
2424 s.returnType = ss.returnType;
2425 s.sampleDef = ss.sampleDef;
2426
2427 // Set format definition for image input types
2428 if (inputType == "image")
2429 s.formatDef = ", " + s.format;
2430
2431 // Set tokens for depth texture format
2432 if (format == GL_DEPTH_COMPONENT16)
2433 {
2434 s.refZDef = ", 0.5";
2435
2436 if (inputType == "sampler" && target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_MULTISAMPLE &&
2437 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2438 {
2439 s.inputType = s.inputType + "Shadow";
2440 }
2441 }
2442
2443 // Set coord type, coord definition and offset vector dimensions
2444 s.coordType = "vec2";
2445 s.offsetType = "ivec";
2446 s.nOffsetType = "vec";
2447 s.offsetDim = "2";
2448 if (target == GL_TEXTURE_1D)
2449 {
2450 s.coordType = "float";
2451 s.offsetType = "int";
2452 s.nOffsetType = "float";
2453 s.offsetDim = "";
2454 }
2455 else if (target == GL_TEXTURE_1D_ARRAY)
2456 {
2457 s.coordType = "vec2";
2458 s.offsetType = "int";
2459 s.nOffsetType = "float";
2460 s.offsetDim = "";
2461 }
2462 else if (target == GL_TEXTURE_2D_ARRAY)
2463 {
2464 s.coordType = "vec3";
2465 }
2466 else if (target == GL_TEXTURE_3D)
2467 {
2468 s.coordType = "vec3";
2469 s.offsetDim = "3";
2470 }
2471 else if (target == GL_TEXTURE_CUBE_MAP)
2472 {
2473 s.coordType = "vec3";
2474 s.offsetDim = "3";
2475 }
2476 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2477 {
2478 s.coordType = "vec4";
2479 s.coordDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6, floor(gl_WorkGroupID.z / 6)";
2480 s.offsetDim = "3";
2481 }
2482 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2483 {
2484 s.coordType = "vec3";
2485 }
2486
2487 if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
2488 funcName.find("Fetch", 0) == std::string::npos)
2489 {
2490 s.cubeMapCoordDef = " int face = point.z % 6;\n"
2491 " if (face == 0) coord.xyz = vec3(1, coord.y * 2 - 1, -coord.x * 2 + 1);\n"
2492 " if (face == 1) coord.xyz = vec3(-1, coord.y * 2 - 1, coord.x * 2 - 1);\n"
2493 " if (face == 2) coord.xyz = vec3(coord.x * 2 - 1, 1, coord.y * 2 - 1);\n"
2494 " if (face == 3) coord.xyz = vec3(coord.x * 2 - 1, -1, -coord.y * 2 + 1);\n"
2495 " if (face == 4) coord.xyz = vec3(coord.x * 2 - 1, coord.y * 2 - 1, 1);\n"
2496 " if (face == 5) coord.xyz = vec3(-coord.x * 2 + 1, coord.y * 2 - 1, -1);\n";
2497 }
2498
2499 if (s.coordDef.empty())
2500 s.coordDef = s.pointDef;
2501
2502 // Set expected result vector, component definition and offset array definition for gather functions
2503 if (funcName.find("Gather", 0) != std::string::npos)
2504 {
2505 if (funcName.find("GatherOffsets", 0) != std::string::npos)
2506 {
2507 s.offsetArrayDef = " <OFFSET_TYPE><OFFSET_DIM> offsetsArray[4];\n"
2508 " offsetsArray[0] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2509 " offsetsArray[1] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2510 " offsetsArray[2] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2511 " offsetsArray[3] = <OFFSET_TYPE><OFFSET_DIM>(0);\n";
2512 }
2513
2514 if (format != GL_DEPTH_COMPONENT16)
2515 s.componentDef = ", 0";
2516 s.resultExpected = "(1, 1, 1, 1)";
2517 }
2518 // Extend coord type dimension and coord vector definition if shadow sampler and non-cube map array target selected
2519 // Set component definition to red component
2520 else if (format == GL_DEPTH_COMPONENT16)
2521 {
2522 if (target != GL_TEXTURE_CUBE_MAP_ARRAY)
2523 {
2524 if (s.coordType == "float")
2525 s.coordType = "vec3";
2526 else if (s.coordType == "vec2")
2527 s.coordType = "vec3";
2528 else if (s.coordType == "vec3")
2529 s.coordType = "vec4";
2530 s.coordDef += s.refZDef;
2531 }
2532 else
2533 s.cubeMapArrayRefZDef = s.refZDef;
2534
2535 s.componentDef = ".r";
2536 }
2537
2538 // Set level of details definition
2539 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
2540 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2541 {
2542 s.lod = de::toString(level);
2543 s.lodDef = ", " + de::toString(level);
2544 }
2545
2546 // Set proper coord vector
2547 if (target == GL_TEXTURE_RECTANGLE || funcName.find("Fetch") != std::string::npos ||
2548 funcName.find("ImageLoad") != std::string::npos)
2549 {
2550 s.pointCoord = "icoord";
2551 }
2552 else
2553 s.pointCoord = "coord";
2554
2555 // Set size vector definition
2556 if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos)
2557 {
2558 if (s.coordType == "float")
2559 s.sizeDef = "<TEX_WIDTH>";
2560 else if (s.coordType == "vec2" && target == GL_TEXTURE_1D_ARRAY)
2561 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>";
2562 else if (s.coordType == "vec2")
2563 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>";
2564 else if (s.coordType == "vec3")
2565 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>";
2566 else if (s.coordType == "vec4")
2567 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 6, floor(<TEX_DEPTH> / 6)";
2568 }
2569 // Set size vector for shadow samplers and non-gether functions selected
2570 else
2571 {
2572 if (s.coordType == "vec3" && target == GL_TEXTURE_1D)
2573 s.sizeDef = "<TEX_WIDTH>, 1 , 1";
2574 else if (s.coordType == "vec3" && target == GL_TEXTURE_1D_ARRAY)
2575 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>, 1";
2576 else if (s.coordType == "vec3")
2577 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 1";
2578 else if (s.coordType == "vec4")
2579 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>, 1";
2580 }
2581
2582 if (s.coordType != "float")
2583 s.iCoordType = "i" + s.coordType;
2584 else
2585 s.iCoordType = "int";
2586
2587 return s;
2588 }
2589
2590 /** Check if specific combination of target and format is
2591
2592 *
2593 * @param target Target for which texture is binded
2594 * @param format Texture internal format
2595 *
2596 * @return Returns true if target/format combination is allowed, false otherwise.
2597 */
caseAllowed(GLint target,GLint format)2598 bool SparseTexture2LookupTestCase::caseAllowed(GLint target, GLint format)
2599 {
2600 DE_UNREF(target);
2601
2602 // As shaders do not support some texture formats it is necessary to exclude them.
2603 if (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5)
2604 {
2605 return false;
2606 }
2607
2608 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_3D) &&
2609 (format == GL_DEPTH_COMPONENT16))
2610 {
2611 return false;
2612 }
2613
2614 return true;
2615 }
2616
2617 /** Check if specific lookup function is allowed for specific target and format
2618 *
2619 * @param target Target for which texture is binded
2620 * @param format Texture internal format
2621 * @param funcToken Texture lookup function structure
2622 *
2623 * @return Returns true if target/format combination is allowed, false otherwise.
2624 */
funcAllowed(GLint target,GLint format,FunctionToken & funcToken)2625 bool SparseTexture2LookupTestCase::funcAllowed(GLint target, GLint format, FunctionToken& funcToken)
2626 {
2627 if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end())
2628 return false;
2629
2630 if (format == GL_DEPTH_COMPONENT16)
2631 {
2632 if (funcToken.name == "sparseTextureLodARB" || funcToken.name == "sparseTextureLodOffsetARB")
2633 {
2634 if (target != GL_TEXTURE_2D)
2635 return false;
2636 }
2637 else if (funcToken.name == "sparseTextureOffsetARB" || funcToken.name == "sparseTextureGradOffsetARB" ||
2638 funcToken.name == "sparseTextureGatherOffsetARB" || funcToken.name == "sparseTextureGatherOffsetsARB")
2639 {
2640 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE)
2641 {
2642 return false;
2643 }
2644 }
2645 else if (funcToken.name == "sparseTexelFetchARB" || funcToken.name == "sparseTexelFetchOffsetARB")
2646 {
2647 return false;
2648 }
2649 else if (funcToken.name == "sparseTextureGradARB")
2650 {
2651 if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2652 return false;
2653 }
2654 else if (funcToken.name == "sparseImageLoadARB")
2655 {
2656 return false;
2657 }
2658 }
2659
2660 return true;
2661 }
2662
2663 /** Writing data to generated texture using compute shader
2664 *
2665 * @param gl GL API functions
2666 * @param target Target for which texture is binded
2667 * @param format Texture internal format
2668 * @param texture Texture object
2669 *
2670 * @return Returns true if no error occurred, otherwise throws an exception.
2671 */
writeDataToTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)2672 bool SparseTexture2LookupTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture,
2673 GLint level)
2674 {
2675 mLog << "Fill Texture with shader [level: " << level << "] - ";
2676
2677 if (level > mState.levels - 1)
2678 TCU_FAIL("Invalid level");
2679
2680 GLint width;
2681 GLint height;
2682 GLint depth;
2683 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2684
2685 if (width > 0 && height > 0 && depth >= mState.minDepth)
2686 {
2687 if (target == GL_TEXTURE_CUBE_MAP)
2688 depth = depth * 6;
2689
2690 GLint texSize = width * height * depth * mState.format.getPixelSize();
2691
2692 std::vector<GLubyte> vecData;
2693 vecData.resize(texSize);
2694 GLubyte* data = vecData.data();
2695
2696 deMemset(data, 255, texSize);
2697
2698 for (GLint sample = 0; sample < mState.samples; ++sample)
2699 {
2700 std::string shader = st2_compute_textureFill;
2701
2702 // Adjust shader source to texture format
2703 TokenStrings s = createShaderTokens(target, format, sample);
2704
2705 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2706 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2707 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2708 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2709 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2710 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2711
2712 ProgramSources sources;
2713 sources << ComputeSource(shader);
2714
2715 GLint convFormat = format;
2716 if (format == GL_DEPTH_COMPONENT16)
2717 convFormat = GL_R16;
2718
2719 // Build and run shader
2720 ShaderProgram program(m_context.getRenderContext(), sources);
2721 if (program.isOk())
2722 {
2723 gl.useProgram(program.getProgram());
2724 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2725 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */,
2726 GL_WRITE_ONLY, convFormat);
2727 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2728 gl.uniform1i(1, 0 /* image_unit */);
2729 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2730 gl.dispatchCompute(width, height, depth);
2731 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2732 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2733 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2734 }
2735 else
2736 {
2737 mLog << "Compute shader compilation failed (writing) for target: " << target << ", format: " << format
2738 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2739 << ", shaderSource: " << shader.c_str() << " - ";
2740 }
2741 }
2742 }
2743
2744 return true;
2745 }
2746
2747 /** Setup depth compare mode and compare function for depth texture
2748 *
2749 * @param gl GL API functions
2750 * @param target Target for which texture is binded
2751 * @param texture Texture object
2752 */
setupDepthMode(const Functions & gl,GLint target,GLuint & texture)2753 void SparseTexture2LookupTestCase::setupDepthMode(const Functions& gl, GLint target, GLuint& texture)
2754 {
2755 Texture::Bind(gl, texture, target);
2756 gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2757 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2758 gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
2759 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2760 }
2761
2762 /** Verify if data stored in texture is as expected
2763 *
2764 * @param gl GL API functions
2765 * @param target Target for which texture is binded
2766 * @param format Texture internal format
2767 * @param texture Texture object
2768 * @param level Texture mipmap level
2769 * @param funcToken Lookup function tokenize structure
2770 *
2771 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
2772 */
verifyLookupTextureData(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level,FunctionToken & funcToken)2773 bool SparseTexture2LookupTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format,
2774 GLuint& texture, GLint level, FunctionToken& funcToken)
2775 {
2776 mLog << "Verify Lookup Texture Data [function: " << funcToken.name << ", level: " << level << "] - ";
2777
2778 if (level > mState.levels - 1)
2779 TCU_FAIL("Invalid level");
2780
2781 GLint width;
2782 GLint height;
2783 GLint depth;
2784 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2785
2786 //Committed region is limited to 1/2 of width
2787 GLint widthCommitted = width / 2;
2788
2789 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
2790 return true;
2791
2792 bool result = true;
2793
2794 if (target == GL_TEXTURE_CUBE_MAP)
2795 depth = depth * 6;
2796
2797 GLint texSize = width * height * depth;
2798
2799 std::vector<GLubyte> vecExpData;
2800 std::vector<GLubyte> vecOutData;
2801 vecExpData.resize(texSize);
2802 vecOutData.resize(texSize);
2803 GLubyte* exp_data = vecExpData.data();
2804 GLubyte* out_data = vecOutData.data();
2805
2806 // Expected data is 255 because
2807 deMemset(exp_data, 255, texSize);
2808
2809 // Make token copy to work on
2810 FunctionToken f = funcToken;
2811
2812 // Create verifying texture
2813 GLint verifyTarget;
2814 if (target == GL_TEXTURE_2D_MULTISAMPLE)
2815 verifyTarget = GL_TEXTURE_2D;
2816 else
2817 verifyTarget = GL_TEXTURE_2D_ARRAY;
2818
2819 GLuint verifyTexture;
2820 Texture::Generate(gl, verifyTexture);
2821 Texture::Bind(gl, verifyTexture, verifyTarget);
2822 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
2823 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
2824
2825 for (int sample = 0; sample < mState.samples; ++sample)
2826 {
2827 deMemset(out_data, 0, texSize);
2828
2829 Texture::Bind(gl, verifyTexture, verifyTarget);
2830 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
2831 (GLvoid*)out_data);
2832 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
2833
2834 std::string shader = st2_compute_lookupVerify;
2835
2836 // Adjust shader source to texture format
2837 TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f);
2838
2839 replaceToken("<FUNCTION>", f.name.c_str(), shader);
2840 replaceToken("<ARGUMENTS>", f.arguments.c_str(), shader);
2841
2842 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
2843 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2844 replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), shader);
2845 replaceToken("<LOD>", s.lod.c_str(), shader);
2846 replaceToken("<LOD_DEF>", s.lodDef.c_str(), shader);
2847 replaceToken("<COORD_TYPE>", s.coordType.c_str(), shader);
2848 replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), shader);
2849 replaceToken("<COORD_DEF>", s.coordDef.c_str(), shader);
2850 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2851 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2852 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2853 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2854 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
2855 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2856 replaceToken("<REFZ_DEF>", s.refZDef.c_str(), shader);
2857 replaceToken("<CUBE_REFZ_DEF>", s.cubeMapArrayRefZDef.c_str(), shader);
2858 replaceToken("<POINT_COORD>", s.pointCoord.c_str(), shader);
2859 replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), shader);
2860 replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), shader);
2861 replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), shader);
2862 replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), shader);
2863 replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), shader);
2864 replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), shader);
2865 replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), shader);
2866
2867 replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), shader);
2868 replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), shader);
2869 replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), shader);
2870
2871 ProgramSources sources;
2872 sources << ComputeSource(shader);
2873
2874 // Build and run shader
2875 ShaderProgram program(m_context.getRenderContext(), sources);
2876 if (program.isOk())
2877 {
2878 gl.useProgram(program.getProgram());
2879 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2880
2881 // Pass output image to shader
2882 gl.bindImageTexture(1, //unit
2883 verifyTexture,
2884 0, //level
2885 GL_TRUE, //layered
2886 0, //layer
2887 GL_WRITE_ONLY, GL_R8UI);
2888 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2889 gl.uniform1i(1, 1 /* image_unit */);
2890 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2891
2892 // Pass input sampler/image to shader
2893 if (f.name != "sparseImageLoadARB")
2894 {
2895 gl.activeTexture(GL_TEXTURE0);
2896 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
2897 gl.bindTexture(target, texture);
2898 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
2899 gl.uniform1i(2, 0 /* sampler_unit */);
2900 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2901 }
2902 else
2903 {
2904 gl.bindImageTexture(0, //unit
2905 texture,
2906 level, //level
2907 GL_FALSE, //layered
2908 0, //layer
2909 GL_READ_ONLY, format);
2910 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2911 gl.uniform1i(2, 0 /* image_unit */);
2912 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2913 }
2914
2915 // Pass committed region width to shader
2916 gl.uniform1i(3, widthCommitted /* committed region width */);
2917 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2918 gl.dispatchCompute(width, height, depth);
2919 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2920 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2921 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2922
2923 Texture::Bind(gl, verifyTexture, verifyTarget);
2924 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
2925 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
2926
2927 //Verify only committed region
2928 for (GLint z = 0; z < depth; ++z)
2929 for (GLint y = 0; y < height; ++y)
2930 for (GLint x = 0; x < width; ++x)
2931 {
2932 GLubyte* dataRegion = exp_data + x + y * width + z * width * height;
2933 GLubyte* outDataRegion = out_data + x + y * width + z * width * height;
2934 if (dataRegion[0] != outDataRegion[0])
2935 result = false;
2936 }
2937 }
2938 else
2939 {
2940 mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format
2941 << ", shaderInfoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2942 << ", programInfoLog: " << program.getProgramInfo().infoLog << ", shaderSource: " << shader.c_str()
2943 << " - ";
2944
2945 result = false;
2946 }
2947 }
2948
2949 Texture::Delete(gl, verifyTexture);
2950
2951 return result;
2952 }
2953
2954 /** Constructor.
2955 *
2956 * @param context Rendering context.
2957 */
SparseTexture2Tests(deqp::Context & context)2958 SparseTexture2Tests::SparseTexture2Tests(deqp::Context& context)
2959 : TestCaseGroup(context, "sparse_texture2_tests", "Verify conformance of CTS_ARB_sparse_texture2 implementation")
2960 {
2961 }
2962
2963 /** Initializes the test group contents. */
init()2964 void SparseTexture2Tests::init()
2965 {
2966 addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture2"));
2967 addChild(new StandardPageSizesTestCase(m_context));
2968 addChild(new SparseTexture2AllocationTestCase(m_context));
2969 addChild(new SparseTexture2CommitmentTestCase(m_context));
2970 addChild(new UncommittedRegionsAccessTestCase(m_context));
2971 addChild(new SparseTexture2LookupTestCase(m_context));
2972 }
2973
2974 } /* gl4cts namespace */
2975