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