1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2017 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 es2cTexture3DTests.cpp
21 * \brief GL_OES_texture_3D tests definition.
22 */ /*-------------------------------------------------------------------*/
23
24 #include "es2cTexture3DTests.hpp"
25 #include "deDefs.hpp"
26 #include "deInt32.h"
27 #include "deRandom.hpp"
28 #include "deString.h"
29 #include "deStringUtil.hpp"
30 #include "deUniquePtr.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDrawUtil.hpp"
33 #include "gluPixelTransfer.hpp"
34 #include "gluShaderProgram.hpp"
35 #include "gluTexture.hpp"
36 #include "gluTextureTestUtil.hpp"
37 #include "gluTextureUtil.hpp"
38 #include "glwEnums.hpp"
39 #include "glwFunctions.hpp"
40 #include "tcuImageCompare.hpp"
41 #include "tcuPixelFormat.hpp"
42 #include "tcuRenderTarget.hpp"
43 #include "tcuStringTemplate.hpp"
44 #include "tcuTexLookupVerifier.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuVectorUtil.hpp"
47
48 #include <map>
49
50 using namespace glw;
51 using namespace glu::TextureTestUtil;
52
53 namespace es2cts
54 {
55
56 enum
57 {
58 VIEWPORT_WIDTH = 64,
59 VIEWPORT_HEIGHT = 64,
60 };
61
62 typedef std::pair<int, const char *> CompressedFormatName;
63 static CompressedFormatName compressedFormatNames[] = {
64 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8, "etc1_rgb8_oes"),
65 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA, "rgba_astc_4x4_khr"),
66 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA, "rgba_astc_5x4_khr"),
67 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA, "rgba_astc_5x5_khr"),
68 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA, "rgba_astc_6x5_khr"),
69 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA, "rgba_astc_6x6_khr"),
70 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA, "rgba_astc_8x5_khr"),
71 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA, "rgba_astc_8x6_khr"),
72 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA, "rgba_astc_8x8_khr"),
73 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA, "rgba_astc_10x5_khr"),
74 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA, "rgba_astc_10x6_khr"),
75 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA, "rgba_astc_10x8_khr"),
76 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA, "rgba_astc_10x10_khr"),
77 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA, "rgba_astc_12x10_khr"),
78 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA, "rgba_astc_12x12_khr"),
79 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8, "srgb8_alpha8_astc_4x4_khr"),
80 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8, "srgb8_alpha8_astc_5x4_khr"),
81 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8, "srgb8_alpha8_astc_5x5_khr"),
82 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8, "srgb8_alpha8_astc_6x5_khr"),
83 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8, "srgb8_alpha8_astc_6x6_khr"),
84 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8, "srgb8_alpha8_astc_8x5_khr"),
85 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8, "srgb8_alpha8_astc_8x6_khr"),
86 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8, "srgb8_alpha8_astc_8x8_khr"),
87 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8, "sgb8_alpha8_astc_10x5_khr"),
88 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8, "srgb8_alpha8_astc_10x6_khr"),
89 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8, "srgb8_alpha8_astc_10x8_khr"),
90 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8, "srgb8_alpha8_astc_10x10_khr"),
91 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8, "srgb8_alpha8_astc_12x10_khr"),
92 CompressedFormatName(tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8, "srgb8_alpha8_astc_12x12_khr")};
93
getCompressedFormatName(tcu::CompressedTexFormat format)94 const char *getCompressedFormatName(tcu::CompressedTexFormat format)
95 {
96 static std::map<int, const char *> formatMap(compressedFormatNames,
97 compressedFormatNames + DE_LENGTH_OF_ARRAY(compressedFormatNames));
98 return formatMap.at(format);
99 }
100
101 class Texture3DBase : public deqp::TestCase
102 {
103 public:
104 Texture3DBase(deqp::Context &context, const char *name, const char *description);
105 virtual ~Texture3DBase(void);
106
107 bool isFeatureSupported() const;
108 void getSupportedCompressedFormats(std::set<int> &validFormats) const;
109 int calculateDataSize(uint32_t formats, int width, int height, int depth) const;
110
111 template <typename TextureType>
112 void verifyTestResult(const float *texCoords, const tcu::Surface &rendered, const TextureType &reference,
113 const ReferenceParams &refParams, bool isNearestOnly) const;
114
115 void uploadTexture3D(const glu::Texture3D &texture) const;
116
117 void renderQuad(glu::TextureTestUtil::TextureType textureType, const float *texCoords) const;
118
119 void verifyError(GLenum expectedError, const char *missmatchMessage) const;
120 void verifyError(GLenum expectedError1, GLenum expectedError2, const char *missmatchMessage) const;
121
122 // New methods wrappers.
123 void callTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
124 GLint border, GLenum format, GLenum type, const void *pixels) const;
125
126 void callTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width,
127 GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) const;
128
129 void callCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x,
130 GLint y, GLsizei width, GLsizei height) const;
131
132 void callCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
133 GLsizei depth, GLint border, GLsizei imageSize, const void *data) const;
134
135 void callCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
136 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize,
137 const void *data) const;
138
139 void callFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level,
140 GLint zoffset) const;
141 };
142
Texture3DBase(deqp::Context & context,const char * name,const char * description)143 Texture3DBase::Texture3DBase(deqp::Context &context, const char *name, const char *description)
144 : deqp::TestCase(context, name, description)
145 {
146 }
147
~Texture3DBase(void)148 Texture3DBase::~Texture3DBase(void)
149 {
150 }
151
isFeatureSupported() const152 bool Texture3DBase::isFeatureSupported() const
153 {
154 if (!m_context.getContextInfo().isExtensionSupported("GL_OES_texture_3D") &&
155 !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 0)) &&
156 !glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(3, 0)))
157 {
158 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_OES_texture_3D");
159 return false;
160 }
161 return true;
162 }
163
getSupportedCompressedFormats(std::set<int> & formatsSet) const164 void Texture3DBase::getSupportedCompressedFormats(std::set<int> &formatsSet) const
165 {
166 const glu::ContextInfo &contextInfo = m_context.getContextInfo();
167
168 formatsSet.clear();
169 for (int formatNdx = 0; formatNdx < tcu::COMPRESSEDTEXFORMAT_LAST; formatNdx++)
170 {
171 // ETC2/EAC/BC (also known as DXT) texture compression algorithm
172 // supports only two-dimensional images
173 tcu::CompressedTexFormat format = static_cast<tcu::CompressedTexFormat>(formatNdx);
174 if (tcu::isEtcFormat(format) || tcu::isBcFormat(format))
175 continue;
176
177 // AHB formats are not supported
178 if (tcu::isAhbRawFormat(format))
179 continue;
180
181 int glFormat = glu::getGLFormat(format);
182 if (contextInfo.isCompressedTextureFormatSupported(glFormat))
183 formatsSet.insert(glFormat);
184 }
185 }
186
calculateDataSize(uint32_t formats,int width,int height,int depth) const187 int Texture3DBase::calculateDataSize(uint32_t formats, int width, int height, int depth) const
188 {
189 tcu::CompressedTexFormat format = glu::mapGLCompressedTexFormat(formats);
190 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(format);
191 const int blockSize = tcu::getBlockSize(format);
192 return deDivRoundUp32(width, blockPixelSize.x()) * deDivRoundUp32(height, blockPixelSize.y()) *
193 deDivRoundUp32(depth, blockPixelSize.z()) * blockSize;
194 }
195
196 template <typename TextureType>
verifyTestResult(const float * texCoords,const tcu::Surface & rendered,const TextureType & reference,const ReferenceParams & refParams,bool isNearestOnly) const197 void Texture3DBase::verifyTestResult(const float *texCoords, const tcu::Surface &rendered, const TextureType &reference,
198 const ReferenceParams &refParams, bool isNearestOnly) const
199 {
200 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
201 const tcu::IVec4 refChannelBitDepth = tcu::getTextureFormatBitDepth(reference.getFormat());
202 const tcu::IVec4 colorBits = max(tcu::IVec4(de::min(pixelFormat.redBits, refChannelBitDepth[0]),
203 de::min(pixelFormat.greenBits, refChannelBitDepth[1]),
204 de::min(pixelFormat.blueBits, refChannelBitDepth[2]),
205 de::min(pixelFormat.alphaBits, refChannelBitDepth[3])) -
206 (isNearestOnly ? 1 : 2),
207 tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
208 tcu::LodPrecision lodPrecision(18, 6);
209 tcu::LookupPrecision lookupPrecision;
210 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
211 lookupPrecision.coordBits = tcu::IVec3(20, 20, 20);
212 lookupPrecision.uvwBits = tcu::IVec3(7, 7, 7);
213 lookupPrecision.colorMask = getCompareMask(pixelFormat);
214
215 if (verifyTextureResult(m_testCtx, rendered.getAccess(), reference, texCoords, refParams, lookupPrecision,
216 lodPrecision, pixelFormat))
217 {
218 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
219 return;
220 }
221
222 // Evaluate against lower precision requirements.
223 lodPrecision.lodBits = 4;
224 lookupPrecision.uvwBits = tcu::IVec3(4, 4, 4);
225
226 tcu::TestLog &log = m_testCtx.getLog();
227 log << tcu::TestLog::Message
228 << "Warning: Verification against high precision requirements failed, trying with lower requirements."
229 << tcu::TestLog::EndMessage;
230
231 if (verifyTextureResult(m_testCtx, rendered.getAccess(), reference, texCoords, refParams, lookupPrecision,
232 lodPrecision, pixelFormat))
233 {
234 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
235 return;
236 }
237
238 log << tcu::TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case."
239 << tcu::TestLog::EndMessage;
240 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
241 }
242
uploadTexture3D(const glu::Texture3D & texture) const243 void Texture3DBase::uploadTexture3D(const glu::Texture3D &texture) const
244 {
245 // note: this function is modified version of glu::Texture3D::upload()
246 // this was needed to support methods added by GL_OES_texture_3D extension
247
248 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
249 uint32_t textureName = texture.getGLTexture();
250 const tcu::Texture3D &referenceTexture = texture.getRefTexture();
251
252 TCU_CHECK(textureName);
253 gl.bindTexture(GL_TEXTURE_3D, textureName);
254
255 GLint pixelStorageMode = 1;
256 int pixelSize = referenceTexture.getFormat().getPixelSize();
257 if (deIsPowerOfTwo32(pixelSize))
258 pixelStorageMode = de::min(pixelSize, 8);
259
260 gl.pixelStorei(GL_UNPACK_ALIGNMENT, pixelStorageMode);
261 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
262
263 glu::TransferFormat transferFormat = glu::getTransferFormat(referenceTexture.getFormat());
264
265 for (int levelNdx = 0; levelNdx < referenceTexture.getNumLevels(); levelNdx++)
266 {
267 if (referenceTexture.isLevelEmpty(levelNdx))
268 continue; // Don't upload.
269
270 tcu::ConstPixelBufferAccess access = referenceTexture.getLevel(levelNdx);
271 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize() * access.getWidth());
272 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize() * access.getWidth() * access.getHeight());
273 callTexImage3D(GL_TEXTURE_3D, levelNdx, transferFormat.format, access.getWidth(), access.getHeight(),
274 access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType,
275 access.getDataPtr());
276 }
277
278 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
279 }
280
renderQuad(glu::TextureTestUtil::TextureType textureType,const float * texCoords) const281 void Texture3DBase::renderQuad(glu::TextureTestUtil::TextureType textureType, const float *texCoords) const
282 {
283 glu::RenderContext &renderContext = m_context.getRenderContext();
284 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(renderContext.getType());
285 const glw::Functions &gl = renderContext.getFunctions();
286
287 // Prepare data for rendering
288 static const uint16_t quadIndices[] = {0, 1, 2, 2, 1, 3};
289 static const float position[] = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
290
291 static const char *vsTemplate = "${VERSION}\n"
292 "attribute highp vec4 a_position;\n"
293 "attribute highp ${TEXCOORD_TYPE} a_texCoord;\n"
294 "varying highp ${TEXCOORD_TYPE} v_texCoord;\n"
295 "void main (void) {\n"
296 " gl_Position = a_position;\n"
297 " v_texCoord = a_texCoord;\n"
298 "}\n";
299 static const char *fsTemplate = "${VERSION}\n"
300 "${HEADER}\n"
301 "varying highp ${TEXCOORD_TYPE} v_texCoord;\n"
302 "uniform highp ${SAMPLER_TYPE} u_sampler;\n"
303 "void main (void) {\n"
304 " gl_FragColor = ${LOOKUP}(u_sampler, v_texCoord);\n"
305 "}\n";
306
307 int numComponents = 3;
308
309 std::map<std::string, std::string> specializationMap;
310 specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
311
312 if (textureType == TEXTURETYPE_3D)
313 {
314 specializationMap["HEADER"] = "#extension GL_OES_texture_3D : enable";
315 specializationMap["TEXCOORD_TYPE"] = "vec3";
316 specializationMap["SAMPLER_TYPE"] = "sampler3D";
317 specializationMap["LOOKUP"] = "texture3D";
318 }
319 else if (textureType == TEXTURETYPE_2D)
320 {
321 numComponents = 2;
322 specializationMap["HEADER"] = "";
323 specializationMap["TEXCOORD_TYPE"] = "vec2";
324 specializationMap["SAMPLER_TYPE"] = "sampler2D";
325 specializationMap["LOOKUP"] = "texture2D";
326 }
327 else
328 TCU_FAIL("Unsuported texture type.");
329
330 // Specialize shaders
331 std::string vs = tcu::StringTemplate(vsTemplate).specialize(specializationMap);
332 std::string fs = tcu::StringTemplate(fsTemplate).specialize(specializationMap);
333 glu::ProgramSources programSources(glu::makeVtxFragSources(vs, fs));
334
335 // Create program
336 glu::ShaderProgram testProgram(renderContext, programSources);
337 if (!testProgram.isOk())
338 {
339 m_testCtx.getLog() << testProgram;
340 TCU_FAIL("Compile failed");
341 }
342
343 // Set uniforms
344 uint32_t programId = testProgram.getProgram();
345 gl.useProgram(programId);
346 gl.uniform1i(gl.getUniformLocation(programId, "u_sampler"), 0);
347
348 // Define vertex attributes
349 const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, position),
350 glu::va::Float("a_texCoord", numComponents, 4, 0, texCoords)};
351
352 // Draw quad
353 glu::draw(m_context.getRenderContext(), programId, DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
354 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
355 }
356
verifyError(GLenum expectedError,const char * missmatchMessage) const357 void Texture3DBase::verifyError(GLenum expectedError, const char *missmatchMessage) const
358 {
359 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
360 GLenum currentError = gl.getError();
361 if (currentError == expectedError)
362 return;
363
364 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect error was reported");
365 m_testCtx.getLog() << tcu::TestLog::Message << glu::getErrorStr(static_cast<int>(expectedError))
366 << " was expected but got " << glu::getErrorStr(static_cast<int>(currentError)) << ". "
367 << missmatchMessage << tcu::TestLog::EndMessage;
368 }
369
verifyError(GLenum expectedError1,GLenum expectedError2,const char * missmatchMessage) const370 void Texture3DBase::verifyError(GLenum expectedError1, GLenum expectedError2, const char *missmatchMessage) const
371 {
372 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
373 GLenum currentError = gl.getError();
374 if ((currentError == expectedError1) || (currentError == expectedError2))
375 return;
376
377 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Incorrect error was reported");
378 m_testCtx.getLog() << tcu::TestLog::Message << glu::getErrorStr(static_cast<int>(expectedError1)) << " or "
379 << glu::getErrorStr(static_cast<int>(expectedError1)) << " was expected but got "
380 << glu::getErrorStr(static_cast<int>(currentError)) << ". " << missmatchMessage
381 << tcu::TestLog::EndMessage;
382 }
383
callTexImage3D(GLenum target,GLint level,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * pixels) const384 void Texture3DBase::callTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height,
385 GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) const
386 {
387 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
388 if (gl.texImage3DOES)
389 gl.texImage3DOES(target, level, internalFormat, width, height, depth, border, format, type, pixels);
390 else if (gl.texImage3D)
391 gl.texImage3D(target, level, static_cast<GLint>(internalFormat), width, height, depth, border, format, type,
392 pixels);
393 else
394 TCU_FAIL("glTexImage3D not supported");
395 }
396
callTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels) const397 void Texture3DBase::callTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
398 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
399 const void *pixels) const
400 {
401 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
402 if (gl.texSubImage3DOES)
403 gl.texSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
404 else if (gl.texSubImage3D)
405 gl.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
406 else
407 TCU_FAIL("glTexSubImage3D not supported");
408 }
409
callCopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height) const410 void Texture3DBase::callCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
411 GLint x, GLint y, GLsizei width, GLsizei height) const
412 {
413 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
414 if (gl.copyTexSubImage3DOES)
415 gl.copyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
416 else if (gl.copyTexSubImage3D)
417 gl.copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
418 else
419 TCU_FAIL("glCopyTexSubImage3D not supported");
420 }
421
callCompressedTexImage3D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const void * data) const422 void Texture3DBase::callCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width,
423 GLsizei height, GLsizei depth, GLint border, GLsizei imageSize,
424 const void *data) const
425 {
426 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
427 if (gl.compressedTexImage3DOES)
428 gl.compressedTexImage3DOES(target, level, internalformat, width, height, depth, border, imageSize, data);
429 else if (gl.compressedTexImage3D)
430 gl.compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
431 else
432 TCU_FAIL("gl.compressedTexImage3D not supported");
433 }
434
callCompressedTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const void * data) const435 void Texture3DBase::callCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
436 GLsizei width, GLsizei height, GLsizei depth, GLenum format,
437 GLsizei imageSize, const void *data) const
438 {
439 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
440 if (gl.compressedTexSubImage3DOES)
441 gl.compressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize,
442 data);
443 else if (gl.compressedTexSubImage3D)
444 gl.compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize,
445 data);
446 else
447 TCU_FAIL("gl.compressedTexSubImage3D not supported");
448 }
449
callFramebufferTexture3D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset) const450 void Texture3DBase::callFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
451 GLint level, GLint zoffset) const
452 {
453 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
454 if (gl.framebufferTexture3DOES)
455 gl.framebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
456 else if (gl.framebufferTexture3D)
457 gl.framebufferTexture3D(target, attachment, textarget, texture, level, zoffset);
458 else
459 TCU_FAIL("glFramebufferTexture3D not supported");
460 }
461
462 struct FilteringData
463 {
464 GLint minFilter;
465 GLint magFilter;
466 GLint wrapS;
467 GLint wrapT;
468 GLint wrapR;
469
470 uint32_t internalFormat;
471 int width;
472 int height;
473 int depth;
474 };
475
476 class Texture3DFilteringCase : public Texture3DBase
477 {
478 public:
479 Texture3DFilteringCase(deqp::Context &context, const char *name, const char *desc, const FilteringData &data);
480 ~Texture3DFilteringCase(void);
481
482 void init(void);
483 void deinit(void);
484 IterateResult iterate(void);
485
486 private:
487 struct FilterCase
488 {
489 const glu::Texture3D *texture;
490 tcu::Vec3 lod;
491 tcu::Vec3 offset;
492
FilterCasees2cts::Texture3DFilteringCase::FilterCase493 FilterCase(void) : texture(DE_NULL)
494 {
495 }
496
FilterCasees2cts::Texture3DFilteringCase::FilterCase497 FilterCase(const glu::Texture3D *tex_, const tcu::Vec3 &lod_, const tcu::Vec3 &offset_)
498 : texture(tex_)
499 , lod(lod_)
500 , offset(offset_)
501 {
502 }
503 };
504
505 private:
506 Texture3DFilteringCase(const Texture3DFilteringCase &other);
507 Texture3DFilteringCase &operator=(const Texture3DFilteringCase &other);
508
509 const FilteringData m_filteringData;
510
511 glu::Texture3D *m_gradientTex;
512 glu::Texture3D *m_gridTex;
513
514 std::vector<FilterCase> m_cases;
515 int m_caseNdx;
516 };
517
Texture3DFilteringCase(deqp::Context & context,const char * name,const char * desc,const FilteringData & data)518 Texture3DFilteringCase::Texture3DFilteringCase(deqp::Context &context, const char *name, const char *desc,
519 const FilteringData &data)
520 : Texture3DBase(context, name, desc)
521 , m_filteringData(data)
522 , m_gradientTex(DE_NULL)
523 , m_gridTex(DE_NULL)
524 , m_caseNdx(0)
525 {
526 }
527
~Texture3DFilteringCase(void)528 Texture3DFilteringCase::~Texture3DFilteringCase(void)
529 {
530 Texture3DFilteringCase::deinit();
531 }
532
init(void)533 void Texture3DFilteringCase::init(void)
534 {
535 if (!isFeatureSupported())
536 return;
537
538 const uint32_t internalFormat = m_filteringData.internalFormat;
539 const int width = m_filteringData.width;
540 const int height = m_filteringData.height;
541 const int depth = m_filteringData.depth;
542
543 const tcu::TextureFormat texFmt = glu::mapGLInternalFormat(internalFormat);
544 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
545 const tcu::Vec4 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
546 const tcu::Vec4 cBias = fmtInfo.valueMin;
547 const int numLevels = deLog2Floor32(de::max(de::max(width, height), depth)) + 1;
548
549 // Create textures.
550 m_gradientTex = new glu::Texture3D(m_context.getRenderContext(), internalFormat, width, height, depth);
551 m_gridTex = new glu::Texture3D(m_context.getRenderContext(), internalFormat, width, height, depth);
552
553 // Fill first gradient texture.
554 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
555 {
556 tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f) * cScale + cBias;
557 tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) * cScale + cBias;
558
559 m_gradientTex->getRefTexture().allocLevel(levelNdx);
560 tcu::fillWithComponentGradients(m_gradientTex->getRefTexture().getLevel(levelNdx), gMin, gMax);
561 }
562
563 // Fill second with grid texture.
564 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
565 {
566 uint32_t step = 0x00ffffff / numLevels;
567 uint32_t rgb = step * levelNdx;
568 uint32_t colorA = 0xff000000 | rgb;
569 uint32_t colorB = 0xff000000 | ~rgb;
570
571 m_gridTex->getRefTexture().allocLevel(levelNdx);
572 tcu::fillWithGrid(m_gridTex->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec() * cScale + cBias,
573 tcu::RGBA(colorB).toVec() * cScale + cBias);
574 }
575
576 // Upload.
577 uploadTexture3D(*m_gradientTex);
578 uploadTexture3D(*m_gridTex);
579
580 // Test cases
581 m_cases.push_back(FilterCase(m_gradientTex, tcu::Vec3(1.5f, 2.8f, 1.0f), tcu::Vec3(-1.0f, -2.7f, -2.275f)));
582 m_cases.push_back(FilterCase(m_gradientTex, tcu::Vec3(-2.0f, -1.5f, -1.8f), tcu::Vec3(-0.1f, 0.9f, -0.25f)));
583 m_cases.push_back(FilterCase(m_gridTex, tcu::Vec3(0.2f, 0.175f, 0.3f), tcu::Vec3(-2.0f, -3.7f, -1.825f)));
584 m_cases.push_back(FilterCase(m_gridTex, tcu::Vec3(-0.8f, -2.3f, -2.5f), tcu::Vec3(0.2f, -0.1f, 1.325f)));
585
586 m_caseNdx = 0;
587 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
588 }
589
deinit(void)590 void Texture3DFilteringCase::deinit(void)
591 {
592 delete m_gradientTex;
593 delete m_gridTex;
594
595 m_gradientTex = DE_NULL;
596 m_gridTex = DE_NULL;
597
598 m_cases.clear();
599 }
600
iterate(void)601 Texture3DFilteringCase::IterateResult Texture3DFilteringCase::iterate(void)
602 {
603 if (!isFeatureSupported())
604 return STOP;
605
606 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
607 const FilterCase &curCase = m_cases[m_caseNdx];
608 const tcu::TextureFormat texFmt = curCase.texture->getRefTexture().getFormat();
609 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
610 const tcu::ScopedLogSection section(m_testCtx.getLog(), std::string("Test") + de::toString(m_caseNdx),
611 std::string("Test ") + de::toString(m_caseNdx));
612 tcu::TestLog &log = m_testCtx.getLog();
613 ReferenceParams refParams(TEXTURETYPE_3D);
614 tcu::Surface rendered(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
615 tcu::Vec3 texCoord[4];
616
617 // Setup params for reference.
618 refParams.sampler = glu::mapGLSampler(m_filteringData.wrapS, m_filteringData.wrapT, m_filteringData.wrapR,
619 m_filteringData.minFilter, m_filteringData.magFilter);
620 refParams.samplerType = getSamplerType(texFmt);
621 refParams.lodMode = LODMODE_EXACT;
622 refParams.colorBias = fmtInfo.lookupBias;
623 refParams.colorScale = fmtInfo.lookupScale;
624
625 // Compute texture coordinates.
626 log << tcu::TestLog::Message << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset
627 << tcu::TestLog::EndMessage;
628
629 {
630 const float lodX = curCase.lod.x();
631 const float lodY = curCase.lod.y();
632 const float lodZ = curCase.lod.z();
633 const float oX = curCase.offset.x();
634 const float oY = curCase.offset.y();
635 const float oZ = curCase.offset.z();
636 const float sX = deFloatExp2(lodX) * float(VIEWPORT_WIDTH) / float(m_gradientTex->getRefTexture().getWidth());
637 const float sY = deFloatExp2(lodY) * float(VIEWPORT_HEIGHT) / float(m_gradientTex->getRefTexture().getHeight());
638 const float sZ = deFloatExp2(lodZ) * float(VIEWPORT_WIDTH) / float(m_gradientTex->getRefTexture().getDepth());
639
640 texCoord[0] = tcu::Vec3(oX, oY, oZ);
641 texCoord[1] = tcu::Vec3(oX, oY + sY, oZ + sZ * 0.5f);
642 texCoord[2] = tcu::Vec3(oX + sX, oY, oZ + sZ * 0.5f);
643 texCoord[3] = tcu::Vec3(oX + sX, oY + sY, oZ + sZ);
644 }
645
646 gl.bindTexture(GL_TEXTURE_3D, curCase.texture->getGLTexture());
647 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, m_filteringData.minFilter);
648 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, m_filteringData.magFilter);
649 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, m_filteringData.wrapS);
650 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, m_filteringData.wrapT);
651 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, m_filteringData.wrapR);
652
653 // Verify bound 3D texture.
654 GLint resultName;
655 gl.getIntegerv(GL_TEXTURE_BINDING_3D, &resultName);
656 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
657 if (curCase.texture->getGLTexture() == static_cast<uint32_t>(resultName))
658 {
659 // Render.
660 gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
661 renderQuad(TEXTURETYPE_3D, texCoord->getPtr());
662 glu::readPixels(m_context.getRenderContext(), 0, 0, rendered.getAccess());
663
664 // Compare rendered image to reference.
665 const bool isNearestOnly =
666 (m_filteringData.minFilter == GL_NEAREST) && (m_filteringData.magFilter == GL_NEAREST);
667 verifyTestResult(texCoord[0].getPtr(), rendered, curCase.texture->getRefTexture(), refParams, isNearestOnly);
668 }
669 else
670 {
671 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid texture name");
672 }
673
674 ++m_caseNdx;
675 return (m_caseNdx < static_cast<int>(m_cases.size())) ? CONTINUE : STOP;
676 }
677
678 class TexSubImage3DCase : public Texture3DBase
679 {
680 public:
681 TexSubImage3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t internalFormat, int width,
682 int height, int depth);
683
684 IterateResult iterate(void);
685
686 private:
687 uint32_t m_internalFormat;
688 int m_width;
689 int m_height;
690 int m_depth;
691 int m_numLevels;
692 };
693
TexSubImage3DCase(deqp::Context & context,const char * name,const char * desc,uint32_t internalFormat,int width,int height,int depth)694 TexSubImage3DCase::TexSubImage3DCase(deqp::Context &context, const char *name, const char *desc,
695 uint32_t internalFormat, int width, int height, int depth)
696 : Texture3DBase(context, name, desc)
697 , m_internalFormat(internalFormat)
698 , m_width(width)
699 , m_height(height)
700 , m_depth(depth)
701 , m_numLevels(static_cast<int>(deLog2Floor32(de::max(width, de::max(height, depth))) + 1))
702 {
703 }
704
iterate(void)705 TexSubImage3DCase::IterateResult TexSubImage3DCase::iterate(void)
706 {
707 if (!isFeatureSupported())
708 return STOP;
709
710 glu::RenderContext &renderCtx = m_context.getRenderContext();
711 const glw::Functions &gl = renderCtx.getFunctions();
712
713 tcu::Vec4 firstColor(0.0f, 1.0f, 0.0f, 1.0f);
714 tcu::Vec4 secondColor(1.0f, 0.0f, 1.0f, 1.0f);
715 glu::Texture3D texture(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
716 const tcu::TextureFormat textureFormat = texture.getRefTexture().getFormat();
717 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
718
719 // Fill texture.
720 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
721 {
722 texture.getRefTexture().allocLevel(levelNdx);
723 const tcu::PixelBufferAccess &pba = texture.getRefTexture().getLevel(levelNdx);
724 tcu::fillWithComponentGradients(pba, firstColor, secondColor);
725 }
726
727 // Upload texture
728 uploadTexture3D(texture);
729
730 gl.bindTexture(GL_TEXTURE_3D, texture.getGLTexture());
731 GLU_EXPECT_NO_ERROR(gl.getError(), "gl.bindTexture");
732 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
733 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri for GL_TEXTURE_WRAP_R");
734 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
735 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri for GL_TEXTURE_WRAP_T");
736 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
737 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri for GL_TEXTURE_WRAP_R");
738 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
739 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri for GL_TEXTURE_MIN_FILTER");
740 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
741 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri for GL_TEXTURE_MAG_FILTER");
742
743 // Re-specify parts of each level in uploaded texture and in reference texture
744 tcu::TextureLevel data(textureFormat);
745 for (int levelNdx = 0; levelNdx < m_numLevels - 2; levelNdx++)
746 {
747 int scale = levelNdx + 1;
748 int w = de::max(1, m_width >> scale);
749 int h = de::max(1, m_height >> scale);
750 int d = de::max(1, m_depth >> levelNdx);
751
752 data.setSize(w, h, d);
753 tcu::clear(data.getAccess(), secondColor);
754
755 glu::TransferFormat transferFormat = glu::getTransferFormat(textureFormat);
756 callTexSubImage3D(GL_TEXTURE_3D, levelNdx, w, h, 0, w, h, d, transferFormat.format, transferFormat.dataType,
757 data.getAccess().getDataPtr());
758 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D");
759
760 const tcu::PixelBufferAccess &pba = texture.getRefTexture().getLevel(levelNdx);
761 tcu::clear(getSubregion(pba, w, h, 0, w, h, d), secondColor);
762 }
763
764 // Setup params for reference.
765 ReferenceParams refParams(TEXTURETYPE_3D);
766 refParams.sampler = glu::mapGLSampler(GL_REPEAT, GL_REPEAT, GL_REPEAT, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST);
767 refParams.samplerType = getSamplerType(textureFormat);
768 refParams.lodMode = LODMODE_EXACT;
769 refParams.colorBias = formatInfo.lookupBias;
770 refParams.colorScale = formatInfo.lookupScale;
771
772 tcu::Vec3 texCoord[4] = {tcu::Vec3(0.0f, 0.0f, 0.5f), tcu::Vec3(0.0f, 1.0f, 0.5f), tcu::Vec3(1.0f, 0.0f, 0.5f),
773 tcu::Vec3(1.0f, 1.0f, 0.5f)};
774
775 // Render.
776 gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
777 renderQuad(TEXTURETYPE_3D, texCoord[0].getPtr());
778
779 tcu::Surface rendered(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
780 glu::readPixels(m_context.getRenderContext(), 0, 0, rendered.getAccess());
781
782 // Compare rendered image to reference.
783 verifyTestResult(texCoord[0].getPtr(), rendered, texture.getRefTexture(), refParams, false);
784 return STOP;
785 }
786
787 class CopyTexSubImage3DCase : public Texture3DBase
788 {
789 public:
790 CopyTexSubImage3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t format, uint32_t type,
791 int width, int height, int depth);
792
793 IterateResult iterate(void);
794
795 private:
796 uint32_t m_format;
797 uint32_t m_type;
798 int m_width;
799 int m_height;
800 int m_depth;
801 int m_numLevels;
802 };
803
CopyTexSubImage3DCase(deqp::Context & context,const char * name,const char * desc,uint32_t format,uint32_t type,int width,int height,int depth)804 CopyTexSubImage3DCase::CopyTexSubImage3DCase(deqp::Context &context, const char *name, const char *desc,
805 uint32_t format, uint32_t type, int width, int height, int depth)
806 : Texture3DBase(context, name, desc)
807 , m_format(format)
808 , m_type(type)
809 , m_width(width)
810 , m_height(height)
811 , m_depth(depth)
812 , m_numLevels(static_cast<int>(deLog2Floor32(de::max(width, de::max(height, depth))) + 1))
813 {
814 }
815
iterate(void)816 CopyTexSubImage3DCase::IterateResult CopyTexSubImage3DCase::iterate(void)
817 {
818 if (!isFeatureSupported())
819 return STOP;
820
821 glu::RenderContext &renderCtx = m_context.getRenderContext();
822 const glw::Functions &gl = renderCtx.getFunctions();
823
824 ReferenceParams refParams(TEXTURETYPE_3D);
825 tcu::Surface rendered(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
826 tcu::Vec4 firstColor(0.0f, 1.0f, 0.0f, 1.0f);
827 tcu::Vec4 secondColor(1.0f, 0.0f, 1.0f, 1.0f);
828 glu::Texture3D texture(m_context.getRenderContext(), m_format, m_type, m_width, m_height, m_depth);
829 const tcu::TextureFormat textureFormat = texture.getRefTexture().getFormat();
830 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
831
832 glw::GLuint fbo = 0;
833 gl.genFramebuffers(1, &fbo);
834 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
835 glw::GLuint new_dst_to = 0;
836 gl.genTextures(1, &new_dst_to);
837 gl.bindTexture(GL_TEXTURE_2D, new_dst_to);
838
839 /* The longest edge of texture(32*64*8) is 64, so we create a texture with 64*64 dimension. */
840 gl.texImage2D(GL_TEXTURE_2D, 0, m_format, 64, 64, 0, m_format, m_type, NULL);
841 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not setup texture object for draw framebuffer color attachment.");
842
843 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, new_dst_to, 0);
844
845 GLU_EXPECT_NO_ERROR(gl.getError(), "Could not attach texture object to draw framebuffer color attachment.");
846 // Fill texture.
847 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
848 {
849 texture.getRefTexture().allocLevel(levelNdx);
850 const tcu::PixelBufferAccess &pba = texture.getRefTexture().getLevel(levelNdx);
851 tcu::fillWithComponentGradients(pba, firstColor, secondColor);
852 }
853
854 // Upload texture.
855 uploadTexture3D(texture);
856
857 gl.clearColor(secondColor[0], secondColor[1], secondColor[2], secondColor[3]);
858 gl.clear(GL_COLOR_BUFFER_BIT);
859 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
860
861 gl.bindTexture(GL_TEXTURE_3D, texture.getGLTexture());
862 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
863 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
864 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
865 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
866 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
867
868 // Re-specify parts of each level in uploaded texture and in reference texture
869 tcu::TextureLevel data(textureFormat);
870 for (int levelNdx = 0; levelNdx < m_numLevels - 2; levelNdx++)
871 {
872 int scale = levelNdx + 1;
873 int w = de::max(1, m_width >> scale);
874 int h = de::max(1, m_height >> scale);
875 int d = de::max(1, m_depth >> levelNdx);
876
877 data.setSize(w, h, d);
878 tcu::clear(data.getAccess(), secondColor);
879
880 for (int depthNdx = 0; depthNdx < d; depthNdx++)
881 {
882 callCopyTexSubImage3D(GL_TEXTURE_3D, levelNdx, w, h, depthNdx, 0, 0, w, h);
883 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyTexSubImage3D");
884 }
885 const tcu::PixelBufferAccess &pba = texture.getRefTexture().getLevel(levelNdx);
886 tcu::clear(getSubregion(pba, w, h, 0, w, h, d), secondColor);
887 }
888
889 // Setup params for reference.
890 refParams.sampler = glu::mapGLSampler(GL_REPEAT, GL_REPEAT, GL_REPEAT, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST);
891 refParams.samplerType = getSamplerType(textureFormat);
892 refParams.lodMode = LODMODE_EXACT;
893 refParams.colorBias = formatInfo.lookupBias;
894 refParams.colorScale = formatInfo.lookupScale;
895
896 tcu::Vec3 texCoord[4] = {tcu::Vec3(0.0f, 0.0f, 0.5f), tcu::Vec3(0.0f, 1.0f, 0.5f), tcu::Vec3(1.0f, 0.0f, 0.5f),
897 tcu::Vec3(1.0f, 1.0f, 0.5f)};
898
899 // Render.
900 gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
901 renderQuad(TEXTURETYPE_3D, texCoord[0].getPtr());
902 glu::readPixels(m_context.getRenderContext(), 0, 0, rendered.getAccess());
903
904 // Compare rendered image to reference.
905 verifyTestResult(texCoord[0].getPtr(), rendered, texture.getRefTexture(), refParams, false);
906 gl.deleteTextures(1, &new_dst_to);
907 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
908 gl.deleteFramebuffers(1, &fbo);
909 return STOP;
910 }
911
912 class FramebufferTexture3DCase : public Texture3DBase
913 {
914 public:
915 FramebufferTexture3DCase(deqp::Context &context, const char *name, const char *desc, uint32_t format, uint32_t type,
916 int width, int height, int depth);
917
918 IterateResult iterate(void);
919
920 private:
921 uint32_t m_format;
922 uint32_t m_type;
923 int m_width;
924 int m_height;
925 int m_depth;
926 int m_numLevels;
927 };
928
FramebufferTexture3DCase(deqp::Context & context,const char * name,const char * desc,uint32_t format,uint32_t type,int width,int height,int depth)929 FramebufferTexture3DCase::FramebufferTexture3DCase(deqp::Context &context, const char *name, const char *desc,
930 uint32_t format, uint32_t type, int width, int height, int depth)
931 : Texture3DBase(context, name, desc)
932 , m_format(format)
933 , m_type(type)
934 , m_width(width)
935 , m_height(height)
936 , m_depth(depth)
937 , m_numLevels(static_cast<int>(deLog2Floor32(de::max(width, de::max(height, depth))) + 1))
938 {
939 }
940
iterate(void)941 FramebufferTexture3DCase::IterateResult FramebufferTexture3DCase::iterate(void)
942 {
943 if (!isFeatureSupported())
944 return STOP;
945
946 glu::RenderContext &renderCtx = m_context.getRenderContext();
947 const glw::Functions &gl = renderCtx.getFunctions();
948
949 tcu::Vec4 firstColor(0.0f, 1.0f, 0.0f, 1.0f);
950 tcu::Vec4 secondColor(1.0f, 0.0f, 1.0f, 1.0f);
951 glu::Texture3D texture3D(m_context.getRenderContext(), m_format, m_type, m_width, m_height, m_depth);
952 glu::Texture2D texture2D(m_context.getRenderContext(), m_format, m_type, m_width, m_height);
953
954 // Fill textures.
955 texture3D.getRefTexture().allocLevel(0);
956 const tcu::PixelBufferAccess &pba3D = texture3D.getRefTexture().getLevel(0);
957 tcu::clear(pba3D, secondColor);
958
959 for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
960 {
961 texture2D.getRefTexture().allocLevel(levelNdx);
962 const tcu::PixelBufferAccess &pba2D = texture2D.getRefTexture().getLevel(levelNdx);
963 tcu::fillWithGrid(pba2D, 4, firstColor, secondColor);
964 }
965
966 // Upload textures.
967 uploadTexture3D(texture3D);
968 texture2D.upload();
969
970 gl.bindTexture(GL_TEXTURE_3D, texture3D.getGLTexture());
971 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
972 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
973 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
974 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
975 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
976
977 // Create framebuffer.
978 glw::GLuint fbo = 0;
979 gl.genFramebuffers(1, &fbo);
980 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
981 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
982 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers");
983 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, texture3D.getGLTexture(), 0, 1);
984 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture3D");
985
986 uint32_t status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
987 if (status != GL_FRAMEBUFFER_COMPLETE)
988 TCU_FAIL("Framebuffer is not complete");
989
990 gl.bindTexture(GL_TEXTURE_2D, texture2D.getGLTexture());
991 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
992 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
993 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
994 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
995
996 const tcu::TextureFormat textureFormat = texture2D.getRefTexture().getFormat();
997 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(textureFormat);
998
999 tcu::Vec2 texCoord[4] = {tcu::Vec2(0.0f, 0.0f), tcu::Vec2(0.0f, 1.0f), tcu::Vec2(1.0f, 0.0f),
1000 tcu::Vec2(1.0f, 1.0f)};
1001
1002 // Render to fbo.
1003 gl.viewport(0, 0, m_width, m_height);
1004 renderQuad(TEXTURETYPE_2D, texCoord[0].getPtr());
1005
1006 // Setup params for reference.
1007 ReferenceParams refParams(TEXTURETYPE_2D);
1008 refParams.sampler = glu::mapGLSampler(GL_REPEAT, GL_REPEAT, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST);
1009 refParams.samplerType = getSamplerType(textureFormat);
1010 refParams.lodMode = LODMODE_EXACT;
1011 refParams.colorBias = formatInfo.lookupBias;
1012 refParams.colorScale = formatInfo.lookupScale;
1013
1014 // Compare image rendered to selected layer of 3d texture to reference.
1015 tcu::Surface rendered(m_width, m_height);
1016 glu::readPixels(m_context.getRenderContext(), 0, 0, rendered.getAccess());
1017 verifyTestResult(texCoord[0].getPtr(), rendered, texture2D.getRefTexture(), refParams, false);
1018
1019 // Cleanup.
1020 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1021 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1022 gl.deleteFramebuffers(1, &fbo);
1023 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1024
1025 return STOP;
1026 }
1027
checkFormatSupport(const glu::ContextInfo & info,uint32_t format)1028 void checkFormatSupport(const glu::ContextInfo &info, uint32_t format)
1029 {
1030 if (glu::isCompressedFormat(format))
1031 {
1032 if (isAstcFormat(glu::mapGLCompressedTexFormat(format)))
1033 {
1034 if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_hdr") &&
1035 !info.isExtensionSupported("GL_OES_texture_compression_astc"))
1036 {
1037 TCU_THROW(NotSupportedError, "requires HDR astc support.");
1038 }
1039 }
1040 }
1041 }
1042
1043 class CompressedTexture3DCase : public Texture3DBase
1044 {
1045 public:
1046 CompressedTexture3DCase(deqp::Context &context, const char *name, uint32_t format);
1047
1048 IterateResult iterate(void);
1049
1050 private:
1051 int m_compressedFormat;
1052 };
1053
CompressedTexture3DCase(deqp::Context & context,const char * name,uint32_t format)1054 CompressedTexture3DCase::CompressedTexture3DCase(deqp::Context &context, const char *name, uint32_t format)
1055 : Texture3DBase(context, name, "")
1056 , m_compressedFormat(static_cast<int>(format))
1057 {
1058 }
1059
iterate(void)1060 CompressedTexture3DCase::IterateResult CompressedTexture3DCase::iterate(void)
1061 {
1062 if (!isFeatureSupported())
1063 return STOP;
1064
1065 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1066 const glu::ContextInfo &contextInfo = m_context.getContextInfo();
1067 tcu::CompressedTexFormat format = glu::mapGLCompressedTexFormat(m_compressedFormat);
1068
1069 if (!contextInfo.isCompressedTextureFormatSupported(m_compressedFormat))
1070 {
1071 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Compressed format not supported by implementation");
1072 return STOP;
1073 }
1074
1075 checkFormatSupport(contextInfo, m_compressedFormat);
1076
1077 const int32_t width = 64;
1078 const int32_t height = 64;
1079 const int32_t depth = 4;
1080 const int32_t levelsCount = 4;
1081
1082 GLuint textureName;
1083 gl.genTextures(1, &textureName);
1084 GLU_EXPECT_NO_ERROR(gl.getError(), "gl.genTextures");
1085 gl.bindTexture(GL_TEXTURE_3D, textureName);
1086 GLU_EXPECT_NO_ERROR(gl.getError(), "gl.bindTexture");
1087
1088 // Create 3D texture with random data.
1089 for (int32_t levelIndex = 0; levelIndex < levelsCount; ++levelIndex)
1090 {
1091 int32_t levelWidth = de::max(width >> levelIndex, 1);
1092 int32_t levelHeight = de::max(height >> levelIndex, 1);
1093 int32_t levelDepth = de::max(depth >> levelIndex, 1);
1094
1095 tcu::CompressedTexture level(format, levelWidth, levelHeight, levelDepth);
1096 const int dataSize = level.getDataSize();
1097 uint8_t *const data = static_cast<uint8_t *>(level.getData());
1098 de::Random rnd(deStringHash(getName()) + levelIndex);
1099
1100 for (int i = 0; i < dataSize; i++)
1101 data[i] = rnd.getUint32() & 0xff;
1102
1103 callCompressedTexImage3D(GL_TEXTURE_3D, levelIndex, m_compressedFormat, level.getWidth(), level.getHeight(),
1104 level.getDepth(), 0 /* border */, level.getDataSize(), level.getData());
1105 GLU_EXPECT_NO_ERROR(gl.getError(), "callCompressedTexImage3D");
1106 }
1107
1108 // Replace whole texture data.
1109 for (int32_t levelIndex = levelsCount - 2; levelIndex >= 0; --levelIndex)
1110 {
1111 int32_t partWidth = de::max(width >> levelIndex, 1);
1112 int32_t partHeight = de::max(height >> levelIndex, 1);
1113 int32_t partDepth = de::max(depth >> levelIndex, 1);
1114
1115 tcu::CompressedTexture dataPart(format, partWidth, partHeight, partDepth);
1116 const int dataSize = dataPart.getDataSize();
1117 uint8_t *const data = static_cast<uint8_t *>(dataPart.getData());
1118 de::Random rnd(deStringHash(getName()) + levelIndex);
1119
1120 for (int i = 0; i < dataSize; i++)
1121 data[i] = rnd.getUint32() & 0xff;
1122
1123 callCompressedTexSubImage3D(GL_TEXTURE_3D, levelIndex, 0, 0, 0, dataPart.getWidth(), dataPart.getHeight(),
1124 dataPart.getDepth(), m_compressedFormat, dataPart.getDataSize(),
1125 dataPart.getData());
1126 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexSubImage3D");
1127 }
1128
1129 gl.deleteTextures(1, &textureName);
1130 GLU_EXPECT_NO_ERROR(gl.getError(), "gl.deleteTextures");
1131
1132 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1133 return STOP;
1134 }
1135
1136 class NegativeTexImage3DCase : public Texture3DBase
1137 {
1138 public:
1139 NegativeTexImage3DCase(deqp::Context &context, const char *name);
1140
1141 IterateResult iterate(void);
1142 };
1143
NegativeTexImage3DCase(deqp::Context & context,const char * name)1144 NegativeTexImage3DCase::NegativeTexImage3DCase(deqp::Context &context, const char *name)
1145 : Texture3DBase(context, name, "")
1146 {
1147 }
1148
iterate(void)1149 NegativeTexImage3DCase::IterateResult NegativeTexImage3DCase::iterate(void)
1150 {
1151 if (!isFeatureSupported())
1152 return STOP;
1153
1154 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1155
1156 /* Integer textures supported for OpenGL ES 3.0+ */
1157 int major = 0;
1158 gl.getIntegerv(GL_MAJOR_VERSION, &major);
1159 bool supportsIntegerTextures = major >= 3;
1160
1161 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1162
1163 // negative usage
1164 {
1165 const char *message1 = "GL_INVALID_ENUM is generated if target is invalid.";
1166 callTexImage3D(0, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1167 verifyError(GL_INVALID_ENUM, message1);
1168 callTexImage3D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1169 verifyError(GL_INVALID_ENUM, message1);
1170
1171 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, 0, 0);
1172 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if type is not a type constant.");
1173
1174 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, 0, GL_UNSIGNED_BYTE, 0);
1175 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if format is not an accepted format constant.");
1176
1177 callTexImage3D(GL_TEXTURE_3D, 0, 0, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1178 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if internalFormat is not one of the accepted "
1179 "resolution and format symbolic constants.");
1180
1181 const char *message2 = "GL_INVALID_OPERATION is generated if target is GL_TEXTURE_3D and format is "
1182 "GL_DEPTH_COMPONENT, or GL_DEPTH_STENCIL.";
1183 callTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH_STENCIL, 1, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
1184 verifyError(GL_INVALID_OPERATION, message2);
1185 callTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH_COMPONENT, 1, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
1186 verifyError(GL_INVALID_OPERATION, message2);
1187
1188 const char *message3 =
1189 "GL_INVALID_OPERATION is generated if the combination of internalFormat, format and type is invalid.";
1190 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1191 verifyError(GL_INVALID_OPERATION, message3);
1192 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_4_4_4_4, 0);
1193 verifyError(GL_INVALID_OPERATION, message3);
1194 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGB5_A1, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 0);
1195 verifyError(GL_INVALID_OPERATION, message3);
1196 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, 0);
1197 verifyError(GL_INVALID_OPERATION, message3);
1198
1199 if (supportsIntegerTextures)
1200 {
1201 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32UI, 1, 1, 1, 0, GL_RGBA_INTEGER, GL_INT, 0);
1202 verifyError(GL_INVALID_OPERATION, message3);
1203 }
1204 }
1205
1206 // invalid leve
1207 {
1208 const char *message = "GL_INVALID_VALUE is generated if level is less than 0.";
1209 callTexImage3D(GL_TEXTURE_3D, -1, GL_RGB, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1210 verifyError(GL_INVALID_VALUE, message);
1211 }
1212
1213 // maximal level
1214 {
1215 int max3DTexSize;
1216 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTexSize);
1217 GLint log2Max3DTextureSize = deLog2Floor32(max3DTexSize) + 1;
1218 callTexImage3D(GL_TEXTURE_3D, log2Max3DTextureSize, GL_RGB, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
1219 verifyError(GL_INVALID_VALUE,
1220 "GL_INVALID_VALUE is generated if level is greater than log_2(GL_MAX_3D_TEXTURE_SIZE).");
1221 }
1222
1223 // negative dimensions
1224 {
1225 const char *message = "GL_INVALID_VALUE is generated if width or height is less than 0.";
1226 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, -1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1227 verifyError(GL_INVALID_VALUE, message);
1228 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, -1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1229 verifyError(GL_INVALID_VALUE, message);
1230 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, -1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1231 verifyError(GL_INVALID_VALUE, message);
1232 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, -1, -1, -1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1233 verifyError(GL_INVALID_VALUE, message);
1234 }
1235
1236 // maximal dimensions
1237 {
1238 int aboveMax3DTextureSize;
1239 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &aboveMax3DTextureSize);
1240 int aboveMaxTextureSize;
1241 gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &aboveMaxTextureSize);
1242 ++aboveMax3DTextureSize;
1243 ++aboveMaxTextureSize;
1244
1245 const char *message =
1246 "GL_INVALID_VALUE is generated if width, height or depth is greater than GL_MAX_3D_TEXTURE_SIZE.";
1247 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, aboveMax3DTextureSize, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1248 verifyError(GL_INVALID_VALUE, message);
1249 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, aboveMax3DTextureSize, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1250 verifyError(GL_INVALID_VALUE, message);
1251 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, aboveMax3DTextureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1252 verifyError(GL_INVALID_VALUE, message);
1253 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, aboveMax3DTextureSize, aboveMax3DTextureSize, aboveMax3DTextureSize,
1254 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1255 verifyError(GL_INVALID_VALUE, message);
1256 }
1257
1258 // invalid border
1259 {
1260 const char *message = "GL_INVALID_VALUE is generated if border is not 0 or 1.";
1261 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 1, 1, 1, -1, GL_RGB, GL_UNSIGNED_BYTE, 0);
1262 verifyError(GL_INVALID_VALUE, message);
1263 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 1, 1, 1, 2, GL_RGB, GL_UNSIGNED_BYTE, 0);
1264 verifyError(GL_INVALID_VALUE, message);
1265 }
1266
1267 return STOP;
1268 }
1269
1270 class NegativeCompressedTexImage3DCase : public Texture3DBase
1271 {
1272 public:
1273 NegativeCompressedTexImage3DCase(deqp::Context &context, const char *name);
1274
1275 IterateResult iterate(void);
1276 };
1277
NegativeCompressedTexImage3DCase(deqp::Context & context,const char * name)1278 NegativeCompressedTexImage3DCase::NegativeCompressedTexImage3DCase(deqp::Context &context, const char *name)
1279 : Texture3DBase(context, name, "")
1280 {
1281 }
1282
1283 class NegativeTexSubImage3DCase : public Texture3DBase
1284 {
1285 public:
1286 NegativeTexSubImage3DCase(deqp::Context &context, const char *name);
1287
1288 IterateResult iterate(void);
1289 };
1290
NegativeTexSubImage3DCase(deqp::Context & context,const char * name)1291 NegativeTexSubImage3DCase::NegativeTexSubImage3DCase(deqp::Context &context, const char *name)
1292 : Texture3DBase(context, name, "")
1293 {
1294 }
1295
iterate(void)1296 NegativeTexSubImage3DCase::IterateResult NegativeTexSubImage3DCase::iterate(void)
1297 {
1298 if (!isFeatureSupported())
1299 return STOP;
1300
1301 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1302
1303 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1304
1305 // negative usage
1306 {
1307 uint32_t texture = 0x1234;
1308 gl.genTextures(1, &texture);
1309 gl.bindTexture(GL_TEXTURE_3D, texture);
1310 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1311 gl.getError(); // reset error
1312
1313 const char *message1 = "GL_INVALID_ENUM is generated if target is invalid.";
1314 callTexSubImage3D(0, 0, 0, 0, 0, 4, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1315 verifyError(GL_INVALID_ENUM, message1);
1316 callTexSubImage3D(GL_TEXTURE_2D, 0, 0, 0, 0, 4, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1317 verifyError(GL_INVALID_ENUM, message1);
1318
1319 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 4, 4, 4, GL_UNSIGNED_BYTE, 0);
1320 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if format is not an accepted format constant.");
1321
1322 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, GL_RGB, 0, 0);
1323 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if type is not a type constant.");
1324
1325 const char *message2 = "GL_INVALID_OPERATION is generated if the combination of internalFormat of "
1326 "the previously specified texture array, format and type is not valid.";
1327 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, GL_RGB, GL_UNSIGNED_SHORT_4_4_4_4, 0);
1328 verifyError(GL_INVALID_OPERATION, message2);
1329 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 0);
1330 verifyError(GL_INVALID_OPERATION, message2);
1331 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 0);
1332 verifyError(GL_INVALID_OPERATION, message2);
1333
1334 gl.deleteTextures(1, &texture);
1335 }
1336
1337 // negative level
1338 {
1339 uint32_t texture;
1340 gl.genTextures(1, &texture);
1341 gl.bindTexture(GL_TEXTURE_3D, texture);
1342 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1343 gl.getError(); // reset error
1344
1345 const char *message = "GL_INVALID_VALUE is generated if level is less than 0.";
1346 callTexSubImage3D(GL_TEXTURE_3D, -1, 0, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1347 verifyError(GL_INVALID_VALUE, message);
1348
1349 gl.deleteTextures(1, &texture);
1350 }
1351
1352 // maximal level
1353 {
1354 uint32_t texture;
1355 gl.genTextures(1, &texture);
1356 gl.bindTexture(GL_TEXTURE_3D, texture);
1357 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1358 gl.getError(); // reset error
1359
1360 int maxSize;
1361 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxSize);
1362 GLint log2Max3DTextureSize = deLog2Floor32(maxSize) + 1;
1363
1364 callTexSubImage3D(GL_TEXTURE_3D, log2Max3DTextureSize, 0, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1365 verifyError(GL_INVALID_VALUE,
1366 "GL_INVALID_VALUE is generated if level is greater than log_2(GL_MAX_3D_TEXTURE_SIZE).");
1367
1368 gl.deleteTextures(1, &texture);
1369 }
1370
1371 // negative offset
1372 {
1373 uint32_t texture;
1374 gl.genTextures(1, &texture);
1375 gl.bindTexture(GL_TEXTURE_3D, texture);
1376 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1377 gl.getError(); // reset error
1378
1379 const char *message = "GL_INVALID_VALUE is generated if xoffset, yoffset or zoffset are negative.";
1380 callTexSubImage3D(GL_TEXTURE_3D, 0, -1, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1381 verifyError(GL_INVALID_VALUE, message);
1382 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, -1, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1383 verifyError(GL_INVALID_VALUE, message);
1384 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, -1, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1385 verifyError(GL_INVALID_VALUE, message);
1386 callTexSubImage3D(GL_TEXTURE_3D, 0, -1, -1, -1, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1387 verifyError(GL_INVALID_VALUE, message);
1388
1389 gl.deleteTextures(1, &texture);
1390 }
1391
1392 // invalid offset
1393 {
1394 uint32_t texture = 0x1234;
1395 gl.genTextures(1, &texture);
1396 gl.bindTexture(GL_TEXTURE_3D, texture);
1397 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1398
1399 callTexSubImage3D(GL_TEXTURE_3D, 0, 2, 0, 0, 4, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1400 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if xoffset + width > texture_width.");
1401 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 2, 0, 4, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1402 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if yoffset + height > texture_height.");
1403 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, 4, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1404 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if zoffset + depth > texture_depth.");
1405
1406 gl.deleteTextures(1, &texture);
1407 }
1408
1409 // negative dimensions
1410 {
1411 const char *message = "GL_INVALID_VALUE is generated if width, height or depth is less than 0.";
1412 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, -1, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1413 verifyError(GL_INVALID_VALUE, message);
1414 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, -1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1415 verifyError(GL_INVALID_VALUE, message);
1416 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, -1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1417 verifyError(GL_INVALID_VALUE, message);
1418 callTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, -1, -1, -1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1419 verifyError(GL_INVALID_VALUE, message);
1420 }
1421
1422 return STOP;
1423 }
1424
1425 class NegativeCopyTexSubImage3DCase : public Texture3DBase
1426 {
1427 public:
1428 NegativeCopyTexSubImage3DCase(deqp::Context &context, const char *name);
1429
1430 IterateResult iterate(void);
1431 };
1432
NegativeCopyTexSubImage3DCase(deqp::Context & context,const char * name)1433 NegativeCopyTexSubImage3DCase::NegativeCopyTexSubImage3DCase(deqp::Context &context, const char *name)
1434 : Texture3DBase(context, name, "")
1435 {
1436 }
1437
iterate(void)1438 NegativeCopyTexSubImage3DCase::IterateResult NegativeCopyTexSubImage3DCase::iterate(void)
1439 {
1440 if (!isFeatureSupported())
1441 return STOP;
1442
1443 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1444 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1445
1446 // invalid usage
1447 {
1448 GLuint texture = 0x1234;
1449 gl.genTextures(1, &texture);
1450 gl.bindTexture(GL_TEXTURE_3D, texture);
1451 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1452
1453 callCopyTexSubImage3D(0, 0, 0, 0, 0, 0, 0, 4, 4);
1454 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if target is invalid.");
1455
1456 gl.deleteTextures(1, &texture);
1457 }
1458
1459 // negative level
1460 {
1461 uint32_t texture;
1462 gl.genTextures(1, &texture);
1463 gl.bindTexture(GL_TEXTURE_3D, texture);
1464 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1465 gl.getError(); // reset error
1466
1467 const char *message = "GL_INVALID_VALUE is generated if level is less than 0.";
1468 callCopyTexSubImage3D(GL_TEXTURE_3D, -1, 0, 0, 0, 0, 0, 4, 4);
1469 verifyError(GL_INVALID_VALUE, message);
1470
1471 gl.deleteTextures(1, &texture);
1472 }
1473
1474 // maximal level
1475 {
1476 int maxSize;
1477 int max3DSize;
1478 gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
1479 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DSize);
1480 uint32_t log2Max3DTextureSize = deLog2Floor32(max3DSize) + 1;
1481
1482 uint32_t texture;
1483 gl.genTextures(1, &texture);
1484 gl.bindTexture(GL_TEXTURE_3D, texture);
1485 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1486 gl.getError(); // reset error
1487
1488 callCopyTexSubImage3D(GL_TEXTURE_3D, log2Max3DTextureSize, 0, 0, 0, 0, 0, 4, 4);
1489 verifyError(GL_INVALID_VALUE,
1490 "GL_INVALID_VALUE is generated if level is greater than log_2(GL_MAX_3D_TEXTURE_SIZE).");
1491
1492 gl.deleteTextures(1, &texture);
1493 }
1494
1495 // negative offset
1496 {
1497 GLuint texture = 0x1234;
1498 gl.genTextures(1, &texture);
1499 gl.bindTexture(GL_TEXTURE_3D, texture);
1500 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1501 gl.getError(); // reset error
1502
1503 const char *message = "GL_INVALID_VALUE is generated if xoffset, yoffset or zoffset is negative.";
1504 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, -1, 0, 0, 0, 0, 4, 4);
1505 verifyError(GL_INVALID_VALUE, message);
1506 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, -1, 0, 0, 0, 4, 4);
1507 verifyError(GL_INVALID_VALUE, message);
1508 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, -1, 0, 0, 4, 4);
1509 verifyError(GL_INVALID_VALUE, message);
1510 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, -1, -1, -1, 0, 0, 4, 4);
1511 verifyError(GL_INVALID_VALUE, message);
1512
1513 gl.deleteTextures(1, &texture);
1514 }
1515
1516 // invalid offset
1517 {
1518 GLuint texture = 0x1234;
1519 gl.genTextures(1, &texture);
1520 gl.bindTexture(GL_TEXTURE_3D, texture);
1521 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1522 gl.getError(); // reset error
1523
1524 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 1, 0, 0, 0, 0, 4, 4);
1525 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if xoffset + width > texture_width.");
1526
1527 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 1, 0, 0, 0, 4, 4);
1528 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if yoffset + height > texture_height.");
1529
1530 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 4, 0, 0, 4, 4);
1531 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if zoffset + 1 > texture_depth.");
1532
1533 gl.deleteTextures(1, &texture);
1534 }
1535
1536 // negative dimensions
1537 {
1538 GLuint texture = 0x1234;
1539 gl.genTextures(1, &texture);
1540 gl.bindTexture(GL_TEXTURE_3D, texture);
1541 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1542 gl.getError(); // reset error
1543
1544 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, -4, 4);
1545 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if width < 0.");
1546
1547 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 4, -4);
1548 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if height < 0.");
1549
1550 gl.deleteTextures(1, &texture);
1551 }
1552
1553 // incomplete_framebuffer
1554 {
1555 GLuint fbo = 0x1234;
1556 GLuint texture;
1557
1558 gl.genTextures(1, &texture);
1559 gl.bindTexture(GL_TEXTURE_3D, texture);
1560 callTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1561 gl.genFramebuffers(1, &fbo);
1562 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1563 gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1564
1565 const char *message = "GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently "
1566 "bound framebuffer is not framebuffer complete.";
1567 callCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 4, 4);
1568 verifyError(GL_INVALID_FRAMEBUFFER_OPERATION, message);
1569
1570 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1571 gl.deleteFramebuffers(1, &fbo);
1572 gl.deleteTextures(1, &texture);
1573 }
1574
1575 return STOP;
1576 }
1577
1578 class NegativeFramebufferTexture3DCase : public Texture3DBase
1579 {
1580 public:
1581 NegativeFramebufferTexture3DCase(deqp::Context &context, const char *name);
1582
1583 IterateResult iterate(void);
1584 };
1585
NegativeFramebufferTexture3DCase(deqp::Context & context,const char * name)1586 NegativeFramebufferTexture3DCase::NegativeFramebufferTexture3DCase(deqp::Context &context, const char *name)
1587 : Texture3DBase(context, name, "")
1588 {
1589 }
1590
iterate(void)1591 NegativeFramebufferTexture3DCase::IterateResult NegativeFramebufferTexture3DCase::iterate(void)
1592 {
1593 if (!isFeatureSupported())
1594 return STOP;
1595
1596 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1597 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1598
1599 GLuint fbo = 0x1234;
1600 gl.genFramebuffers(1, &fbo);
1601 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1602
1603 GLuint tex3D = 0x1234;
1604 gl.genTextures(1, &tex3D);
1605 gl.bindTexture(GL_TEXTURE_3D, tex3D);
1606
1607 GLint maxTexSize = 0x1234;
1608 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE_OES, &maxTexSize);
1609 gl.getError(); // reset error
1610
1611 callFramebufferTexture3D(-1, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, tex3D, 0, 0);
1612 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if target is not one of the accepted tokens.");
1613
1614 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex3D, 0, 0);
1615 verifyError(GL_INVALID_OPERATION,
1616 "GL_INVALID_OPERATION is generated if textarget is not an accepted texture target.");
1617
1618 callFramebufferTexture3D(GL_FRAMEBUFFER, -1, GL_TEXTURE_3D, tex3D, 0, 0);
1619 verifyError(GL_INVALID_ENUM, "GL_INVALID_ENUM is generated if attachment is not an accepted token.");
1620
1621 const char *message1 =
1622 "GL_INVALID_VALUE is generated if level is less than 0 or larger than log_2 of maximum texture size.";
1623 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, tex3D, -1, 0);
1624 verifyError(GL_INVALID_VALUE, message1);
1625 GLint maxSize = deLog2Floor32(maxTexSize) + 1;
1626 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, tex3D, maxSize, 0);
1627 verifyError(GL_INVALID_VALUE, message1);
1628
1629 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, -1, 0, 0);
1630 verifyError(
1631 GL_INVALID_OPERATION,
1632 "GL_INVALID_OPERATION is generated if texture is neither 0 nor the name of an existing texture object.");
1633
1634 const char *message2 = "GL_INVALID_OPERATION is generated if textarget and texture are not compatible.";
1635 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, tex3D, 0, 0);
1636 verifyError(GL_INVALID_OPERATION, message2);
1637 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex3D, 0, 0);
1638 verifyError(GL_INVALID_OPERATION, message2);
1639 gl.deleteTextures(1, &tex3D);
1640
1641 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1642 callFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, 0, 0, 0);
1643 verifyError(GL_INVALID_OPERATION, "GL_INVALID_OPERATION is generated if zero is bound to target.");
1644
1645 gl.deleteFramebuffers(1, &fbo);
1646 return STOP;
1647 }
1648
iterate(void)1649 NegativeCompressedTexImage3DCase::IterateResult NegativeCompressedTexImage3DCase::iterate(void)
1650 {
1651 if (!isFeatureSupported())
1652 return STOP;
1653
1654 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1655 const glu::ContextInfo &contextInfo = m_context.getContextInfo();
1656
1657 std::set<int> supportedFormats;
1658 getSupportedCompressedFormats(supportedFormats);
1659
1660 if (supportedFormats.empty())
1661 {
1662 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "No supported compressed texture formats.");
1663 return STOP;
1664 }
1665
1666 GLenum supportedCompressedFormat = static_cast<GLenum>(*(supportedFormats.begin()));
1667 checkFormatSupport(contextInfo, supportedCompressedFormat);
1668 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1669
1670 // negative usage
1671 {
1672 const char *message1 = "GL_INVALID_ENUM is generated if target is invalid.";
1673 callCompressedTexImage3D(0, 0, supportedCompressedFormat, 0, 0, 0, 0, 0, 0);
1674 verifyError(GL_INVALID_ENUM, message1);
1675 callCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, supportedCompressedFormat, 0, 0, 0, 0, 0, 0);
1676 verifyError(GL_INVALID_ENUM, message1);
1677
1678 const char *message2 =
1679 "GL_INVALID_ENUM is generated if internalformat is not one of the specific compressed internal formats.";
1680 callCompressedTexImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 0, 0);
1681 verifyError(GL_INVALID_ENUM, message2);
1682 callCompressedTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, 0, 0);
1683 verifyError(GL_INVALID_ENUM, message2);
1684
1685 const char *message3 = "INVALID_OPERATION is generated if internalformat is an ETC2/EAC format.";
1686 for (int formatNdx = 0; formatNdx < tcu::COMPRESSEDTEXFORMAT_LAST; formatNdx++)
1687 {
1688 tcu::CompressedTexFormat format = static_cast<tcu::CompressedTexFormat>(formatNdx);
1689 if (tcu::isEtcFormat(format) && (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8))
1690 {
1691 uint32_t compressedFormat = glu::getGLFormat(format);
1692 callCompressedTexImage3D(GL_TEXTURE_3D, 0, compressedFormat, 0, 0, 0, 0, 0, 0);
1693 verifyError(GL_INVALID_OPERATION, message3);
1694 }
1695 }
1696 }
1697
1698 // negative level
1699 {
1700 callCompressedTexImage3D(GL_TEXTURE_3D, -1, supportedCompressedFormat, 0, 0, 0, 0, 0, 0);
1701 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if level is less than 0.");
1702 }
1703
1704 // maximal level
1705 {
1706 int maxSize;
1707 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxSize);
1708 GLint log2MaxTextureSize = deLog2Floor32(maxSize) + 1;
1709 callCompressedTexImage3D(GL_TEXTURE_3D, log2MaxTextureSize, supportedCompressedFormat, 0, 0, 0, 0, 0, 0);
1710 verifyError(GL_INVALID_VALUE,
1711 "GL_INVALID_VALUE is generated if level is greater than log_2(GL_MAX_TEXTURE_SIZE).");
1712 }
1713
1714 // negative dimensions
1715 {
1716 const char *message = "GL_INVALID_VALUE is generated if width, height or depth is less than 0.";
1717 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, -1, 0, 0, 0, 0, 0);
1718 verifyError(GL_INVALID_VALUE, message);
1719 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, -1, 0, 0, 0, 0);
1720 verifyError(GL_INVALID_VALUE, message);
1721 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, 0, -1, 0, 0, 0);
1722 verifyError(GL_INVALID_VALUE, message);
1723 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, -1, -1, -1, 0, 0, 0);
1724 verifyError(GL_INVALID_VALUE, message);
1725 }
1726
1727 // maximal dimensions
1728 {
1729 int maxTextureSize;
1730 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE_OES, &maxTextureSize);
1731 ++maxTextureSize;
1732
1733 const char *message =
1734 "GL_INVALID_VALUE is generated if width, height or depth is greater than GL_MAX_3D_TEXTURE_SIZE_OES.";
1735 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, maxTextureSize, 0, 0, 0, 0, 0);
1736 verifyError(GL_INVALID_VALUE, message);
1737 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, maxTextureSize, 0, 0, 0, 0);
1738 verifyError(GL_INVALID_VALUE, message);
1739 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, 0, maxTextureSize, 0, 0, 0);
1740 verifyError(GL_INVALID_VALUE, message);
1741 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, maxTextureSize, maxTextureSize,
1742 maxTextureSize, 0, 0, 0);
1743 verifyError(GL_INVALID_VALUE, message);
1744 }
1745
1746 // invalid border
1747 {
1748 const char *message = "GL_INVALID_VALUE is generated if border is not 0.";
1749 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, 0, 0, -1, 0, 0);
1750 verifyError(GL_INVALID_VALUE, message);
1751 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, 0, 0, 1, 0, 0);
1752 verifyError(GL_INVALID_VALUE, message);
1753 }
1754
1755 // invalid size
1756 {
1757 const char *message = "GL_INVALID_VALUE is generated if imageSize is not consistent with the "
1758 "format, dimensions, and contents of the specified compressed image data.";
1759 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 0, 0, 0, 0, -1, 0);
1760 verifyError(GL_INVALID_VALUE, message);
1761 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 16, 16, 1, 0, 9 * 4 * 8, 0);
1762 verifyError(GL_INVALID_VALUE, message);
1763 }
1764
1765 return STOP;
1766 }
1767
1768 class NegativeCompressedTexSubImage3DCase : public Texture3DBase
1769 {
1770 public:
1771 NegativeCompressedTexSubImage3DCase(deqp::Context &context, const char *name);
1772
1773 IterateResult iterate(void);
1774 };
1775
NegativeCompressedTexSubImage3DCase(deqp::Context & context,const char * name)1776 NegativeCompressedTexSubImage3DCase::NegativeCompressedTexSubImage3DCase(deqp::Context &context, const char *name)
1777 : Texture3DBase(context, name, "")
1778 {
1779 }
1780
iterate(void)1781 NegativeCompressedTexSubImage3DCase::IterateResult NegativeCompressedTexSubImage3DCase::iterate(void)
1782 {
1783 if (!isFeatureSupported())
1784 return STOP;
1785
1786 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1787 const glu::ContextInfo &contextInfo = m_context.getContextInfo();
1788
1789 std::set<int> supportedFormats;
1790 getSupportedCompressedFormats(supportedFormats);
1791
1792 if (supportedFormats.empty())
1793 {
1794 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "No supported compressed texture formats.");
1795 return STOP;
1796 }
1797
1798 GLenum supportedCompressedFormat = static_cast<GLenum>(*(supportedFormats.begin()));
1799 int textureSize = 16;
1800 int dataSize = calculateDataSize(supportedCompressedFormat, textureSize, textureSize, 1);
1801
1802 checkFormatSupport(contextInfo, supportedCompressedFormat);
1803
1804 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1805
1806 // negative level
1807 {
1808 uint32_t texture;
1809 gl.genTextures(1, &texture);
1810 gl.bindTexture(GL_TEXTURE_3D, texture);
1811 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, textureSize, textureSize, 1, 0, dataSize,
1812 0);
1813 gl.getError(); // reset error
1814
1815 callCompressedTexSubImage3D(GL_TEXTURE_3D, -1, 0, 0, 0, 0, 0, 0, supportedCompressedFormat, 0, 0);
1816 verifyError(GL_INVALID_VALUE, "GL_INVALID_VALUE is generated if level is less than 0.");
1817
1818 gl.deleteTextures(1, &texture);
1819 }
1820
1821 // invalid level
1822 {
1823 uint32_t texture;
1824 gl.genTextures(1, &texture);
1825 gl.bindTexture(GL_TEXTURE_3D, texture);
1826 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, textureSize, textureSize, 1, 0, dataSize,
1827 0);
1828 gl.getError(); // reset error
1829
1830 GLint log2MaxTextureSize = deLog2Floor32(m_context.getContextInfo().getInt(GL_MAX_3D_TEXTURE_SIZE)) + 1;
1831 callCompressedTexSubImage3D(GL_TEXTURE_3D, log2MaxTextureSize, 0, 0, 0, 0, 0, 0, supportedCompressedFormat, 0,
1832 0);
1833 verifyError(GL_INVALID_VALUE,
1834 "GL_INVALID_VALUE is generated if level is greater than log_2(GL_MAX_3D_TEXTURE_SIZE).");
1835
1836 gl.deleteTextures(1, &texture);
1837 }
1838
1839 // negative offsets
1840 {
1841 uint32_t texture;
1842 gl.genTextures(1, &texture);
1843 gl.bindTexture(GL_TEXTURE_3D, texture);
1844 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, textureSize, textureSize, 1, 0, dataSize,
1845 0);
1846 gl.getError(); // reset error
1847
1848 const char *message =
1849 "GL_INVALID_VALUE or GL_INVALID_OPERATION is generated if xoffset, yoffset or zoffset are negative.";
1850 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, -4, 0, 0, 0, 0, 0, supportedCompressedFormat, 0, 0);
1851 verifyError(GL_INVALID_VALUE, message);
1852 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, -4, 0, 0, 0, 0, supportedCompressedFormat, 0, 0);
1853 verifyError(GL_INVALID_VALUE, message);
1854 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, -4, 0, 0, 0, supportedCompressedFormat, 0, 0);
1855 verifyError(GL_INVALID_VALUE, message);
1856 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, -4, -4, -4, 0, 0, 0, supportedCompressedFormat, 0, 0);
1857 verifyError(GL_INVALID_VALUE, message);
1858
1859 gl.deleteTextures(1, &texture);
1860 }
1861
1862 // invalid offsets
1863 {
1864 uint32_t texture;
1865 gl.genTextures(1, &texture);
1866 gl.bindTexture(GL_TEXTURE_3D, texture);
1867 dataSize = calculateDataSize(supportedCompressedFormat, 4, 4, 1);
1868 callCompressedTexImage3D(GL_TEXTURE_3D, 0, supportedCompressedFormat, 4, 4, 1, 0, dataSize, 0);
1869 gl.getError(); // reset error
1870
1871 const char *message = "GL_INVALID_VALUE or GL_INVALID_OPERATION is generated if xoffset + width > "
1872 "texture_width or yoffset + height > texture_height.";
1873 dataSize = calculateDataSize(supportedCompressedFormat, 8, 4, 1);
1874 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 12, 0, 0, 8, 4, 1, supportedCompressedFormat, dataSize, 0);
1875 verifyError(GL_INVALID_VALUE, GL_INVALID_OPERATION, message);
1876 dataSize = calculateDataSize(supportedCompressedFormat, 4, 8, 1);
1877 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, 12, 0, 4, 8, 1, supportedCompressedFormat, dataSize, 0);
1878 verifyError(GL_INVALID_VALUE, GL_INVALID_OPERATION, message);
1879 dataSize = calculateDataSize(supportedCompressedFormat, 4, 4, 1);
1880 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 12, 4, 4, 1, supportedCompressedFormat, dataSize, 0);
1881 verifyError(GL_INVALID_VALUE, GL_INVALID_OPERATION, message);
1882 dataSize = calculateDataSize(supportedCompressedFormat, 8, 8, 1);
1883 callCompressedTexSubImage3D(GL_TEXTURE_3D, 0, 12, 12, 12, 8, 8, 1, supportedCompressedFormat, dataSize, 0);
1884 verifyError(GL_INVALID_VALUE, GL_INVALID_OPERATION, message);
1885
1886 gl.deleteTextures(1, &texture);
1887 }
1888
1889 return STOP;
1890 }
1891
Texture3DTests(deqp::Context & context)1892 Texture3DTests::Texture3DTests(deqp::Context &context) : TestCaseGroup(context, "texture_3d", "")
1893 {
1894 }
1895
~Texture3DTests(void)1896 Texture3DTests::~Texture3DTests(void)
1897 {
1898 }
1899
init()1900 void Texture3DTests::init()
1901 {
1902 static const struct
1903 {
1904 const char *name;
1905 GLint mode;
1906 } wrapModes[] = {{"clamp", GL_CLAMP_TO_EDGE}, {"repeat", GL_REPEAT}, {"mirror", GL_MIRRORED_REPEAT}};
1907
1908 static const struct
1909 {
1910 const char *name;
1911 GLint mode;
1912 } minFilterModes[] = {{"nearest", GL_NEAREST},
1913 {"linear", GL_LINEAR},
1914 {"nearest_mipmap_nearest", GL_NEAREST_MIPMAP_NEAREST},
1915 {"linear_mipmap_nearest", GL_LINEAR_MIPMAP_NEAREST},
1916 {"nearest_mipmap_linear", GL_NEAREST_MIPMAP_LINEAR},
1917 {"linear_mipmap_linear", GL_LINEAR_MIPMAP_LINEAR}};
1918
1919 static const struct
1920 {
1921 const char *name;
1922 GLint mode;
1923 } magFilterModes[] = {{"nearest", GL_NEAREST}, {"linear", GL_LINEAR}};
1924
1925 static const struct
1926 {
1927 int width;
1928 int height;
1929 int depth;
1930 } sizes[] = {{4, 8, 8}, {32, 64, 16}, {128, 32, 64}, {3, 7, 5}, {63, 63, 63}};
1931
1932 static const struct
1933 {
1934 const char *name;
1935 uint32_t format;
1936 uint32_t type;
1937 } filterableFormatsByType[] = {
1938 {"rgba", GL_RGBA, GL_UNSIGNED_BYTE},
1939 };
1940
1941 static const struct
1942 {
1943 const char *name;
1944 uint32_t format;
1945 } sizedFilterableFormatsByType[] = {
1946 {"rgba8", GL_RGBA8},
1947 };
1948
1949 static const struct
1950 {
1951 tcu::CompressedTexFormat fmt;
1952 } compressedFormats[] = {
1953 {tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8},
1954 {tcu::COMPRESSEDTEXFORMAT_EAC_R11},
1955 {tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11},
1956 {tcu::COMPRESSEDTEXFORMAT_EAC_RG11},
1957 {tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11},
1958 {tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8},
1959 {tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8},
1960 {tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1},
1961 {tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1},
1962 {tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8},
1963 {tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8},
1964 {tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA},
1965 {tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA},
1966 {tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA},
1967 {tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA},
1968 {tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA},
1969 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA},
1970 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA},
1971 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA},
1972 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA},
1973 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA},
1974 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA},
1975 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA},
1976 {tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA},
1977 {tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA},
1978 {tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8},
1979 {tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8},
1980 {tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8},
1981 {tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8},
1982 {tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8},
1983 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8},
1984 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8},
1985 {tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8},
1986 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8},
1987 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8},
1988 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8},
1989 {tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8},
1990 {tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8},
1991 {tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8},
1992 };
1993
1994 // Texture3DFilteringCase
1995 {
1996 deqp::TestCaseGroup *texFilteringGroup =
1997 new deqp::TestCaseGroup(m_context, "filtering", "3D Texture Filtering");
1998 addChild(texFilteringGroup);
1999
2000 // Formats.
2001 FilteringData data;
2002 deqp::TestCaseGroup *formatsGroup = new deqp::TestCaseGroup(m_context, "formats", "3D Texture Formats");
2003 texFilteringGroup->addChild(formatsGroup);
2004 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(sizedFilterableFormatsByType); fmtNdx++)
2005 {
2006 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
2007 {
2008 data.minFilter = minFilterModes[filterNdx].mode;
2009 bool isMipmap = data.minFilter != GL_NEAREST && data.minFilter != GL_LINEAR;
2010 data.magFilter = isMipmap ? GL_LINEAR : data.minFilter;
2011 data.internalFormat = sizedFilterableFormatsByType[fmtNdx].format;
2012 data.wrapS = GL_REPEAT;
2013 data.wrapT = GL_REPEAT;
2014 data.wrapR = GL_REPEAT;
2015 data.width = 64;
2016 data.height = 64;
2017 data.depth = 64;
2018
2019 const char *formatName = sizedFilterableFormatsByType[fmtNdx].name;
2020 const char *filterName = minFilterModes[filterNdx].name;
2021 std::string name = std::string(formatName) + "_" + filterName;
2022
2023 formatsGroup->addChild(new Texture3DFilteringCase(m_context, name.c_str(), "", data));
2024 }
2025 }
2026
2027 // Sizes.
2028 deqp::TestCaseGroup *sizesGroup = new deqp::TestCaseGroup(m_context, "sizes", "Texture Sizes");
2029 texFilteringGroup->addChild(sizesGroup);
2030 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); sizeNdx++)
2031 {
2032 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
2033 {
2034 data.minFilter = minFilterModes[filterNdx].mode;
2035 data.internalFormat = GL_RGBA8;
2036 bool isMipmap = data.minFilter != GL_NEAREST && data.minFilter != GL_LINEAR;
2037 data.magFilter = isMipmap ? GL_LINEAR : data.minFilter;
2038 data.wrapS = GL_REPEAT;
2039 data.wrapT = GL_REPEAT;
2040 data.wrapR = GL_REPEAT;
2041 data.width = sizes[sizeNdx].width;
2042 data.height = sizes[sizeNdx].height;
2043 data.depth = sizes[sizeNdx].depth;
2044
2045 const char *filterName = minFilterModes[filterNdx].name;
2046 std::string name = de::toString(data.width) + "x" + de::toString(data.height) + "x" +
2047 de::toString(data.depth) + "_" + filterName;
2048
2049 sizesGroup->addChild(new Texture3DFilteringCase(m_context, name.c_str(), "", data));
2050 }
2051 }
2052
2053 // Wrap modes.
2054 deqp::TestCaseGroup *combinationsGroup =
2055 new deqp::TestCaseGroup(m_context, "combinations", "Filter and wrap mode combinations");
2056 texFilteringGroup->addChild(combinationsGroup);
2057 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
2058 {
2059 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
2060 {
2061 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
2062 {
2063 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
2064 {
2065 for (int wrapRNdx = 0; wrapRNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapRNdx++)
2066 {
2067 data.minFilter = minFilterModes[minFilterNdx].mode;
2068 data.magFilter = magFilterModes[magFilterNdx].mode;
2069 data.internalFormat = GL_RGBA8;
2070 data.wrapS = wrapModes[wrapSNdx].mode;
2071 data.wrapT = wrapModes[wrapTNdx].mode;
2072 data.wrapR = wrapModes[wrapRNdx].mode;
2073 data.width = 63;
2074 data.height = 57;
2075 data.depth = 67;
2076 std::string name = std::string(minFilterModes[minFilterNdx].name) + "_" +
2077 magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name +
2078 "_" + wrapModes[wrapTNdx].name + "_" + wrapModes[wrapRNdx].name;
2079
2080 combinationsGroup->addChild(new Texture3DFilteringCase(m_context, name.c_str(), "", data));
2081 }
2082 }
2083 }
2084 }
2085 }
2086
2087 // negative tests.
2088 combinationsGroup->addChild(new NegativeTexImage3DCase(m_context, "negative"));
2089 }
2090
2091 // TexSubImage3DOES tests
2092 {
2093 tcu::TestCaseGroup *texSubImageGroup =
2094 new tcu::TestCaseGroup(m_testCtx, "sub_image", "Basic glTexSubImage3D() usage");
2095 addChild(texSubImageGroup);
2096 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(sizedFilterableFormatsByType); formatNdx++)
2097 {
2098 const char *fmtName = sizedFilterableFormatsByType[formatNdx].name;
2099 uint32_t format = sizedFilterableFormatsByType[formatNdx].format;
2100 texSubImageGroup->addChild(new TexSubImage3DCase(m_context, fmtName, "", format, 32, 64, 8));
2101 }
2102 texSubImageGroup->addChild(new NegativeTexSubImage3DCase(m_context, "negative"));
2103 }
2104
2105 // CopyTexSubImage3DOES tests
2106 {
2107 tcu::TestCaseGroup *copyTexSubImageGroup =
2108 new tcu::TestCaseGroup(m_testCtx, "copy_sub_image", "Basic glCopyTexSubImage3D() usage");
2109 addChild(copyTexSubImageGroup);
2110 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); formatNdx++)
2111 {
2112 const char *fmtName = filterableFormatsByType[formatNdx].name;
2113 uint32_t format = filterableFormatsByType[formatNdx].format;
2114 uint32_t type = filterableFormatsByType[formatNdx].type;
2115 copyTexSubImageGroup->addChild(new CopyTexSubImage3DCase(m_context, fmtName, "", format, type, 32, 64, 8));
2116 }
2117 copyTexSubImageGroup->addChild(new NegativeCopyTexSubImage3DCase(m_context, "negative"));
2118 }
2119
2120 // FramebufferTexture3DOES tests
2121 {
2122 tcu::TestCaseGroup *framebufferTextureGroup =
2123 new tcu::TestCaseGroup(m_testCtx, "framebuffer_texture", "Basic glFramebufferTexture3D() usage");
2124 addChild(framebufferTextureGroup);
2125 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); formatNdx++)
2126 {
2127 const char *fmtName = filterableFormatsByType[formatNdx].name;
2128 uint32_t format = filterableFormatsByType[formatNdx].format;
2129 uint32_t type = filterableFormatsByType[formatNdx].type;
2130 framebufferTextureGroup->addChild(
2131 new FramebufferTexture3DCase(m_context, fmtName, "", format, type, 64, 64, 3));
2132 }
2133 framebufferTextureGroup->addChild(new NegativeFramebufferTexture3DCase(m_context, "negative"));
2134 }
2135
2136 // CompressedTexImage3DOES and CompressedTexSubImage3DOES tests
2137 {
2138 tcu::TestCaseGroup *compressedTexGroup =
2139 new tcu::TestCaseGroup(m_testCtx, "compressed_texture", "Basic gl.compressedTexImage3D() usage");
2140 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(compressedFormats); formatNdx++)
2141 {
2142 // ETC2/EAC texture compression algorithm supports only two-dimensional images
2143 tcu::CompressedTexFormat format = static_cast<tcu::CompressedTexFormat>(formatNdx);
2144 if (tcu::isEtcFormat(format))
2145 continue;
2146
2147 uint32_t compressedFormat = glu::getGLFormat(format);
2148 const char *name = getCompressedFormatName(format);
2149 compressedTexGroup->addChild(new CompressedTexture3DCase(m_context, name, compressedFormat));
2150 }
2151 compressedTexGroup->addChild(new NegativeCompressedTexImage3DCase(m_context, "negative_compressed_tex_image"));
2152 compressedTexGroup->addChild(
2153 new NegativeCompressedTexSubImage3DCase(m_context, "negative_compressed_tex_sub_image"));
2154 addChild(compressedTexGroup);
2155 }
2156 }
2157 } // namespace es2cts
2158