1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Mipmapping tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktTextureMipmapTests.hpp"
27
28 #include "deRandom.hpp"
29 #include "deString.h"
30 #include "gluShaderUtil.hpp"
31 #include "gluTextureTestUtil.hpp"
32 #include "tcuMatrix.hpp"
33 #include "tcuMatrixUtil.hpp"
34 #include "tcuPixelFormat.hpp"
35 #include "tcuTexLookupVerifier.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuVectorUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vktTestGroupUtil.hpp"
40 #include "vktTextureTestUtil.hpp"
41
42 using namespace vk;
43
44 namespace vkt
45 {
46 namespace texture
47 {
48 namespace
49 {
50
51 using std::string;
52 using std::vector;
53 using tcu::TestLog;
54 using tcu::Vec2;
55 using tcu::Vec3;
56 using tcu::Vec4;
57 using tcu::IVec4;
58 using tcu::Sampler;
59 using tcu::TextureFormat;
60 using namespace texture::util;
61 using namespace glu::TextureTestUtil;
62
getMinLodForCell(int cellNdx)63 float getMinLodForCell (int cellNdx)
64 {
65 static const float s_values[] =
66 {
67 1.0f,
68 3.5f,
69 2.0f,
70 -2.0f,
71 0.0f,
72 3.0f,
73 10.0f,
74 4.8f,
75 5.8f,
76 5.7f,
77 -1.9f,
78 4.0f,
79 6.5f,
80 7.1f,
81 -1e10,
82 1000.f
83 };
84 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
85 }
86
getMaxLodForCell(int cellNdx)87 float getMaxLodForCell (int cellNdx)
88 {
89 static const float s_values[] =
90 {
91 0.0f,
92 0.2f,
93 0.7f,
94 0.4f,
95 1.3f,
96 0.0f,
97 0.5f,
98 1.2f,
99 -2.0f,
100 1.0f,
101 0.1f,
102 0.3f,
103 2.7f,
104 1.2f,
105 10.0f,
106 -1000.f,
107 1e10f
108 };
109 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
110 }
111
112 enum CoordType
113 {
114 COORDTYPE_BASIC, //!< texCoord = translateScale(position).
115 COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values.
116 COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position).
117 COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1
118
119 COORDTYPE_LAST
120 };
121
122 struct TextureMipmapCommonTestCaseParameters
123 {
124 TextureMipmapCommonTestCaseParameters (void);
125 CoordType coordType;
126 const char* minFilterName;
127 };
128
TextureMipmapCommonTestCaseParameters(void)129 TextureMipmapCommonTestCaseParameters::TextureMipmapCommonTestCaseParameters (void)
130 : coordType (COORDTYPE_BASIC)
131 , minFilterName (NULL)
132 {
133 }
134
135 struct Texture2DMipmapTestCaseParameters : public Texture2DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
136 {
137 };
138
139 struct TextureCubeMipmapTestCaseParameters : public TextureCubeTestCaseParameters, public TextureMipmapCommonTestCaseParameters
140 {
141 };
142
143 struct Texture3DMipmapTestCaseParameters : public Texture3DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
144 {
145 };
146
147 // Texture2DMipmapTestInstance
148 class Texture2DMipmapTestInstance : public TestInstance
149 {
150 public:
151 typedef Texture2DMipmapTestCaseParameters ParameterType;
152
153 Texture2DMipmapTestInstance (Context& context, const ParameterType& testParameters);
154 ~Texture2DMipmapTestInstance (void);
155
156 virtual tcu::TestStatus iterate (void);
157
158 private:
159 Texture2DMipmapTestInstance (const Texture2DMipmapTestInstance& other);
160 Texture2DMipmapTestInstance& operator= (const Texture2DMipmapTestInstance& other);
161
162 const ParameterType m_testParameters;
163 TestTexture2DSp m_texture;
164 TextureRenderer m_renderer;
165 };
166
Texture2DMipmapTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)167 Texture2DMipmapTestInstance::Texture2DMipmapTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
168 : TestInstance (context)
169 , m_testParameters (testParameters)
170 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
171 {
172 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
173
174 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height));
175
176 const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1;
177
178 // Fill texture with colored grid.
179 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
180 {
181 const deUint32 step = 0xff / (numLevels-1);
182 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
183 const deUint32 dec = 0xff - inc;
184 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
185 const deUint32 color = 0xff000000 | rgb;
186
187 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
188 }
189
190 // Upload texture data.
191 m_renderer.add2DTexture(m_texture);
192 }
193
~Texture2DMipmapTestInstance(void)194 Texture2DMipmapTestInstance::~Texture2DMipmapTestInstance (void)
195 {
196 }
197
getBasicTexCoord2D(std::vector<float> & dst,int cellNdx)198 static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
199 {
200 static const struct
201 {
202 const Vec2 bottomLeft;
203 const Vec2 topRight;
204 } s_basicCoords[] =
205 {
206 { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) },
207 { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) },
208 { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) },
209 { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) },
210
211 { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) },
212 { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) },
213 { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) },
214 { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) },
215
216 { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) },
217 { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) },
218 { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) },
219 { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },
220
221 { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) },
222 { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) },
223 { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) },
224 { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) },
225 };
226
227 DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));
228
229 const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft;
230 const Vec2& topRight = s_basicCoords[cellNdx].topRight;
231
232 computeQuadTexCoord2D(dst, bottomLeft, topRight);
233 }
234
getAffineTexCoord2D(std::vector<float> & dst,int cellNdx)235 static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
236 {
237 // Use basic coords as base.
238 getBasicTexCoord2D(dst, cellNdx);
239
240 // Rotate based on cell index.
241 const float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f);
242 const tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle);
243
244 // Second and third row are sheared.
245 const float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
246 const tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));
247
248 const tcu::Mat2 transform = rotMatrix * shearMatrix;
249 const Vec2 p0 = transform * Vec2(dst[0], dst[1]);
250 const Vec2 p1 = transform * Vec2(dst[2], dst[3]);
251 const Vec2 p2 = transform * Vec2(dst[4], dst[5]);
252 const Vec2 p3 = transform * Vec2(dst[6], dst[7]);
253
254 dst[0] = p0.x(); dst[1] = p0.y();
255 dst[2] = p1.x(); dst[3] = p1.y();
256 dst[4] = p2.x(); dst[5] = p2.y();
257 dst[6] = p3.x(); dst[7] = p3.y();
258 }
259
iterate(void)260 tcu::TestStatus Texture2DMipmapTestInstance::iterate (void)
261 {
262 const Sampler::FilterMode magFilter = Sampler::NEAREST;
263 const int viewportWidth = m_renderer.getRenderWidth();
264 const int viewportHeight = m_renderer.getRenderHeight();
265
266 ReferenceParams refParams (TEXTURETYPE_2D);
267 vector<float> texCoord;
268
269 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
270 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
271
272 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
273
274 // Viewport is divided into 4x4 grid.
275 const int gridWidth = 4;
276 const int gridHeight = 4;
277 const int cellWidth = viewportWidth / gridWidth;
278 const int cellHeight = viewportHeight / gridHeight;
279
280 // Sampling parameters.
281 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
282 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format));
283 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
284 refParams.lodMode = LODMODE_EXACT; // Use ideal lod.
285
286 // Bias values.
287 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
288
289 // Projection values.
290 static const Vec4 s_projections[] =
291 {
292 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
293 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
294 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
295 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
296 };
297
298 // Render cells.
299 for (int gridY = 0; gridY < gridHeight; gridY++)
300 {
301 for (int gridX = 0; gridX < gridWidth; gridX++)
302 {
303 const int curX = cellWidth*gridX;
304 const int curY = cellHeight*gridY;
305 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
306 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
307 const int cellNdx = gridY*gridWidth + gridX;
308
309 // Compute texcoord.
310 switch (m_testParameters.coordType)
311 {
312 case COORDTYPE_BASIC_BIAS: // Fall-through.
313 case COORDTYPE_PROJECTED:
314 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
315 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
316 default: DE_ASSERT(DE_FALSE);
317 }
318
319 if (isProjected)
320 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
321
322 if (useLodBias)
323 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
324
325 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
326 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
327 }
328 }
329
330 // Compare and log.
331 {
332 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
333 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
334 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
335 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
336 tcu::Surface errorMask (viewportWidth, viewportHeight);
337 tcu::LookupPrecision lookupPrec;
338 tcu::LodPrecision lodPrec;
339 int numFailedPixels = 0;
340
341 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
342 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
343 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
344 lookupPrec.colorMask = getCompareMask(pixelFormat);
345 lodPrec.derivateBits = 10;
346 lodPrec.lodBits = isProjected ? 6 : 8;
347
348 for (int gridY = 0; gridY < gridHeight; gridY++)
349 {
350 for (int gridX = 0; gridX < gridWidth; gridX++)
351 {
352 const int curX = cellWidth*gridX;
353 const int curY = cellHeight*gridY;
354 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
355 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
356 const int cellNdx = gridY*gridWidth + gridX;
357
358 // Compute texcoord.
359 switch (m_testParameters.coordType)
360 {
361 case COORDTYPE_BASIC_BIAS: // Fall-through.
362 case COORDTYPE_PROJECTED:
363 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
364 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
365 default: DE_ASSERT(DE_FALSE);
366 }
367
368 if (isProjected)
369 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
370
371 if (useLodBias)
372 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
373
374 // Render ideal result
375 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
376 m_texture->getTexture(), &texCoord[0], refParams);
377
378 // Compare this cell
379 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
380 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
381 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
382 m_texture->getTexture(), &texCoord[0], refParams,
383 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
384 }
385 }
386
387 if (numFailedPixels > 0)
388 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
389
390 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
391 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
392
393 if (numFailedPixels > 0)
394 {
395 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
396 << TestLog::Image("ErrorMask", "Error mask", errorMask);
397 }
398
399 m_context.getTestContext().getLog() << TestLog::EndImageSet;
400
401 {
402 const bool isOk = numFailedPixels == 0;
403 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
404 }
405 }
406 }
407
408 // TextureCubeMipmapTestInstance
409 class TextureCubeMipmapTestInstance : public TestInstance
410 {
411 public:
412 typedef TextureCubeMipmapTestCaseParameters ParameterType;
413
414 TextureCubeMipmapTestInstance (Context& context, const ParameterType& testParameters);
415 ~TextureCubeMipmapTestInstance (void);
416
417 virtual tcu::TestStatus iterate (void);
418
419 private:
420 TextureCubeMipmapTestInstance (const TextureCubeMipmapTestInstance& other);
421 TextureCubeMipmapTestInstance& operator= (const TextureCubeMipmapTestInstance& other);
422
423 const ParameterType m_testParameters;
424 TestTextureCubeSp m_texture;
425 TextureRenderer m_renderer;
426 };
427
TextureCubeMipmapTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)428 TextureCubeMipmapTestInstance::TextureCubeMipmapTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
429 : TestInstance (context)
430 , m_testParameters (testParameters)
431 , m_renderer (context, m_testParameters.sampleCount, m_testParameters.size*2, m_testParameters.size*2)
432 {
433 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
434
435 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size));
436
437 const int numLevels = deLog2Floor32(m_testParameters.size)+1;
438
439 // Fill texture with colored grid.
440 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
441 {
442 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
443 {
444 const deUint32 step = 0xff / (numLevels-1);
445 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
446 const deUint32 dec = 0xff - inc;
447 deUint32 rgb = 0;
448
449 switch (faceNdx)
450 {
451 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
452 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
453 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
454 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
455 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
456 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
457 }
458
459 const deUint32 color = 0xff000000 | rgb;
460 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
461 }
462 }
463
464 m_renderer.addCubeTexture(m_texture);
465 }
466
~TextureCubeMipmapTestInstance(void)467 TextureCubeMipmapTestInstance::~TextureCubeMipmapTestInstance (void)
468 {
469 }
470
randomPartition(vector<IVec4> & dst,de::Random & rnd,int x,int y,int width,int height)471 static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
472 {
473 const int minWidth = 8;
474 const int minHeight = 8;
475
476 const bool partition = rnd.getFloat() > 0.4f;
477 const bool partitionX = partition && width > minWidth && rnd.getBool();
478 const bool partitionY = partition && height > minHeight && !partitionX;
479
480 if (partitionX)
481 {
482 const int split = width/2 + rnd.getInt(-width/4, +width/4);
483 randomPartition(dst, rnd, x, y, split, height);
484 randomPartition(dst, rnd, x+split, y, width-split, height);
485 }
486 else if (partitionY)
487 {
488 const int split = height/2 + rnd.getInt(-height/4, +height/4);
489 randomPartition(dst, rnd, x, y, width, split);
490 randomPartition(dst, rnd, x, y+split, width, height-split);
491 }
492 else
493 dst.push_back(IVec4(x, y, width, height));
494 }
495
computeGridLayout(vector<IVec4> & dst,int width,int height)496 static void computeGridLayout (vector<IVec4>& dst, int width, int height)
497 {
498 de::Random rnd(7);
499 randomPartition(dst, rnd, 0, 0, width, height);
500 }
501
iterate(void)502 tcu::TestStatus TextureCubeMipmapTestInstance::iterate (void)
503 {
504 const int viewportWidth = m_renderer.getRenderWidth();
505 const int viewportHeight = m_renderer.getRenderHeight();
506
507 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
508 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
509
510 ReferenceParams refParams (TEXTURETYPE_CUBE);
511 vector<float> texCoord;
512 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
513
514 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
515 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format));
516 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
517 refParams.lodMode = LODMODE_EXACT; // Use ideal lod.
518
519 // Compute grid.
520 vector<IVec4> gridLayout;
521 computeGridLayout(gridLayout, viewportWidth, viewportHeight);
522
523 // Bias values.
524 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
525
526 // Projection values \note Less agressive than in 2D case due to smaller quads.
527 static const Vec4 s_projections[] =
528 {
529 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
530 Vec4(1.3f, 0.8f, 0.6f, 1.1f),
531 Vec4(0.8f, 1.0f, 1.2f, 0.8f),
532 Vec4(1.2f, 1.0f, 1.3f, 0.9f)
533 };
534
535 // Render with GL
536 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
537 {
538 const float curX = (float)gridLayout[cellNdx].x();
539 const float curY = (float)gridLayout[cellNdx].y();
540 const float curW = (float)gridLayout[cellNdx].z();
541 const float curH = (float)gridLayout[cellNdx].w();
542 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
543
544 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
545 computeQuadTexCoordCube(texCoord, cubeFace);
546
547 if (isProjected)
548 {
549 refParams.flags |= ReferenceParams::PROJECTED;
550 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
551 }
552
553 if (useLodBias)
554 {
555 refParams.flags |= ReferenceParams::USE_BIAS;
556 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
557 }
558
559 // Render
560 m_renderer.setViewport(curX, curY, curW, curH);
561 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
562 }
563
564 // Render reference and compare
565 {
566 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
567 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
568 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
569 tcu::Surface errorMask (viewportWidth, viewportHeight);
570 int numFailedPixels = 0;
571 tcu::LookupPrecision lookupPrec;
572 tcu::LodPrecision lodPrec;
573
574 // Params for rendering reference
575 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
576 refParams.sampler.seamlessCubeMap = true;
577 refParams.lodMode = LODMODE_EXACT;
578
579 // Comparison parameters
580 lookupPrec.colorMask = getCompareMask(pixelFormat);
581 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, tcu::IVec4(0)));
582 lookupPrec.coordBits = isProjected ? tcu::IVec3(8) : tcu::IVec3(10);
583 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
584 lodPrec.derivateBits = 10;
585 lodPrec.lodBits = isProjected ? 3 : 6;
586
587 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
588 {
589 const int curX = gridLayout[cellNdx].x();
590 const int curY = gridLayout[cellNdx].y();
591 const int curW = gridLayout[cellNdx].z();
592 const int curH = gridLayout[cellNdx].w();
593 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
594
595 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
596 computeQuadTexCoordCube(texCoord, cubeFace);
597
598 if (isProjected)
599 {
600 refParams.flags |= ReferenceParams::PROJECTED;
601 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
602 }
603
604 if (useLodBias)
605 {
606 refParams.flags |= ReferenceParams::USE_BIAS;
607 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
608 }
609
610 // Render ideal reference.
611 {
612 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
613 sampleTexture(idealDst, m_texture->getTexture(), &texCoord[0], refParams);
614 }
615
616 // Compare this cell
617 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
618 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
619 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
620 m_texture->getTexture(), &texCoord[0], refParams,
621 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
622 }
623
624 if (numFailedPixels > 0)
625 {
626 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
627 }
628
629 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
630 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
631
632 if (numFailedPixels > 0)
633 {
634 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
635 << TestLog::Image("ErrorMask", "Error mask", errorMask);
636 }
637
638 m_context.getTestContext().getLog() << TestLog::EndImageSet;
639
640 {
641 const bool isOk = numFailedPixels == 0;
642 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
643 }
644 }
645 }
646
647 // Texture3DMipmapTestInstance
648 class Texture3DMipmapTestInstance : public TestInstance
649 {
650 public:
651 typedef Texture3DMipmapTestCaseParameters ParameterType;
652
653 Texture3DMipmapTestInstance (Context& context, const ParameterType& testParameters);
654 ~Texture3DMipmapTestInstance (void);
655
656 virtual tcu::TestStatus iterate (void);
657
658 private:
659 Texture3DMipmapTestInstance (const Texture3DMipmapTestInstance& other);
660 Texture3DMipmapTestInstance& operator= (const Texture3DMipmapTestInstance& other);
661
662 const ParameterType m_testParameters;
663 TestTexture3DSp m_texture;
664 TextureRenderer m_renderer;
665 };
666
Texture3DMipmapTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)667 Texture3DMipmapTestInstance::Texture3DMipmapTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
668 : TestInstance (context)
669 , m_testParameters (testParameters)
670 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
671 {
672 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
673
674 const tcu::TextureFormat& texFmt = mapVkFormat(testParameters.format);
675 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
676 const tcu::Vec4& cScale = fmtInfo.lookupScale;
677 const tcu::Vec4& cBias = fmtInfo.lookupBias;
678 const int numLevels = deLog2Floor32(de::max(de::max(testParameters.width, testParameters.height), testParameters.depth))+1;
679
680 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.depth));
681
682 // Fill texture with colored grid.
683 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
684 {
685 const deUint32 step = 0xff / (numLevels-1);
686 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
687 const deUint32 dec = 0xff - inc;
688 const deUint32 rgb = (0xff << 16) | (dec << 8) | inc;
689 const deUint32 color = 0xff000000 | rgb;
690
691 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
692 }
693
694 m_renderer.add3DTexture(m_texture);
695 }
696
~Texture3DMipmapTestInstance(void)697 Texture3DMipmapTestInstance::~Texture3DMipmapTestInstance (void)
698 {
699 }
700
getBasicTexCoord3D(std::vector<float> & dst,int cellNdx)701 static void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx)
702 {
703 static const struct
704 {
705 const float sScale;
706 const float sBias;
707 const float tScale;
708 const float tBias;
709 const float rScale;
710 const float rBias;
711 } s_params[] =
712 {
713 // sScale sBias tScale tBias rScale rBias
714 { 0.9f, -0.1f, 0.7f, 0.3f, 0.8f, 0.9f },
715 { 1.2f, -0.1f, 1.1f, 0.3f, 1.0f, 0.9f },
716 { 1.5f, 0.7f, 0.9f, -0.3f, 1.1f, 0.1f },
717 { 1.2f, 0.7f, -2.3f, -0.3f, 1.1f, 0.2f },
718 { 1.1f, 0.8f, -1.3f, -0.3f, 2.9f, 0.9f },
719 { 3.4f, 0.8f, 4.0f, 0.0f, -3.3f, -1.0f },
720 { -3.4f, -0.1f, -4.0f, 0.0f, -5.1f, 1.0f },
721 { -4.0f, -0.1f, 3.4f, 0.1f, 5.7f, 0.0f },
722 { -5.6f, 0.0f, 0.5f, 1.2f, 3.9f, 4.0f },
723 { 5.0f, -2.0f, 3.1f, 1.2f, 5.1f, 0.2f },
724 { 2.5f, -2.0f, 6.3f, 3.0f, 5.1f, 0.2f },
725 { -8.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
726 { 3.8f, 0.0f, 9.7f, 1.0f, 7.0f, 0.7f },
727 { 13.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
728 { 16.0f, 8.0f, 12.7f, 1.0f, 17.1f, 0.7f },
729 { 15.3f, 0.0f, 20.1f, 3.0f, 33.0f, 3.2f }
730 };
731
732 const float sScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale;
733 const float sBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias;
734 const float tScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale;
735 const float tBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias;
736 const float rScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale;
737 const float rBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias;
738
739 dst.resize(3*4);
740
741 dst[0] = sBias; dst[ 1] = tBias; dst[ 2] = rBias;
742 dst[3] = sBias; dst[ 4] = tBias+tScale; dst[ 5] = rBias+rScale*0.5f;
743 dst[6] = sBias+sScale; dst[ 7] = tBias; dst[ 8] = rBias+rScale*0.5f;
744 dst[9] = sBias+sScale; dst[10] = tBias+tScale; dst[11] = rBias+rScale;
745 }
746
getAffineTexCoord3D(std::vector<float> & dst,int cellNdx)747 static void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx)
748 {
749 // Use basic coords as base.
750 getBasicTexCoord3D(dst, cellNdx);
751
752 // Rotate based on cell index.
753 const float angleX = 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f);
754 const float angleY = 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f);
755 const tcu::Mat3 rotMatrix = tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY);
756
757 const Vec3 p0 = rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]);
758 const Vec3 p1 = rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]);
759 const Vec3 p2 = rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]);
760 const Vec3 p3 = rotMatrix * Vec3(dst[9], dst[10], dst[11]);
761
762 dst[0] = p0.x(); dst[ 1] = p0.y(); dst[ 2] = p0.z();
763 dst[3] = p1.x(); dst[ 4] = p1.y(); dst[ 5] = p1.z();
764 dst[6] = p2.x(); dst[ 7] = p2.y(); dst[ 8] = p2.z();
765 dst[9] = p3.x(); dst[10] = p3.y(); dst[11] = p3.z();
766 }
767
iterate(void)768 tcu::TestStatus Texture3DMipmapTestInstance::iterate (void)
769 {
770 const tcu::TextureFormat& texFmt = m_texture->getTextureFormat();
771 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
772 const Sampler::FilterMode magFilter = Sampler::NEAREST;
773 const int viewportWidth = m_renderer.getRenderWidth();
774 const int viewportHeight = m_renderer.getRenderHeight();
775
776 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
777 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
778
779 // Viewport is divided into 4x4 grid.
780 const int gridWidth = 4;
781 const int gridHeight = 4;
782 const int cellWidth = viewportWidth / gridWidth;
783 const int cellHeight = viewportHeight / gridHeight;
784
785 ReferenceParams refParams (TEXTURETYPE_3D);
786
787 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
788 vector<float> texCoord;
789
790 // Sampling parameters.
791 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
792 refParams.samplerType = getSamplerType(texFmt);
793
794 refParams.colorBias = fmtInfo.lookupBias;
795 refParams.colorScale = fmtInfo.lookupScale;
796 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
797
798 // Bias values.
799 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
800
801 // Projection values.
802 static const Vec4 s_projections[] =
803 {
804 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
805 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
806 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
807 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
808 };
809
810 // Render cells.
811 for (int gridY = 0; gridY < gridHeight; gridY++)
812 {
813 for (int gridX = 0; gridX < gridWidth; gridX++)
814 {
815 const int curX = cellWidth*gridX;
816 const int curY = cellHeight*gridY;
817 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
818 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
819 const int cellNdx = gridY*gridWidth + gridX;
820
821 // Compute texcoord.
822 switch (m_testParameters.coordType)
823 {
824 case COORDTYPE_BASIC_BIAS: // Fall-through.
825 case COORDTYPE_PROJECTED:
826 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
827 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
828 default: DE_ASSERT(DE_FALSE);
829 }
830
831 // Set projection.
832 if (isProjected)
833 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
834
835 // Set LOD bias.
836 if (useLodBias)
837 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
838
839 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
840 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
841 }
842 }
843
844 // Compare and log
845 {
846 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
847 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
848 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
849 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
850 tcu::Surface errorMask (viewportWidth, viewportHeight);
851 tcu::LookupPrecision lookupPrec;
852 tcu::LodPrecision lodPrec;
853 int numFailedPixels = 0;
854
855 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
856 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
857 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
858 lookupPrec.colorMask = getCompareMask(pixelFormat);
859 lodPrec.derivateBits = 10;
860 lodPrec.lodBits = isProjected ? 6 : 8;
861
862 for (int gridY = 0; gridY < gridHeight; gridY++)
863 {
864 for (int gridX = 0; gridX < gridWidth; gridX++)
865 {
866 const int curX = cellWidth*gridX;
867 const int curY = cellHeight*gridY;
868 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
869 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
870 const int cellNdx = gridY*gridWidth + gridX;
871
872 switch (m_testParameters.coordType)
873 {
874 case COORDTYPE_BASIC_BIAS: // Fall-through.
875 case COORDTYPE_PROJECTED:
876 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
877 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
878 default: DE_ASSERT(DE_FALSE);
879 }
880
881 if (isProjected)
882 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
883
884 if (useLodBias)
885 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
886
887 // Render ideal result
888 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
889 m_texture->getTexture(), &texCoord[0], refParams);
890
891 // Compare this cell
892 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
893 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
894 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
895 m_texture->getTexture(), &texCoord[0], refParams,
896 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
897 }
898 }
899
900 if (numFailedPixels > 0)
901 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
902
903 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
904 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
905
906 if (numFailedPixels > 0)
907 {
908 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
909 << TestLog::Image("ErrorMask", "Error mask", errorMask);
910 }
911
912 m_context.getTestContext().getLog() << TestLog::EndImageSet;
913
914 {
915 const bool isOk = numFailedPixels == 0;
916 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
917 }
918 }
919 }
920
921 // Texture2DLodControlTestInstance
922 class Texture2DLodControlTestInstance : public TestInstance
923 {
924 public:
925 typedef Texture2DMipmapTestCaseParameters ParameterType;
926
927 Texture2DLodControlTestInstance (Context& context, const ParameterType& testParameters);
928 ~Texture2DLodControlTestInstance (void);
929
930 virtual tcu::TestStatus iterate (void);
931
932 protected:
933 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = 0;
934
935 const int m_texWidth;
936 const int m_texHeight;
937
938 private:
939 Texture2DLodControlTestInstance (const Texture2DLodControlTestInstance& other);
940 Texture2DLodControlTestInstance& operator= (const Texture2DLodControlTestInstance& other);
941
942 const ParameterType m_testParameters;
943 tcu::Sampler::FilterMode m_minFilter;
944 TestTexture2DSp m_texture;
945 TextureRenderer m_renderer;
946 };
947
Texture2DLodControlTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)948 Texture2DLodControlTestInstance::Texture2DLodControlTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
949 : TestInstance (context)
950 , m_texWidth (64) //64
951 , m_texHeight (64)//64
952 , m_testParameters (testParameters)
953 , m_minFilter (testParameters.minFilter)
954 , m_texture (DE_NULL)
955 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4)
956 {
957 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
958 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
959
960 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(format), m_texWidth, m_texHeight));
961
962 // Fill texture with colored grid.
963 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
964 {
965 const deUint32 step = 0xff / (numLevels-1);
966 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
967 const deUint32 dec = 0xff - inc;
968 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
969 const deUint32 color = 0xff000000 | rgb;
970
971 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
972 }
973
974 m_renderer.add2DTexture(m_texture);
975 }
976
~Texture2DLodControlTestInstance(void)977 Texture2DLodControlTestInstance::~Texture2DLodControlTestInstance (void)
978 {
979 }
980
iterate(void)981 tcu::TestStatus Texture2DLodControlTestInstance::iterate (void)
982 {
983 const tcu::Sampler::WrapMode wrapS = Sampler::REPEAT_GL;
984 const tcu::Sampler::WrapMode wrapT = Sampler::REPEAT_GL;
985 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
986
987 const tcu::Texture2D& refTexture = m_texture->getTexture();
988
989 const int viewportWidth = m_renderer.getRenderWidth();
990 const int viewportHeight = m_renderer.getRenderHeight();
991
992 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
993
994 ReferenceParams refParams (TEXTURETYPE_2D, sampler);
995 vector<float> texCoord;
996 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
997
998 // Viewport is divided into 4x4 grid.
999 const int gridWidth = 4;
1000 const int gridHeight = 4;
1001 const int cellWidth = viewportWidth / gridWidth;
1002 const int cellHeight = viewportHeight / gridHeight;
1003
1004 refParams.maxLevel = deLog2Floor32(de::max(m_texWidth, m_texHeight));
1005
1006 // Render cells.
1007 for (int gridY = 0; gridY < gridHeight; gridY++)
1008 {
1009 for (int gridX = 0; gridX < gridWidth; gridX++)
1010 {
1011 const int curX = cellWidth*gridX;
1012 const int curY = cellHeight*gridY;
1013 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1014 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1015 const int cellNdx = gridY*gridWidth + gridX;
1016
1017 // Compute texcoord.
1018 getBasicTexCoord2D(texCoord, cellNdx);
1019 // Render
1020 getReferenceParams(refParams,cellNdx);
1021 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1022 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel);
1023 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1024 }
1025 }
1026
1027 // Compare and log.
1028 {
1029 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1030 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1031 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
1032 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
1033 tcu::Surface errorMask (viewportWidth, viewportHeight);
1034 tcu::LookupPrecision lookupPrec;
1035 tcu::LodPrecision lodPrec;
1036 int numFailedPixels = 0;
1037
1038 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
1039 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
1040 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1041 lookupPrec.colorMask = getCompareMask(pixelFormat);
1042 lodPrec.derivateBits = 10;
1043 lodPrec.lodBits = 8;
1044
1045 for (int gridY = 0; gridY < gridHeight; gridY++)
1046 {
1047 for (int gridX = 0; gridX < gridWidth; gridX++)
1048 {
1049 const int curX = cellWidth*gridX;
1050 const int curY = cellHeight*gridY;
1051 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1052 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1053 const int cellNdx = gridY*gridWidth + gridX;
1054
1055 getBasicTexCoord2D(texCoord, cellNdx);
1056 getReferenceParams(refParams, cellNdx);
1057
1058 // Render ideal result
1059 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1060 refTexture, &texCoord[0], refParams);
1061
1062 // Compare this cell
1063 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1064 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1065 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1066 m_texture->getTexture(), &texCoord[0], refParams,
1067 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1068 }
1069 }
1070
1071 if (numFailedPixels > 0)
1072 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1073
1074 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1075 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1076
1077 if (numFailedPixels > 0)
1078 {
1079 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1080 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1081 }
1082
1083 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1084
1085 {
1086 const bool isOk = numFailedPixels == 0;
1087 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1088 }
1089 }
1090 }
1091
1092 class Texture2DMinLodTestInstance : public Texture2DLodControlTestInstance
1093 {
1094 public:
Texture2DMinLodTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1095 Texture2DMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1096 : Texture2DLodControlTestInstance(context, testParameters)
1097 {
1098 }
1099
1100 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1101 void getReferenceParams (ReferenceParams& params, int cellNdx)
1102 {
1103 params.minLod = getMinLodForCell(cellNdx);
1104 }
1105 };
1106
1107 class Texture2DMaxLodTestInstance : public Texture2DLodControlTestInstance
1108 {
1109 public:
Texture2DMaxLodTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1110 Texture2DMaxLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1111 : Texture2DLodControlTestInstance(context, testParameters)
1112 {
1113 }
1114
1115 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1116 void getReferenceParams (ReferenceParams& params, int cellNdx)
1117 {
1118 params.maxLod = getMaxLodForCell(cellNdx);
1119 }
1120 };
1121
1122 class Texture2DBaseLevelTestInstance : public Texture2DLodControlTestInstance
1123 {
1124 public:
Texture2DBaseLevelTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1125 Texture2DBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1126 : Texture2DLodControlTestInstance(context, testParameters)
1127 , m_testParam (testParameters)
1128 {
1129 }
1130
1131 protected:
1132 const Texture2DMipmapTestCaseParameters m_testParam;
1133
getBaseLevel(int cellNdx) const1134 int getBaseLevel (int cellNdx) const
1135 {
1136 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1137 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;
1138
1139 return baseLevel;
1140 }
1141
getReferenceParams(ReferenceParams & params,int cellNdx)1142 void getReferenceParams (ReferenceParams& params, int cellNdx)
1143 {
1144 params.baseLevel = getBaseLevel(cellNdx);
1145 }
1146 };
1147
1148 class Texture2DMaxLevelTestInstance : public Texture2DLodControlTestInstance
1149 {
1150 public:
Texture2DMaxLevelTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1151 Texture2DMaxLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1152 : Texture2DLodControlTestInstance(context, testParameters)
1153 , m_testParam (testParameters)
1154 {
1155 }
1156
1157 protected:
1158 const Texture2DMipmapTestCaseParameters m_testParam;
1159
getMaxLevel(int cellNdx) const1160 int getMaxLevel (int cellNdx) const
1161 {
1162 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1163 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x82cfa4e) % numLevels;
1164
1165 return maxLevel;
1166 }
1167
getReferenceParams(ReferenceParams & params,int cellNdx)1168 void getReferenceParams (ReferenceParams& params, int cellNdx)
1169 {
1170 params.maxLevel = getMaxLevel(cellNdx);
1171 }
1172 };
1173
1174 // TextureCubeLodControlTestInstance
1175 class TextureCubeLodControlTestInstance : public TestInstance
1176 {
1177 public:
1178 typedef TextureCubeMipmapTestCaseParameters ParameterType;
1179
1180 TextureCubeLodControlTestInstance (Context& context, const ParameterType& testParameters);
1181 ~TextureCubeLodControlTestInstance (void);
1182
1183 virtual tcu::TestStatus iterate (void);
1184
1185 protected:
1186 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1187
1188 const int m_texSize;
1189
1190 private:
1191 TextureCubeLodControlTestInstance (const TextureCubeLodControlTestInstance& other);
1192 TextureCubeLodControlTestInstance& operator= (const TextureCubeLodControlTestInstance& other);
1193
1194 const ParameterType m_testParameters;
1195 tcu::Sampler::FilterMode m_minFilter;
1196 TestTextureCubeSp m_texture;
1197 TextureRenderer m_renderer;
1198 };
1199
TextureCubeLodControlTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1200 TextureCubeLodControlTestInstance::TextureCubeLodControlTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1201 : TestInstance (context)
1202 , m_texSize (64)
1203 , m_testParameters (testParameters)
1204 , m_minFilter (testParameters.minFilter)
1205 , m_texture (DE_NULL)
1206 , m_renderer (context, testParameters.sampleCount, m_texSize*2, m_texSize*2)
1207 {
1208 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1209 const int numLevels = deLog2Floor32(m_texSize)+1;
1210
1211 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(format), m_texSize));
1212
1213 // Fill texture with colored grid.
1214 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1215 {
1216 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1217 {
1218 const deUint32 step = 0xff / (numLevels-1);
1219 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1220 const deUint32 dec = 0xff - inc;
1221 deUint32 rgb = 0;
1222
1223 switch (faceNdx)
1224 {
1225 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
1226 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
1227 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
1228 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
1229 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
1230 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
1231 }
1232
1233 const deUint32 color = 0xff000000 | rgb;
1234
1235 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
1236 }
1237 }
1238
1239 m_renderer.addCubeTexture(m_texture);
1240 }
1241
~TextureCubeLodControlTestInstance(void)1242 TextureCubeLodControlTestInstance::~TextureCubeLodControlTestInstance (void)
1243 {
1244 }
1245
iterate(void)1246 tcu::TestStatus TextureCubeLodControlTestInstance::iterate (void)
1247 {
1248 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE;
1249 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE;
1250 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
1251
1252 const tcu::TextureCube& refTexture = m_texture->getTexture();
1253 const int viewportWidth = m_renderer.getRenderWidth();
1254 const int viewportHeight = m_renderer.getRenderHeight();
1255
1256 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
1257 ReferenceParams refParams (TEXTURETYPE_CUBE, sampler);
1258 vector<float> texCoord;
1259 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
1260
1261 refParams.maxLevel = deLog2Floor32(m_texSize);
1262
1263 // Compute grid.
1264 vector<tcu::IVec4> gridLayout;
1265 computeGridLayout(gridLayout, viewportWidth, viewportHeight);
1266
1267 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1268 {
1269 const int curX = gridLayout[cellNdx].x();
1270 const int curY = gridLayout[cellNdx].y();
1271 const int curW = gridLayout[cellNdx].z();
1272 const int curH = gridLayout[cellNdx].w();
1273 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1274
1275 computeQuadTexCoordCube(texCoord, cubeFace);
1276 getReferenceParams(refParams, cellNdx);
1277
1278 // Render with GL.
1279 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1280 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel);
1281 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1282 }
1283
1284 // Render reference and compare
1285 {
1286 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1287 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1288 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
1289 tcu::Surface errorMask (viewportWidth, viewportHeight);
1290 int numFailedPixels = 0;
1291 tcu::LookupPrecision lookupPrec;
1292 tcu::LodPrecision lodPrec;
1293
1294 // Params for rendering reference
1295 refParams.sampler = util::createSampler(wrapS, wrapT, m_testParameters.minFilter, magFilter);
1296 refParams.sampler.seamlessCubeMap = true;
1297 refParams.lodMode = LODMODE_EXACT;
1298
1299 // Comparison parameters
1300 lookupPrec.colorMask = getCompareMask(pixelFormat);
1301 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, IVec4(0)));
1302 lookupPrec.coordBits = tcu::IVec3(10);
1303 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
1304 lodPrec.derivateBits = 10;
1305 lodPrec.lodBits = 6;
1306
1307 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1308 {
1309 const int curX = gridLayout[cellNdx].x();
1310 const int curY = gridLayout[cellNdx].y();
1311 const int curW = gridLayout[cellNdx].z();
1312 const int curH = gridLayout[cellNdx].w();
1313 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1314
1315 computeQuadTexCoordCube(texCoord, cubeFace);
1316 getReferenceParams(refParams, cellNdx);
1317
1318 // Render ideal reference.
1319 {
1320 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
1321 sampleTexture(idealDst, refTexture, &texCoord[0], refParams);
1322 }
1323
1324 // Compare this cell
1325 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1326 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1327 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1328 m_texture->getTexture(), &texCoord[0], refParams,
1329 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1330 }
1331
1332 if (numFailedPixels > 0)
1333 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1334
1335 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1336 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1337
1338 if (numFailedPixels > 0)
1339 {
1340 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1341 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1342 }
1343
1344 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1345
1346 {
1347 const bool isOk = numFailedPixels == 0;
1348 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1349 }
1350 }
1351 }
1352
1353 class TextureCubeMinLodTestInstance : public TextureCubeLodControlTestInstance
1354 {
1355 public:
TextureCubeMinLodTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1356 TextureCubeMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1357 : TextureCubeLodControlTestInstance(context, testParameters)
1358 {
1359 }
1360
1361 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1362 void getReferenceParams (ReferenceParams& params, int cellNdx)
1363 {
1364 params.minLod = getMinLodForCell(cellNdx);
1365 }
1366 };
1367
1368 class TextureCubeMaxLodTestInstance : public TextureCubeLodControlTestInstance
1369 {
1370 public:
TextureCubeMaxLodTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1371 TextureCubeMaxLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1372 : TextureCubeLodControlTestInstance(context, testParameters)
1373 {
1374 }
1375
1376 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1377 void getReferenceParams (ReferenceParams& params, int cellNdx)
1378 {
1379 params.maxLod = getMaxLodForCell(cellNdx);
1380 }
1381 };
1382
1383 class TextureCubeBaseLevelTestInstance : public TextureCubeLodControlTestInstance
1384 {
1385 public:
TextureCubeBaseLevelTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1386 TextureCubeBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1387 : TextureCubeLodControlTestInstance(context, testParameters)
1388 , m_testParam (testParameters)
1389 {
1390 }
1391
1392 protected:
1393 const TextureCubeMipmapTestCaseParameters m_testParam;
1394
getBaseLevel(int cellNdx) const1395 int getBaseLevel (int cellNdx) const
1396 {
1397 const int numLevels = deLog2Floor32(m_texSize)+1;
1398 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels;
1399
1400 return baseLevel;
1401 }
1402
getReferenceParams(ReferenceParams & params,int cellNdx)1403 void getReferenceParams (ReferenceParams& params, int cellNdx)
1404 {
1405 params.baseLevel = getBaseLevel(cellNdx);
1406 }
1407 };
1408
1409 class TextureCubeMaxLevelTestInstance : public TextureCubeLodControlTestInstance
1410 {
1411 public:
TextureCubeMaxLevelTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1412 TextureCubeMaxLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1413 : TextureCubeLodControlTestInstance(context, testParameters)
1414 , m_testParam (testParameters)
1415 {
1416 }
1417
1418 protected:
1419 const TextureCubeMipmapTestCaseParameters m_testParam;
getMaxLevel(int cellNdx) const1420 int getMaxLevel (int cellNdx) const
1421 {
1422 const int numLevels = deLog2Floor32(m_texSize)+1;
1423 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x974e21) % numLevels;
1424
1425 return maxLevel;
1426 }
1427
getReferenceParams(ReferenceParams & params,int cellNdx)1428 void getReferenceParams (ReferenceParams& params, int cellNdx)
1429 {
1430 params.maxLevel = getMaxLevel(cellNdx);
1431 }
1432 };
1433
1434 // Texture3DLodControlTestInstance
1435 class Texture3DLodControlTestInstance : public TestInstance
1436 {
1437 public:
1438 typedef Texture3DMipmapTestCaseParameters ParameterType;
1439
1440 Texture3DLodControlTestInstance (Context& context, const ParameterType& testParameters);
1441 ~Texture3DLodControlTestInstance (void);
1442
1443 virtual tcu::TestStatus iterate (void);
1444
1445 protected:
1446 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1447
1448 const int m_texWidth;
1449 const int m_texHeight;
1450 const int m_texDepth;
1451
1452 private:
1453 Texture3DLodControlTestInstance (const Texture3DLodControlTestInstance& other);
1454 Texture3DLodControlTestInstance& operator= (const Texture3DLodControlTestInstance& other);
1455
1456 const ParameterType m_testParameters;
1457 tcu::Sampler::FilterMode m_minFilter;
1458 TestTexture3DSp m_texture;
1459 TextureRenderer m_renderer;
1460 };
1461
Texture3DLodControlTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1462 Texture3DLodControlTestInstance::Texture3DLodControlTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1463 : TestInstance (context)
1464 , m_texWidth (32)
1465 , m_texHeight (32)
1466 , m_texDepth (32)
1467 , m_testParameters (testParameters)
1468 , m_minFilter (testParameters.minFilter)
1469 , m_texture (DE_NULL)
1470 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4)
1471 {
1472 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1473 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format));
1474 const tcu::Vec4& cScale = fmtInfo.lookupScale;
1475 const tcu::Vec4& cBias = fmtInfo.lookupBias;
1476 const int numLevels = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1;
1477
1478 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(format), m_texWidth, m_texHeight, m_texDepth));
1479
1480 // Fill texture with colored grid.
1481 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1482 {
1483 const deUint32 step = 0xff / (numLevels-1);
1484 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1485 const deUint32 dec = 0xff - inc;
1486 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
1487 const deUint32 color = 0xff000000 | rgb;
1488
1489 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
1490 }
1491
1492 m_renderer.add3DTexture(m_texture);
1493 }
1494
~Texture3DLodControlTestInstance(void)1495 Texture3DLodControlTestInstance::~Texture3DLodControlTestInstance (void)
1496 {
1497 }
1498
iterate(void)1499 tcu::TestStatus Texture3DLodControlTestInstance::iterate (void)
1500 {
1501 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE;
1502 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE;
1503 const tcu::Sampler::WrapMode wrapR = Sampler::CLAMP_TO_EDGE;
1504 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
1505
1506 const tcu::Texture3D& refTexture = m_texture->getTexture();
1507 const tcu::TextureFormat& texFmt = refTexture.getFormat();
1508 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1509 const int viewportWidth = m_renderer.getRenderWidth();
1510 const int viewportHeight = m_renderer.getRenderHeight();
1511
1512 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
1513 ReferenceParams refParams (TEXTURETYPE_3D, sampler);
1514 vector<float> texCoord;
1515 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
1516
1517 // Viewport is divided into 4x4 grid.
1518 const int gridWidth = 4;
1519 const int gridHeight = 4;
1520 const int cellWidth = viewportWidth / gridWidth;
1521 const int cellHeight = viewportHeight / gridHeight;
1522
1523 // Sampling parameters.
1524 refParams.sampler = util::createSampler(wrapS, wrapT, wrapR, m_testParameters.minFilter, magFilter);
1525 refParams.samplerType = getSamplerType(texFmt);
1526 refParams.colorBias = fmtInfo.lookupBias;
1527 refParams.colorScale = fmtInfo.lookupScale;
1528 refParams.maxLevel = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth));
1529
1530 // Render cells.
1531 for (int gridY = 0; gridY < gridHeight; gridY++)
1532 {
1533 for (int gridX = 0; gridX < gridWidth; gridX++)
1534 {
1535 const int curX = cellWidth*gridX;
1536 const int curY = cellHeight*gridY;
1537 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1538 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1539 const int cellNdx = gridY*gridWidth + gridX;
1540
1541 // Compute texcoord.
1542 getBasicTexCoord3D(texCoord, cellNdx);
1543
1544 getReferenceParams(refParams,cellNdx);
1545 //Render
1546 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1547 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel);
1548 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1549 }
1550 }
1551
1552 // Compare and log
1553 {
1554 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1555 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1556 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
1557 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
1558 tcu::Surface errorMask (viewportWidth, viewportHeight);
1559 tcu::LookupPrecision lookupPrec;
1560 tcu::LodPrecision lodPrec;
1561 int numFailedPixels = 0;
1562
1563 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
1564 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
1565 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1566 lookupPrec.colorMask = getCompareMask(pixelFormat);
1567 lodPrec.derivateBits = 10;
1568 lodPrec.lodBits = 8;
1569
1570 for (int gridY = 0; gridY < gridHeight; gridY++)
1571 {
1572 for (int gridX = 0; gridX < gridWidth; gridX++)
1573 {
1574 const int curX = cellWidth*gridX;
1575 const int curY = cellHeight*gridY;
1576 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1577 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1578 const int cellNdx = gridY*gridWidth + gridX;
1579
1580 getBasicTexCoord3D(texCoord, cellNdx);
1581 getReferenceParams(refParams, cellNdx);
1582
1583 // Render ideal result
1584 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1585 refTexture, &texCoord[0], refParams);
1586
1587 // Compare this cell
1588 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1589 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1590 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1591 m_texture->getTexture(), &texCoord[0], refParams,
1592 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1593 }
1594 }
1595
1596 if (numFailedPixels > 0)
1597 {
1598 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1599 }
1600
1601 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1602 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1603
1604 if (numFailedPixels > 0)
1605 {
1606 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1607 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1608 }
1609
1610 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1611
1612 {
1613 const bool isOk = numFailedPixels == 0;
1614 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1615 }
1616 }
1617 }
1618
1619 class Texture3DMinLodTestInstance : public Texture3DLodControlTestInstance
1620 {
1621 public:
Texture3DMinLodTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1622 Texture3DMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1623 : Texture3DLodControlTestInstance(context, testParameters)
1624 {
1625 }
1626
1627 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1628 void getReferenceParams (ReferenceParams& params, int cellNdx)
1629 {
1630 params.minLod = getMinLodForCell(cellNdx);
1631 }
1632 };
1633
1634 class Texture3DMaxLodTestInstance : public Texture3DLodControlTestInstance
1635 {
1636 public:
Texture3DMaxLodTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1637 Texture3DMaxLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1638 : Texture3DLodControlTestInstance(context, testParameters)
1639 {
1640 }
1641
1642 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1643 void getReferenceParams (ReferenceParams& params, int cellNdx)
1644 {
1645 params.maxLod = getMaxLodForCell(cellNdx);
1646 }
1647 };
1648
1649 class Texture3DBaseLevelTestInstance : public Texture3DLodControlTestInstance
1650 {
1651 public:
Texture3DBaseLevelTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1652 Texture3DBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1653 : Texture3DLodControlTestInstance(context, testParameters)
1654 ,m_testParam (testParameters)
1655 {
1656 }
1657
1658 protected:
1659 const Texture3DMipmapTestCaseParameters m_testParam;
1660
getBaseLevel(int cellNdx) const1661 int getBaseLevel (int cellNdx) const
1662 {
1663 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
1664 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;
1665
1666 return baseLevel;
1667 }
1668
getReferenceParams(ReferenceParams & params,int cellNdx)1669 void getReferenceParams (ReferenceParams& params, int cellNdx)
1670 {
1671 params.baseLevel = getBaseLevel(cellNdx);
1672 }
1673 };
1674
1675 class Texture3DMaxLevelTestInstance : public Texture3DLodControlTestInstance
1676 {
1677 public:
Texture3DMaxLevelTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1678 Texture3DMaxLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1679 : Texture3DLodControlTestInstance(context, testParameters)
1680 ,m_testParam (testParameters)
1681 {
1682 }
1683
1684 protected:
1685 const Texture3DMipmapTestCaseParameters m_testParam;
1686
getMaxLevel(int cellNdx) const1687 int getMaxLevel (int cellNdx) const
1688 {
1689 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
1690 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x9111e7) % numLevels;
1691
1692 return maxLevel;
1693 }
1694
getReferenceParams(ReferenceParams & params,int cellNdx)1695 void getReferenceParams (ReferenceParams& params, int cellNdx)
1696 {
1697 params.maxLevel = getMaxLevel(cellNdx);
1698 }
1699 };
1700
populateTextureMipmappingTests(tcu::TestCaseGroup * textureMipmappingTests)1701 void populateTextureMipmappingTests (tcu::TestCaseGroup* textureMipmappingTests)
1702 {
1703 tcu::TestContext& testCtx = textureMipmappingTests->getTestContext();
1704
1705 static const struct
1706 {
1707 const char* name;
1708 const Sampler::WrapMode mode;
1709 } wrapModes[] =
1710 {
1711 { "clamp", Sampler::CLAMP_TO_EDGE },
1712 { "repeat", Sampler::REPEAT_GL },
1713 { "mirror", Sampler::MIRRORED_REPEAT_GL }
1714 };
1715
1716 static const struct
1717 {
1718 const char* name;
1719 const Sampler::FilterMode mode;
1720 } minFilterModes[] =
1721 {
1722 { "nearest_nearest", Sampler::NEAREST_MIPMAP_NEAREST },
1723 { "linear_nearest", Sampler::LINEAR_MIPMAP_NEAREST },
1724 { "nearest_linear", Sampler::NEAREST_MIPMAP_LINEAR },
1725 { "linear_linear", Sampler::LINEAR_MIPMAP_LINEAR }
1726 };
1727
1728 static const struct
1729 {
1730 const char* name;
1731 const Sampler::FilterMode mode;
1732 } magFilterModes[] =
1733 {
1734 { "nearest", Sampler::NEAREST},
1735 { "linear", Sampler::LINEAR}
1736 };
1737
1738
1739 static const struct
1740 {
1741 const CoordType type;
1742 const char* name;
1743 const char* desc;
1744 } coordTypes[] =
1745 {
1746 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
1747 { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" },
1748 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }
1749 };
1750
1751 static const struct
1752 {
1753 const char* name;
1754 const int width;
1755 const int height;
1756 } tex2DSizes[] =
1757 {
1758 { DE_NULL, 64, 64 }, // Default.
1759 { "npot", 63, 57 },
1760 { "non_square", 32, 64 }
1761 };
1762
1763 static const struct
1764 {
1765 const char* name;
1766 const int width;
1767 const int height;
1768 const int depth;
1769 } tex3DSizes[] =
1770 {
1771 { DE_NULL, 32, 32, 32 }, // Default.
1772 { "npot", 33, 29, 27 }
1773 };
1774
1775 const int cubeMapSize = 64;
1776
1777 static const struct
1778 {
1779 const CoordType type;
1780 const char* name;
1781 const char* desc;
1782 } cubeCoordTypes[] =
1783 {
1784 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
1785 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" },
1786 { COORDTYPE_BASIC_BIAS, "bias", "User-supplied bias value" }
1787 };
1788
1789 // 2D cases.
1790 {
1791 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d", "2D Mipmap Filtering"));
1792
1793 de::MovePtr<tcu::TestCaseGroup> biasGroup2D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
1794 de::MovePtr<tcu::TestCaseGroup> minLodGroup2D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
1795 de::MovePtr<tcu::TestCaseGroup> maxLodGroup2D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
1796 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup2D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
1797 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup2D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
1798
1799 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
1800 {
1801 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));
1802
1803 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1804 {
1805 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
1806 {
1807 // Add non_square variants to basic cases only.
1808 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1;
1809
1810 for (int size = 0; size < sizeEnd; size++)
1811 {
1812 Texture2DMipmapTestCaseParameters testParameters;
1813
1814 testParameters.coordType = coordTypes[coordType].type;
1815 testParameters.minFilter = minFilterModes[minFilter].mode;
1816 testParameters.wrapS = wrapModes[wrapMode].mode;
1817 testParameters.wrapT = wrapModes[wrapMode].mode;
1818 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA)
1819 testParameters.width = tex2DSizes[size].width;
1820 testParameters.height = tex2DSizes[size].height;
1821 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1822
1823 std::ostringstream name;
1824 name << minFilterModes[minFilter].name
1825 << "_" << wrapModes[wrapMode].name;
1826
1827 if (tex2DSizes[size].name)
1828 name << "_" << tex2DSizes[size].name;
1829
1830 coordTypeGroup->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
1831 }
1832 }
1833 }
1834
1835 group2D->addChild(coordTypeGroup.release());
1836 }
1837
1838 // 2D bias variants.
1839 {
1840 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1841 {
1842 Texture2DMipmapTestCaseParameters testParameters;
1843
1844 testParameters.coordType = COORDTYPE_BASIC_BIAS;
1845 testParameters.minFilter = minFilterModes[minFilter].mode;
1846 testParameters.magFilter = minFilterModes[minFilter].mode;
1847 testParameters.wrapS = Sampler::REPEAT_GL;
1848 testParameters.wrapT = Sampler::REPEAT_GL;
1849 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA)
1850 testParameters.width = tex2DSizes[0].width;
1851 testParameters.height = tex2DSizes[0].height;
1852 testParameters.programs.push_back(PROGRAM_2D_FLOAT_BIAS);
1853
1854 std::ostringstream name;
1855 name << minFilterModes[minFilter].name;
1856
1857 biasGroup2D->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
1858 }
1859 }
1860
1861 // 2D LOD controls.
1862 {
1863 // MIN_LOD
1864 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1865 {
1866 Texture2DMipmapTestCaseParameters testParameters;
1867 testParameters.minFilter = minFilterModes[minFilter].mode;
1868 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1869
1870 minLodGroup2D->addChild(new TextureTestCase<Texture2DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1871 }
1872
1873 // MAX_LOD
1874 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1875 {
1876 Texture2DMipmapTestCaseParameters testParameters;
1877 testParameters.minFilter = minFilterModes[minFilter].mode;
1878 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1879
1880 maxLodGroup2D->addChild(new TextureTestCase<Texture2DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1881 }
1882 }
1883
1884 {
1885 // BASE_LEVEL
1886 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1887 {
1888 Texture2DMipmapTestCaseParameters testParameters;
1889 testParameters.minFilter = minFilterModes[minFilter].mode;
1890 testParameters.minFilterName = minFilterModes[minFilter].name;
1891 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1892
1893 baseLevelGroup2D->addChild(new TextureTestCase<Texture2DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1894 }
1895
1896 // MAX_LEVEL
1897 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1898 {
1899 Texture2DMipmapTestCaseParameters testParameters;
1900 testParameters.minFilter = minFilterModes[minFilter].mode;
1901 testParameters.minFilterName = minFilterModes[minFilter].name;
1902 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1903
1904 maxLevelGroup2D->addChild(new TextureTestCase<Texture2DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1905 }
1906 }
1907
1908 group2D->addChild(biasGroup2D.release());
1909 group2D->addChild(minLodGroup2D.release());
1910 group2D->addChild(maxLodGroup2D.release());
1911 group2D->addChild(baseLevelGroup2D.release());
1912 group2D->addChild(maxLevelGroup2D.release());
1913
1914 textureMipmappingTests->addChild(group2D.release());
1915 }
1916
1917 // Cubemap cases.
1918 {
1919 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cubemap", "Cube Mipmap Filtering"));
1920
1921 de::MovePtr<tcu::TestCaseGroup> minLodGroupCube (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
1922 de::MovePtr<tcu::TestCaseGroup> maxLodGroupCube (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
1923 de::MovePtr<tcu::TestCaseGroup> baseLevelGroupCube (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
1924 de::MovePtr<tcu::TestCaseGroup> maxLevelGroupCube (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
1925
1926 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
1927 {
1928 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc));
1929
1930 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1931 {
1932 for (int magFilter = 0; magFilter < DE_LENGTH_OF_ARRAY(magFilterModes); magFilter++)
1933 {
1934 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
1935 {
1936 TextureCubeMipmapTestCaseParameters testParameters;
1937
1938 testParameters.coordType = cubeCoordTypes[coordType].type;
1939 testParameters.minFilter = minFilterModes[minFilter].mode;
1940 testParameters.magFilter = magFilterModes[magFilter].mode;
1941 testParameters.minFilterName = minFilterModes[minFilter].name;
1942 testParameters.wrapS = wrapModes[wrapMode].mode;
1943 testParameters.wrapT = wrapModes[wrapMode].mode;
1944 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1945 testParameters.size = cubeMapSize;
1946 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1947 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT_BIAS);
1948
1949 std::ostringstream name;
1950 name << minFilterModes[minFilter].name
1951 << "_" << magFilterModes[magFilter].name
1952 << "_" << wrapModes[wrapMode].name;
1953
1954 coordTypeGroup->addChild(new TextureTestCase<TextureCubeMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
1955 }
1956 }
1957 }
1958
1959 groupCube->addChild(coordTypeGroup.release());
1960 }
1961
1962 // Cubemap LOD controls.
1963 {
1964 // MIN_LOD
1965 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1966 {
1967 TextureCubeMipmapTestCaseParameters testParameters;
1968 testParameters.minFilter = minFilterModes[minFilter].mode;
1969 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1970
1971 minLodGroupCube->addChild(new TextureTestCase<TextureCubeMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1972 }
1973
1974 // MAX_LOD
1975 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1976 {
1977 TextureCubeMipmapTestCaseParameters testParameters;
1978 testParameters.minFilter = minFilterModes[minFilter].mode;
1979 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1980
1981 maxLodGroupCube->addChild(new TextureTestCase<TextureCubeMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1982 }
1983 }
1984
1985 {
1986 // BASE_LEVEL
1987 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1988 {
1989 TextureCubeMipmapTestCaseParameters testParameters;
1990 testParameters.minFilter = minFilterModes[minFilter].mode;
1991 testParameters.minFilterName = minFilterModes[minFilter].name;
1992 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1993
1994 baseLevelGroupCube->addChild(new TextureTestCase<TextureCubeBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
1995 }
1996
1997 // MAX_LEVEL
1998 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
1999 {
2000 TextureCubeMipmapTestCaseParameters testParameters;
2001 testParameters.minFilter = minFilterModes[minFilter].mode;
2002 testParameters.minFilterName = minFilterModes[minFilter].name;
2003 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
2004
2005 maxLevelGroupCube->addChild(new TextureTestCase<TextureCubeMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2006 }
2007 }
2008
2009 groupCube->addChild(minLodGroupCube.release());
2010 groupCube->addChild(maxLodGroupCube.release());
2011 groupCube->addChild(baseLevelGroupCube.release());
2012 groupCube->addChild(maxLevelGroupCube.release());
2013
2014 textureMipmappingTests->addChild(groupCube.release());
2015 }
2016
2017 // 3D cases.
2018 {
2019 de::MovePtr<tcu::TestCaseGroup> group3D (new tcu::TestCaseGroup(testCtx, "3d", "3D Mipmap Filtering"));
2020
2021 de::MovePtr<tcu::TestCaseGroup> biasGroup3D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
2022 de::MovePtr<tcu::TestCaseGroup> minLodGroup3D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
2023 de::MovePtr<tcu::TestCaseGroup> maxLodGroup3D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
2024 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup3D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
2025 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup3D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
2026
2027 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
2028 {
2029 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));
2030
2031 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2032 {
2033 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
2034 {
2035 // Add other size variants to basic cases only.
2036 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1;
2037
2038 Texture3DMipmapTestCaseParameters testParameters;
2039
2040 testParameters.coordType = coordTypes[coordType].type;
2041 testParameters.minFilter = minFilterModes[minFilter].mode;
2042 testParameters.minFilterName = minFilterModes[minFilter].name;
2043 testParameters.wrapR = wrapModes[wrapMode].mode;
2044 testParameters.wrapS = wrapModes[wrapMode].mode;
2045 testParameters.wrapT = wrapModes[wrapMode].mode;
2046 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
2047 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2048
2049 for (int size = 0; size < sizeEnd; size++)
2050 {
2051 testParameters.width = tex3DSizes[size].width;
2052 testParameters.height = tex3DSizes[size].height;
2053 testParameters.depth = tex3DSizes[size].depth;
2054
2055 std::ostringstream name;
2056 name << minFilterModes[minFilter].name
2057 << "_" << wrapModes[wrapMode].name;
2058
2059 if (tex3DSizes[size].name)
2060 name << "_" << tex3DSizes[size].name;
2061
2062 coordTypeGroup->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
2063 }
2064 }
2065 }
2066
2067 group3D->addChild(coordTypeGroup.release());
2068 }
2069
2070 // 3D bias variants.
2071 {
2072 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2073 {
2074 Texture3DMipmapTestCaseParameters testParameters;
2075 testParameters.coordType = COORDTYPE_BASIC_BIAS;
2076 testParameters.minFilter = minFilterModes[minFilter].mode;
2077 testParameters.wrapR = Sampler::REPEAT_GL;
2078 testParameters.wrapS = Sampler::REPEAT_GL;
2079 testParameters.wrapT = Sampler::REPEAT_GL;
2080 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
2081 testParameters.width = tex3DSizes[0].width;
2082 testParameters.height = tex3DSizes[0].height;
2083 testParameters.depth = tex3DSizes[0].depth;
2084
2085 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2086 testParameters.programs.push_back(PROGRAM_3D_FLOAT_BIAS);
2087
2088 biasGroup3D->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2089 }
2090 }
2091
2092 // 3D LOD controls.
2093 {
2094 // MIN_LOD
2095 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2096 {
2097 Texture3DMipmapTestCaseParameters testParameters;
2098 testParameters.minFilter = minFilterModes[minFilter].mode;
2099 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2100
2101 minLodGroup3D->addChild(new TextureTestCase<Texture3DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2102 }
2103
2104 // MAX_LOD
2105 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2106 {
2107 Texture3DMipmapTestCaseParameters testParameters;
2108 testParameters.minFilter = minFilterModes[minFilter].mode;
2109 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2110
2111 maxLodGroup3D->addChild(new TextureTestCase<Texture3DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2112 }
2113 }
2114
2115 {
2116 // BASE_LEVEL
2117 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2118 {
2119 Texture3DMipmapTestCaseParameters testParameters;
2120 testParameters.minFilter = minFilterModes[minFilter].mode;
2121 testParameters.minFilterName = minFilterModes[minFilter].name;
2122 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2123
2124 baseLevelGroup3D->addChild(new TextureTestCase<Texture3DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2125 }
2126
2127 // MAX_LEVEL
2128 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
2129 {
2130 Texture3DMipmapTestCaseParameters testParameters;
2131 testParameters.minFilter = minFilterModes[minFilter].mode;
2132 testParameters.minFilterName = minFilterModes[minFilter].name;
2133 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
2134
2135 maxLevelGroup3D->addChild(new TextureTestCase<Texture3DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
2136 }
2137 }
2138
2139 group3D->addChild(biasGroup3D.release());
2140 group3D->addChild(minLodGroup3D.release());
2141 group3D->addChild(maxLodGroup3D.release());
2142 group3D->addChild(baseLevelGroup3D.release());
2143 group3D->addChild(maxLevelGroup3D.release());
2144
2145 textureMipmappingTests->addChild(group3D.release());
2146 }
2147 }
2148
2149 } // anonymous
2150
createTextureMipmappingTests(tcu::TestContext & testCtx)2151 tcu::TestCaseGroup* createTextureMipmappingTests (tcu::TestContext& testCtx)
2152 {
2153 return createTestGroup(testCtx, "mipmap", "Texture mipmapping tests.", populateTextureMipmappingTests);
2154 }
2155
2156 } // texture
2157 } // vkt
2158