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 "tcuCommandLine.hpp"
39 #include "vkImageUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkImageWithMemory.hpp"
42 #include "vkBufferWithMemory.hpp"
43 #include "vkObjUtil.hpp"
44 #include "vkCmdUtil.hpp"
45 #include "vkBarrierUtil.hpp"
46 #include "vkBuilderUtil.hpp"
47 #include "vktTestGroupUtil.hpp"
48 #include "vktTextureTestUtil.hpp"
49 #include "vktCustomInstancesDevices.hpp"
50
51 #include <memory>
52
53 using namespace vk;
54
55 namespace vkt
56 {
57 namespace texture
58 {
59 namespace
60 {
61
62 using std::string;
63 using std::vector;
64 using tcu::TestLog;
65 using tcu::Vec2;
66 using tcu::Vec3;
67 using tcu::Vec4;
68 using tcu::IVec3;
69 using tcu::IVec4;
70 using tcu::Sampler;
71 using tcu::TextureFormat;
72 using namespace texture::util;
73 using namespace glu::TextureTestUtil;
74
getMinLodForCell(int cellNdx)75 float getMinLodForCell (int cellNdx)
76 {
77 static const float s_values[] =
78 {
79 1.0f,
80 3.5f,
81 2.0f,
82 -2.0f,
83 0.0f,
84 3.0f,
85 10.0f,
86 4.8f,
87 5.8f,
88 5.7f,
89 -1.9f,
90 4.0f,
91 6.5f,
92 7.1f,
93 -1e10,
94 1000.f
95 };
96 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
97 }
98
getMaxLodForCell(int cellNdx)99 float getMaxLodForCell (int cellNdx)
100 {
101 static const float s_values[] =
102 {
103 0.0f,
104 0.2f,
105 0.7f,
106 0.4f,
107 1.3f,
108 0.0f,
109 0.5f,
110 1.2f,
111 -2.0f,
112 1.0f,
113 0.1f,
114 0.3f,
115 2.7f,
116 1.2f,
117 10.0f,
118 -1000.f,
119 1e10f
120 };
121 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)];
122 }
123
124 enum CoordType
125 {
126 COORDTYPE_BASIC, //!< texCoord = translateScale(position).
127 COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values.
128 COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position).
129 COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1
130
131 COORDTYPE_LAST
132 };
133
134 struct TextureMipmapCommonTestCaseParameters
135 {
136 TextureMipmapCommonTestCaseParameters (void);
137 CoordType coordType;
138 const char* minFilterName;
139 };
140
TextureMipmapCommonTestCaseParameters(void)141 TextureMipmapCommonTestCaseParameters::TextureMipmapCommonTestCaseParameters (void)
142 : coordType (COORDTYPE_BASIC)
143 , minFilterName (NULL)
144 {
145 }
146
147 struct Texture2DMipmapTestCaseParameters : public Texture2DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
148 {
149 };
150
151 struct TextureCubeMipmapTestCaseParameters : public TextureCubeTestCaseParameters, public TextureMipmapCommonTestCaseParameters
152 {
153 };
154
155 struct Texture3DMipmapTestCaseParameters : public Texture3DTestCaseParameters, public TextureMipmapCommonTestCaseParameters
156 {
157 };
158
159 // Texture2DMipmapTestInstance
160 class Texture2DMipmapTestInstance : public TestInstance
161 {
162 public:
163 typedef Texture2DMipmapTestCaseParameters ParameterType;
164
165 Texture2DMipmapTestInstance (Context& context, const ParameterType& testParameters);
166 ~Texture2DMipmapTestInstance (void);
167
168 virtual tcu::TestStatus iterate (void);
169
170 private:
171 Texture2DMipmapTestInstance (const Texture2DMipmapTestInstance& other);
172 Texture2DMipmapTestInstance& operator= (const Texture2DMipmapTestInstance& other);
173
174 const ParameterType m_testParameters;
175 TestTexture2DSp m_texture;
176 TextureRenderer m_renderer;
177 };
178
Texture2DMipmapTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)179 Texture2DMipmapTestInstance::Texture2DMipmapTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
180 : TestInstance (context)
181 , m_testParameters (testParameters)
182 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
183 {
184 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
185
186 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height));
187
188 const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1;
189
190 // Fill texture with colored grid.
191 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
192 {
193 const deUint32 step = 0xff / (numLevels-1);
194 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
195 const deUint32 dec = 0xff - inc;
196 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
197 const deUint32 color = 0xff000000 | rgb;
198
199 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
200 }
201
202 // Upload texture data.
203 m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
204 }
205
~Texture2DMipmapTestInstance(void)206 Texture2DMipmapTestInstance::~Texture2DMipmapTestInstance (void)
207 {
208 }
209
getBasicTexCoord2D(std::vector<float> & dst,int cellNdx)210 static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx)
211 {
212 static const struct
213 {
214 const Vec2 bottomLeft;
215 const Vec2 topRight;
216 } s_basicCoords[] =
217 {
218 { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) },
219 { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) },
220 { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) },
221 { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) },
222
223 { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) },
224 { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) },
225 { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) },
226 { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) },
227
228 { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) },
229 { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) },
230 { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) },
231 { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) },
232
233 { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) },
234 { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) },
235 { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) },
236 { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) },
237 };
238
239 DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords)));
240
241 const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft;
242 const Vec2& topRight = s_basicCoords[cellNdx].topRight;
243
244 computeQuadTexCoord2D(dst, bottomLeft, topRight);
245 }
246
getBasicTexCoord2DImageViewMinLodIntTexCoord(std::vector<float> & dst)247 static void getBasicTexCoord2DImageViewMinLodIntTexCoord (std::vector<float>& dst)
248 {
249 computeQuadTexCoord2D(dst, Vec2(0.0f), Vec2(1.0f));
250 }
251
getAffineTexCoord2D(std::vector<float> & dst,int cellNdx)252 static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx)
253 {
254 // Use basic coords as base.
255 getBasicTexCoord2D(dst, cellNdx);
256
257 // Rotate based on cell index.
258 const float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f);
259 const tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle);
260
261 // Second and third row are sheared.
262 const float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f;
263 const tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f));
264
265 const tcu::Mat2 transform = rotMatrix * shearMatrix;
266 const Vec2 p0 = transform * Vec2(dst[0], dst[1]);
267 const Vec2 p1 = transform * Vec2(dst[2], dst[3]);
268 const Vec2 p2 = transform * Vec2(dst[4], dst[5]);
269 const Vec2 p3 = transform * Vec2(dst[6], dst[7]);
270
271 dst[0] = p0.x(); dst[1] = p0.y();
272 dst[2] = p1.x(); dst[3] = p1.y();
273 dst[4] = p2.x(); dst[5] = p2.y();
274 dst[6] = p3.x(); dst[7] = p3.y();
275 }
276
iterate(void)277 tcu::TestStatus Texture2DMipmapTestInstance::iterate (void)
278 {
279 const Sampler::FilterMode magFilter = Sampler::NEAREST;
280 const int viewportWidth = m_renderer.getRenderWidth();
281 const int viewportHeight = m_renderer.getRenderHeight();
282
283 ReferenceParams refParams (TEXTURETYPE_2D);
284 vector<float> texCoord;
285
286 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
287 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
288
289 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
290
291 // Viewport is divided into 4x4 grid.
292 const int gridWidth = 4;
293 const int gridHeight = 4;
294 const int cellWidth = viewportWidth / gridWidth;
295 const int cellHeight = viewportHeight / gridHeight;
296
297 // Sampling parameters.
298 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
299 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format));
300 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
301 refParams.lodMode = LODMODE_EXACT; // Use ideal lod.
302
303 // Bias values.
304 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
305
306 // Projection values.
307 static const Vec4 s_projections[] =
308 {
309 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
310 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
311 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
312 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
313 };
314
315 // Render cells.
316 for (int gridY = 0; gridY < gridHeight; gridY++)
317 {
318 for (int gridX = 0; gridX < gridWidth; gridX++)
319 {
320 const int curX = cellWidth*gridX;
321 const int curY = cellHeight*gridY;
322 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
323 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
324 const int cellNdx = gridY*gridWidth + gridX;
325
326 // Compute texcoord.
327 switch (m_testParameters.coordType)
328 {
329 case COORDTYPE_BASIC_BIAS: // Fall-through.
330 case COORDTYPE_PROJECTED:
331 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
332 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
333 default: DE_ASSERT(DE_FALSE);
334 }
335
336 if (isProjected)
337 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
338
339 if (useLodBias)
340 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
341
342 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
343 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
344 }
345 }
346
347 // Compare and log.
348 {
349 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
350 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
351 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
352 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
353 tcu::Surface errorMask (viewportWidth, viewportHeight);
354 tcu::LookupPrecision lookupPrec;
355 tcu::LodPrecision lodPrec;
356 int numFailedPixels = 0;
357
358 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
359 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
360 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
361 lookupPrec.colorMask = getCompareMask(pixelFormat);
362 lodPrec.derivateBits = 10;
363 lodPrec.lodBits = isProjected ? 6 : 8;
364
365 for (int gridY = 0; gridY < gridHeight; gridY++)
366 {
367 for (int gridX = 0; gridX < gridWidth; gridX++)
368 {
369 const int curX = cellWidth*gridX;
370 const int curY = cellHeight*gridY;
371 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
372 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
373 const int cellNdx = gridY*gridWidth + gridX;
374
375 // Compute texcoord.
376 switch (m_testParameters.coordType)
377 {
378 case COORDTYPE_BASIC_BIAS: // Fall-through.
379 case COORDTYPE_PROJECTED:
380 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break;
381 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break;
382 default: DE_ASSERT(DE_FALSE);
383 }
384
385 if (isProjected)
386 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
387
388 if (useLodBias)
389 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
390
391 // Render ideal result
392 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
393 m_texture->getTexture(), &texCoord[0], refParams);
394
395 // Compare this cell
396 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
397 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
398 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
399 m_texture->getTexture(), &texCoord[0], refParams,
400 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
401 }
402 }
403
404 if (numFailedPixels > 0)
405 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
406
407 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
408 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
409
410 if (numFailedPixels > 0)
411 {
412 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
413 << TestLog::Image("ErrorMask", "Error mask", errorMask);
414 }
415
416 m_context.getTestContext().getLog() << TestLog::EndImageSet;
417
418 {
419 const bool isOk = numFailedPixels == 0;
420 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
421 }
422 }
423 }
424
425 // TextureCubeMipmapTestInstance
426 class TextureCubeMipmapTestInstance : public TestInstance
427 {
428 public:
429 typedef TextureCubeMipmapTestCaseParameters ParameterType;
430
431 TextureCubeMipmapTestInstance (Context& context, const ParameterType& testParameters);
432 ~TextureCubeMipmapTestInstance (void);
433
434 virtual tcu::TestStatus iterate (void);
435
436 private:
437 TextureCubeMipmapTestInstance (const TextureCubeMipmapTestInstance& other);
438 TextureCubeMipmapTestInstance& operator= (const TextureCubeMipmapTestInstance& other);
439
440 const ParameterType m_testParameters;
441 TestTextureCubeSp m_texture;
442 TextureRenderer m_renderer;
443 };
444
TextureCubeMipmapTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)445 TextureCubeMipmapTestInstance::TextureCubeMipmapTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
446 : TestInstance (context)
447 , m_testParameters (testParameters)
448 , m_renderer (context, m_testParameters.sampleCount, m_testParameters.size*2, m_testParameters.size*2)
449 {
450 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
451
452 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size));
453
454 const int numLevels = deLog2Floor32(m_testParameters.size)+1;
455
456 // Fill texture with colored grid.
457 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
458 {
459 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
460 {
461 const deUint32 step = 0xff / (numLevels-1);
462 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
463 const deUint32 dec = 0xff - inc;
464 deUint32 rgb = 0;
465
466 switch (faceNdx)
467 {
468 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
469 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
470 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
471 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
472 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
473 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
474 }
475
476 const deUint32 color = 0xff000000 | rgb;
477 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
478 }
479 }
480
481 m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
482 }
483
~TextureCubeMipmapTestInstance(void)484 TextureCubeMipmapTestInstance::~TextureCubeMipmapTestInstance (void)
485 {
486 }
487
randomPartition(vector<IVec4> & dst,de::Random & rnd,int x,int y,int width,int height)488 static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height)
489 {
490 const int minWidth = 8;
491 const int minHeight = 8;
492
493 const bool partition = rnd.getFloat() > 0.4f;
494 const bool partitionX = partition && width > minWidth && rnd.getBool();
495 const bool partitionY = partition && height > minHeight && !partitionX;
496
497 if (partitionX)
498 {
499 const int split = width/2 + rnd.getInt(-width/4, +width/4);
500 randomPartition(dst, rnd, x, y, split, height);
501 randomPartition(dst, rnd, x+split, y, width-split, height);
502 }
503 else if (partitionY)
504 {
505 const int split = height/2 + rnd.getInt(-height/4, +height/4);
506 randomPartition(dst, rnd, x, y, width, split);
507 randomPartition(dst, rnd, x, y+split, width, height-split);
508 }
509 else
510 dst.push_back(IVec4(x, y, width, height));
511 }
512
computeGridLayout(vector<IVec4> & dst,int width,int height)513 static void computeGridLayout (vector<IVec4>& dst, int width, int height)
514 {
515 de::Random rnd(7);
516 randomPartition(dst, rnd, 0, 0, width, height);
517 }
518
iterate(void)519 tcu::TestStatus TextureCubeMipmapTestInstance::iterate (void)
520 {
521 const int viewportWidth = m_renderer.getRenderWidth();
522 const int viewportHeight = m_renderer.getRenderHeight();
523
524 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
525 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
526
527 ReferenceParams refParams (TEXTURETYPE_CUBE);
528 vector<float> texCoord;
529 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
530
531 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
532 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format));
533 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
534 refParams.lodMode = LODMODE_EXACT; // Use ideal lod.
535
536 // Compute grid.
537 vector<IVec4> gridLayout;
538 computeGridLayout(gridLayout, viewportWidth, viewportHeight);
539
540 // Bias values.
541 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
542
543 // Projection values \note Less agressive than in 2D case due to smaller quads.
544 static const Vec4 s_projections[] =
545 {
546 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
547 Vec4(1.3f, 0.8f, 0.6f, 1.1f),
548 Vec4(0.8f, 1.0f, 1.2f, 0.8f),
549 Vec4(1.2f, 1.0f, 1.3f, 0.9f)
550 };
551
552 // Render with GL
553 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
554 {
555 const float curX = (float)gridLayout[cellNdx].x();
556 const float curY = (float)gridLayout[cellNdx].y();
557 const float curW = (float)gridLayout[cellNdx].z();
558 const float curH = (float)gridLayout[cellNdx].w();
559 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
560
561 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
562 computeQuadTexCoordCube(texCoord, cubeFace);
563
564 if (isProjected)
565 {
566 refParams.flags |= ReferenceParams::PROJECTED;
567 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
568 }
569
570 if (useLodBias)
571 {
572 refParams.flags |= ReferenceParams::USE_BIAS;
573 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
574 }
575
576 // Render
577 m_renderer.setViewport(curX, curY, curW, curH);
578 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
579 }
580
581 // Render reference and compare
582 {
583 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
584 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
585 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
586 tcu::Surface errorMask (viewportWidth, viewportHeight);
587 int numFailedPixels = 0;
588 tcu::LookupPrecision lookupPrec;
589 tcu::LodPrecision lodPrec;
590
591 // Params for rendering reference
592 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
593 refParams.sampler.seamlessCubeMap = true;
594 refParams.lodMode = LODMODE_EXACT;
595
596 // Comparison parameters
597 lookupPrec.colorMask = getCompareMask(pixelFormat);
598 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, tcu::IVec4(0)));
599 lookupPrec.coordBits = isProjected ? tcu::IVec3(8) : tcu::IVec3(10);
600 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
601 lodPrec.derivateBits = 10;
602 lodPrec.lodBits = isProjected ? 3 : 6;
603
604 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
605 {
606 const int curX = gridLayout[cellNdx].x();
607 const int curY = gridLayout[cellNdx].y();
608 const int curW = gridLayout[cellNdx].z();
609 const int curH = gridLayout[cellNdx].w();
610 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
611
612 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported.
613 computeQuadTexCoordCube(texCoord, cubeFace);
614
615 if (isProjected)
616 {
617 refParams.flags |= ReferenceParams::PROJECTED;
618 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
619 }
620
621 if (useLodBias)
622 {
623 refParams.flags |= ReferenceParams::USE_BIAS;
624 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
625 }
626
627 // Render ideal reference.
628 {
629 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
630 sampleTexture(idealDst, m_texture->getTexture(), &texCoord[0], refParams);
631 }
632
633 // Compare this cell
634 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
635 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
636 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
637 m_texture->getTexture(), &texCoord[0], refParams,
638 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
639 }
640
641 if (numFailedPixels > 0)
642 {
643 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
644 }
645
646 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
647 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
648
649 if (numFailedPixels > 0)
650 {
651 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
652 << TestLog::Image("ErrorMask", "Error mask", errorMask);
653 }
654
655 m_context.getTestContext().getLog() << TestLog::EndImageSet;
656
657 {
658 const bool isOk = numFailedPixels == 0;
659 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
660 }
661 }
662 }
663
664 // Texture3DMipmapTestInstance
665 class Texture3DMipmapTestInstance : public TestInstance
666 {
667 public:
668 typedef Texture3DMipmapTestCaseParameters ParameterType;
669
670 Texture3DMipmapTestInstance (Context& context, const ParameterType& testParameters);
671 ~Texture3DMipmapTestInstance (void);
672
673 virtual tcu::TestStatus iterate (void);
674
675 private:
676 Texture3DMipmapTestInstance (const Texture3DMipmapTestInstance& other);
677 Texture3DMipmapTestInstance& operator= (const Texture3DMipmapTestInstance& other);
678
679 const ParameterType m_testParameters;
680 TestTexture3DSp m_texture;
681 TextureRenderer m_renderer;
682 };
683
Texture3DMipmapTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)684 Texture3DMipmapTestInstance::Texture3DMipmapTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
685 : TestInstance (context)
686 , m_testParameters (testParameters)
687 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4)
688 {
689 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT));
690
691 const tcu::TextureFormat& texFmt = mapVkFormat(testParameters.format);
692 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
693 const tcu::Vec4& cScale = fmtInfo.lookupScale;
694 const tcu::Vec4& cBias = fmtInfo.lookupBias;
695 const int numLevels = deLog2Floor32(de::max(de::max(testParameters.width, testParameters.height), testParameters.depth))+1;
696
697 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.depth));
698
699 // Fill texture with colored grid.
700 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
701 {
702 const deUint32 step = 0xff / (numLevels-1);
703 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
704 const deUint32 dec = 0xff - inc;
705 const deUint32 rgb = (0xff << 16) | (dec << 8) | inc;
706 const deUint32 color = 0xff000000 | rgb;
707
708 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
709 }
710
711 m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
712 }
713
~Texture3DMipmapTestInstance(void)714 Texture3DMipmapTestInstance::~Texture3DMipmapTestInstance (void)
715 {
716 }
717
getBasicTexCoord3D(std::vector<float> & dst,int cellNdx)718 static void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx)
719 {
720 static const struct
721 {
722 const float sScale;
723 const float sBias;
724 const float tScale;
725 const float tBias;
726 const float rScale;
727 const float rBias;
728 } s_params[] =
729 {
730 // sScale sBias tScale tBias rScale rBias
731 { 0.9f, -0.1f, 0.7f, 0.3f, 0.8f, 0.9f },
732 { 1.2f, -0.1f, 1.1f, 0.3f, 1.0f, 0.9f },
733 { 1.5f, 0.7f, 0.9f, -0.3f, 1.1f, 0.1f },
734 { 1.2f, 0.7f, -2.3f, -0.3f, 1.1f, 0.2f },
735 { 1.1f, 0.8f, -1.3f, -0.3f, 2.9f, 0.9f },
736 { 3.4f, 0.8f, 4.0f, 0.0f, -3.3f, -1.0f },
737 { -3.4f, -0.1f, -4.0f, 0.0f, -5.1f, 1.0f },
738 { -4.0f, -0.1f, 3.4f, 0.1f, 5.7f, 0.0f },
739 { -5.6f, 0.0f, 0.5f, 1.2f, 3.9f, 4.0f },
740 { 5.0f, -2.0f, 3.1f, 1.2f, 5.1f, 0.2f },
741 { 2.5f, -2.0f, 6.3f, 3.0f, 5.1f, 0.2f },
742 { -8.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
743 { 3.8f, 0.0f, 9.7f, 1.0f, 7.0f, 0.7f },
744 { 13.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f },
745 { 16.0f, 8.0f, 12.7f, 1.0f, 17.1f, 0.7f },
746 { 15.3f, 0.0f, 20.1f, 3.0f, 33.0f, 3.2f }
747 };
748
749 const float sScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale;
750 const float sBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias;
751 const float tScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale;
752 const float tBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias;
753 const float rScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale;
754 const float rBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias;
755
756 dst.resize(3*4);
757
758 dst[0] = sBias; dst[ 1] = tBias; dst[ 2] = rBias;
759 dst[3] = sBias; dst[ 4] = tBias+tScale; dst[ 5] = rBias+rScale*0.5f;
760 dst[6] = sBias+sScale; dst[ 7] = tBias; dst[ 8] = rBias+rScale*0.5f;
761 dst[9] = sBias+sScale; dst[10] = tBias+tScale; dst[11] = rBias+rScale;
762 }
763
getBasicTexCoord3DImageViewMinlodIntTexCoord(std::vector<float> & dst)764 static void getBasicTexCoord3DImageViewMinlodIntTexCoord (std::vector<float>& dst)
765 {
766 const float sScale = 1.0f;
767 const float sBias = 0.0f;
768 const float tScale = 1.0f;
769 const float tBias = 0.0f;
770 const float rScale = 1.0f;
771 const float rBias = 0.0f;
772
773 dst.resize(3*4);
774
775 dst[0] = sBias; dst[ 1] = tBias; dst[ 2] = rBias;
776 dst[3] = sBias; dst[ 4] = tBias+tScale; dst[ 5] = rBias+rScale*0.5f;
777 dst[6] = sBias+sScale; dst[ 7] = tBias; dst[ 8] = rBias+rScale*0.5f;
778 dst[9] = sBias+sScale; dst[10] = tBias+tScale; dst[11] = rBias+rScale;
779 }
780
getAffineTexCoord3D(std::vector<float> & dst,int cellNdx)781 static void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx)
782 {
783 // Use basic coords as base.
784 getBasicTexCoord3D(dst, cellNdx);
785
786 // Rotate based on cell index.
787 const float angleX = 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f);
788 const float angleY = 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f);
789 const tcu::Mat3 rotMatrix = tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY);
790
791 const Vec3 p0 = rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]);
792 const Vec3 p1 = rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]);
793 const Vec3 p2 = rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]);
794 const Vec3 p3 = rotMatrix * Vec3(dst[9], dst[10], dst[11]);
795
796 dst[0] = p0.x(); dst[ 1] = p0.y(); dst[ 2] = p0.z();
797 dst[3] = p1.x(); dst[ 4] = p1.y(); dst[ 5] = p1.z();
798 dst[6] = p2.x(); dst[ 7] = p2.y(); dst[ 8] = p2.z();
799 dst[9] = p3.x(); dst[10] = p3.y(); dst[11] = p3.z();
800 }
801
iterate(void)802 tcu::TestStatus Texture3DMipmapTestInstance::iterate (void)
803 {
804 const tcu::TextureFormat& texFmt = m_texture->getTextureFormat();
805 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
806 const Sampler::FilterMode magFilter = Sampler::NEAREST;
807 const int viewportWidth = m_renderer.getRenderWidth();
808 const int viewportHeight = m_renderer.getRenderHeight();
809
810 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED;
811 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS;
812
813 // Viewport is divided into 4x4 grid.
814 const int gridWidth = 4;
815 const int gridHeight = 4;
816 const int cellWidth = viewportWidth / gridWidth;
817 const int cellHeight = viewportHeight / gridHeight;
818
819 ReferenceParams refParams (TEXTURETYPE_3D);
820
821 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
822 vector<float> texCoord;
823
824 // Sampling parameters.
825 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter);
826 refParams.samplerType = getSamplerType(texFmt);
827
828 refParams.colorBias = fmtInfo.lookupBias;
829 refParams.colorScale = fmtInfo.lookupScale;
830 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0);
831
832 // Bias values.
833 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f };
834
835 // Projection values.
836 static const Vec4 s_projections[] =
837 {
838 Vec4(1.2f, 1.0f, 0.7f, 1.0f),
839 Vec4(1.3f, 0.8f, 0.6f, 2.0f),
840 Vec4(0.8f, 1.0f, 1.7f, 0.6f),
841 Vec4(1.2f, 1.0f, 1.7f, 1.5f)
842 };
843
844 // Render cells.
845 for (int gridY = 0; gridY < gridHeight; gridY++)
846 {
847 for (int gridX = 0; gridX < gridWidth; gridX++)
848 {
849 const int curX = cellWidth*gridX;
850 const int curY = cellHeight*gridY;
851 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
852 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
853 const int cellNdx = gridY*gridWidth + gridX;
854
855 // Compute texcoord.
856 switch (m_testParameters.coordType)
857 {
858 case COORDTYPE_BASIC_BIAS: // Fall-through.
859 case COORDTYPE_PROJECTED:
860 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
861 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
862 default: DE_ASSERT(DE_FALSE);
863 }
864
865 // Set projection.
866 if (isProjected)
867 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
868
869 // Set LOD bias.
870 if (useLodBias)
871 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
872
873 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
874 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
875 }
876 }
877
878 // Compare and log
879 {
880 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
881 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
882 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
883 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
884 tcu::Surface errorMask (viewportWidth, viewportHeight);
885 tcu::LookupPrecision lookupPrec;
886 tcu::LodPrecision lodPrec;
887 int numFailedPixels = 0;
888
889 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
890 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
891 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
892 lookupPrec.colorMask = getCompareMask(pixelFormat);
893 lodPrec.derivateBits = 10;
894 lodPrec.lodBits = isProjected ? 6 : 8;
895
896 for (int gridY = 0; gridY < gridHeight; gridY++)
897 {
898 for (int gridX = 0; gridX < gridWidth; gridX++)
899 {
900 const int curX = cellWidth*gridX;
901 const int curY = cellHeight*gridY;
902 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
903 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
904 const int cellNdx = gridY*gridWidth + gridX;
905
906 switch (m_testParameters.coordType)
907 {
908 case COORDTYPE_BASIC_BIAS: // Fall-through.
909 case COORDTYPE_PROJECTED:
910 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break;
911 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break;
912 default: DE_ASSERT(DE_FALSE);
913 }
914
915 if (isProjected)
916 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)];
917
918 if (useLodBias)
919 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)];
920
921 // Render ideal result
922 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
923 m_texture->getTexture(), &texCoord[0], refParams);
924
925 // Compare this cell
926 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
927 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
928 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
929 m_texture->getTexture(), &texCoord[0], refParams,
930 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
931 }
932 }
933
934 if (numFailedPixels > 0)
935 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
936
937 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
938 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
939
940 if (numFailedPixels > 0)
941 {
942 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
943 << TestLog::Image("ErrorMask", "Error mask", errorMask);
944 }
945
946 m_context.getTestContext().getLog() << TestLog::EndImageSet;
947
948 {
949 const bool isOk = numFailedPixels == 0;
950 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
951 }
952 }
953 }
954
955 // Texture2DLodControlTestInstance
956 class Texture2DLodControlTestInstance : public TestInstance
957 {
958 public:
959 typedef Texture2DMipmapTestCaseParameters ParameterType;
960
961 Texture2DLodControlTestInstance (Context& context, const ParameterType& testParameters);
962 ~Texture2DLodControlTestInstance (void);
963
964 virtual tcu::TestStatus iterate (void);
965
966 protected:
967 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = 0;
968
969 const int m_texWidth;
970 const int m_texHeight;
971
972 private:
973 Texture2DLodControlTestInstance (const Texture2DLodControlTestInstance& other);
974 Texture2DLodControlTestInstance& operator= (const Texture2DLodControlTestInstance& other);
975
976 const ParameterType m_testParameters;
977 tcu::Sampler::FilterMode m_minFilter;
978 TestTexture2DSp m_texture;
979 TextureRenderer m_renderer;
980 };
981
Texture2DLodControlTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)982 Texture2DLodControlTestInstance::Texture2DLodControlTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
983 : TestInstance (context)
984 , m_texWidth (64) //64
985 , m_texHeight (64)//64
986 , m_testParameters (testParameters)
987 , m_minFilter (testParameters.minFilter)
988 , m_texture (DE_NULL)
989 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4, vk::makeComponentMappingRGBA(), testParameters.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD, testParameters.testType >= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD)
990 {
991 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
992 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
993
994 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(format), m_texWidth, m_texHeight));
995
996 // Fill texture with colored grid.
997 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
998 {
999 const deUint32 step = 0xff / (numLevels-1);
1000 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1001 const deUint32 dec = 0xff - inc;
1002 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
1003 const deUint32 color = 0xff000000 | rgb;
1004
1005 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec());
1006 }
1007
1008 m_renderer.add2DTexture(m_texture, testParameters.aspectMask);
1009 }
1010
~Texture2DLodControlTestInstance(void)1011 Texture2DLodControlTestInstance::~Texture2DLodControlTestInstance (void)
1012 {
1013 }
1014
iterate(void)1015 tcu::TestStatus Texture2DLodControlTestInstance::iterate (void)
1016 {
1017 const tcu::Sampler::WrapMode wrapS = Sampler::REPEAT_GL;
1018 const tcu::Sampler::WrapMode wrapT = Sampler::REPEAT_GL;
1019 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
1020
1021 const tcu::Texture2D& refTexture = m_texture->getTexture();
1022
1023 const int viewportWidth = m_renderer.getRenderWidth();
1024 const int viewportHeight = m_renderer.getRenderHeight();
1025
1026 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
1027
1028 ReferenceParams refParams (TEXTURETYPE_2D, sampler);
1029 vector<float> texCoord;
1030 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
1031
1032 // Viewport is divided into 4x4 grid.
1033 const int gridWidth = 4;
1034 const int gridHeight = 4;
1035 const int cellWidth = viewportWidth / gridWidth;
1036 const int cellHeight = viewportHeight / gridHeight;
1037
1038 refParams.maxLevel = deLog2Floor32(de::max(m_texWidth, m_texHeight));
1039
1040 // Render cells.
1041 for (int gridY = 0; gridY < gridHeight; gridY++)
1042 {
1043 for (int gridX = 0; gridX < gridWidth; gridX++)
1044 {
1045 const int curX = cellWidth*gridX;
1046 const int curY = cellHeight*gridY;
1047 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1048 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1049 const int cellNdx = gridY*gridWidth + gridX;
1050
1051 getReferenceParams(refParams,cellNdx);
1052
1053 // Compute texcoord.
1054 getBasicTexCoord2D(texCoord, cellNdx);
1055 // Render
1056 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1057 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
1058 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1059 }
1060 }
1061
1062 // Compare and log.
1063 {
1064 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1065 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1066 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
1067 tcu::LookupPrecision lookupPrec;
1068 tcu::LodPrecision lodPrec;
1069
1070 lookupPrec.coordBits = tcu::IVec3(20, 20, 0);
1071 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored.
1072 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1073 lookupPrec.colorMask = getCompareMask(pixelFormat);
1074 lodPrec.derivateBits = 10;
1075 lodPrec.lodBits = 8;
1076
1077 auto compareAndLogImages = [&] (tcu::ImageViewMinLodMode imageViewLodMode = tcu::IMAGEVIEWMINLODMODE_PREFERRED)
1078 {
1079 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
1080 tcu::Surface errorMask (viewportWidth, viewportHeight);
1081
1082 int numFailedPixels = 0;
1083
1084 for (int gridY = 0; gridY < gridHeight; gridY++)
1085 {
1086 for (int gridX = 0; gridX < gridWidth; gridX++)
1087 {
1088 const int curX = cellWidth*gridX;
1089 const int curY = cellHeight*gridY;
1090 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1091 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1092 const int cellNdx = gridY*gridWidth + gridX;
1093
1094 getReferenceParams(refParams,cellNdx);
1095
1096 refParams.imageViewMinLodMode = imageViewLodMode;
1097
1098 // Compute texcoord.
1099 if (refParams.samplerType == glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT)
1100 getBasicTexCoord2DImageViewMinLodIntTexCoord(texCoord);
1101 else
1102 getBasicTexCoord2D(texCoord, cellNdx);
1103
1104 // Render ideal result
1105 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1106 refTexture, &texCoord[0], refParams);
1107
1108 // Compare this cell
1109 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1110 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1111 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1112 m_texture->getTexture(), &texCoord[0], refParams,
1113 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1114 }
1115 }
1116
1117 if (numFailedPixels > 0)
1118 {
1119 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1120 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1121 }
1122 return numFailedPixels;
1123 };
1124
1125 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1126 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1127
1128 int numFailedPixels = compareAndLogImages();
1129
1130 if (numFailedPixels > 0 && refParams.imageViewMinLod > 0.0f)
1131 {
1132 numFailedPixels = compareAndLogImages(tcu::IMAGEVIEWMINLODMODE_ALTERNATIVE);
1133 }
1134 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1135
1136 if (numFailedPixels > 0)
1137 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1138
1139 {
1140 const bool isOk = numFailedPixels == 0;
1141 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1142 }
1143 }
1144 }
1145
1146 class Texture2DMinLodTestInstance : public Texture2DLodControlTestInstance
1147 {
1148 public:
Texture2DMinLodTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1149 Texture2DMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1150 : Texture2DLodControlTestInstance(context, testParameters)
1151 {
1152 }
1153
1154 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1155 void getReferenceParams (ReferenceParams& params, int cellNdx)
1156 {
1157 params.minLod = getMinLodForCell(cellNdx);
1158 }
1159 };
1160
1161 class Texture2DMaxLodTestInstance : public Texture2DLodControlTestInstance
1162 {
1163 public:
Texture2DMaxLodTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1164 Texture2DMaxLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1165 : Texture2DLodControlTestInstance(context, testParameters)
1166 {
1167 }
1168
1169 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1170 void getReferenceParams (ReferenceParams& params, int cellNdx)
1171 {
1172 params.maxLod = getMaxLodForCell(cellNdx);
1173 }
1174 };
1175
1176 class Texture2DBaseLevelTestInstance : public Texture2DLodControlTestInstance
1177 {
1178 public:
Texture2DBaseLevelTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1179 Texture2DBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1180 : Texture2DLodControlTestInstance(context, testParameters)
1181 , m_testParam (testParameters)
1182 {
1183 }
1184
1185 protected:
1186 const Texture2DMipmapTestCaseParameters m_testParam;
1187
getBaseLevel(int cellNdx) const1188 int getBaseLevel (int cellNdx) const
1189 {
1190 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1191 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;
1192
1193 return baseLevel;
1194 }
1195
getReferenceParams(ReferenceParams & params,int cellNdx)1196 void getReferenceParams (ReferenceParams& params, int cellNdx)
1197 {
1198 params.baseLevel = getBaseLevel(cellNdx);
1199 }
1200 };
1201
1202 class Texture2DMaxLevelTestInstance : public Texture2DLodControlTestInstance
1203 {
1204 public:
Texture2DMaxLevelTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1205 Texture2DMaxLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1206 : Texture2DLodControlTestInstance(context, testParameters)
1207 , m_testParam (testParameters)
1208 {
1209 }
1210
1211 protected:
1212 const Texture2DMipmapTestCaseParameters m_testParam;
1213
getMaxLevel(int cellNdx) const1214 int getMaxLevel (int cellNdx) const
1215 {
1216 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1217 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x82cfa4e) % numLevels;
1218
1219 return maxLevel;
1220 }
1221
getReferenceParams(ReferenceParams & params,int cellNdx)1222 void getReferenceParams (ReferenceParams& params, int cellNdx)
1223 {
1224 params.maxLevel = getMaxLevel(cellNdx);
1225 }
1226 };
1227
1228 // TextureCubeLodControlTestInstance
1229 class TextureCubeLodControlTestInstance : public TestInstance
1230 {
1231 public:
1232 typedef TextureCubeMipmapTestCaseParameters ParameterType;
1233
1234 TextureCubeLodControlTestInstance (Context& context, const ParameterType& testParameters);
1235 ~TextureCubeLodControlTestInstance (void);
1236
1237 virtual tcu::TestStatus iterate (void);
1238
1239 protected:
1240 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1241
1242 const int m_texSize;
1243
1244 private:
1245 TextureCubeLodControlTestInstance (const TextureCubeLodControlTestInstance& other);
1246 TextureCubeLodControlTestInstance& operator= (const TextureCubeLodControlTestInstance& other);
1247
1248 const ParameterType m_testParameters;
1249 tcu::Sampler::FilterMode m_minFilter;
1250 TestTextureCubeSp m_texture;
1251 TextureRenderer m_renderer;
1252 };
1253
TextureCubeLodControlTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1254 TextureCubeLodControlTestInstance::TextureCubeLodControlTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1255 : TestInstance (context)
1256 , m_texSize (64)
1257 , m_testParameters (testParameters)
1258 , m_minFilter (testParameters.minFilter)
1259 , m_texture (DE_NULL)
1260
1261 , m_renderer (context, testParameters.sampleCount, m_texSize*2, m_texSize*2)
1262 {
1263 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1264 const int numLevels = deLog2Floor32(m_texSize)+1;
1265
1266 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(format), m_texSize));
1267
1268 // Fill texture with colored grid.
1269 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1270 {
1271 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1272 {
1273 const deUint32 step = 0xff / (numLevels-1);
1274 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1275 const deUint32 dec = 0xff - inc;
1276 deUint32 rgb = 0;
1277
1278 switch (faceNdx)
1279 {
1280 case 0: rgb = (inc << 16) | (dec << 8) | 255; break;
1281 case 1: rgb = (255 << 16) | (inc << 8) | dec; break;
1282 case 2: rgb = (dec << 16) | (255 << 8) | inc; break;
1283 case 3: rgb = (dec << 16) | (inc << 8) | 255; break;
1284 case 4: rgb = (255 << 16) | (dec << 8) | inc; break;
1285 case 5: rgb = (inc << 16) | (255 << 8) | dec; break;
1286 }
1287
1288 const deUint32 color = 0xff000000 | rgb;
1289
1290 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec());
1291 }
1292 }
1293
1294 m_renderer.addCubeTexture(m_texture, testParameters.aspectMask);
1295 }
1296
~TextureCubeLodControlTestInstance(void)1297 TextureCubeLodControlTestInstance::~TextureCubeLodControlTestInstance (void)
1298 {
1299 }
1300
iterate(void)1301 tcu::TestStatus TextureCubeLodControlTestInstance::iterate (void)
1302 {
1303 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE;
1304 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE;
1305 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
1306
1307 const tcu::TextureCube& refTexture = m_texture->getTexture();
1308 const int viewportWidth = m_renderer.getRenderWidth();
1309 const int viewportHeight = m_renderer.getRenderHeight();
1310
1311 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
1312 ReferenceParams refParams (TEXTURETYPE_CUBE, sampler);
1313 vector<float> texCoord;
1314 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
1315
1316 refParams.maxLevel = deLog2Floor32(m_texSize);
1317
1318 // Compute grid.
1319 vector<tcu::IVec4> gridLayout;
1320 computeGridLayout(gridLayout, viewportWidth, viewportHeight);
1321
1322 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1323 {
1324 const int curX = gridLayout[cellNdx].x();
1325 const int curY = gridLayout[cellNdx].y();
1326 const int curW = gridLayout[cellNdx].z();
1327 const int curH = gridLayout[cellNdx].w();
1328 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1329
1330 computeQuadTexCoordCube(texCoord, cubeFace);
1331 getReferenceParams(refParams, cellNdx);
1332
1333 // Render with GL.
1334 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1335 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
1336 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1337 }
1338
1339 // Render reference and compare
1340 {
1341 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1342 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1343 tcu::LookupPrecision lookupPrec;
1344 tcu::LodPrecision lodPrec;
1345
1346 // Params for rendering reference
1347 refParams.sampler = util::createSampler(wrapS, wrapT, m_testParameters.minFilter, magFilter);
1348 refParams.sampler.seamlessCubeMap = true;
1349 refParams.lodMode = LODMODE_EXACT;
1350
1351 // Comparison parameters
1352 lookupPrec.colorMask = getCompareMask(pixelFormat);
1353 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, IVec4(0)));
1354 lookupPrec.coordBits = tcu::IVec3(10);
1355 lookupPrec.uvwBits = tcu::IVec3(5,5,0);
1356 lodPrec.derivateBits = 10;
1357 lodPrec.lodBits = 6;
1358
1359 auto compareAndLogImages = [&](tcu::ImageViewMinLodMode imageViewLodMode = tcu::IMAGEVIEWMINLODMODE_PREFERRED)
1360 {
1361 tcu::Surface referenceFrame(viewportWidth, viewportHeight);
1362 tcu::Surface errorMask(viewportWidth, viewportHeight);
1363 int numFailedPixels = 0;
1364
1365 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++)
1366 {
1367 const int curX = gridLayout[cellNdx].x();
1368 const int curY = gridLayout[cellNdx].y();
1369 const int curW = gridLayout[cellNdx].z();
1370 const int curH = gridLayout[cellNdx].w();
1371 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST);
1372
1373 computeQuadTexCoordCube(texCoord, cubeFace);
1374 getReferenceParams(refParams, cellNdx);
1375
1376 refParams.imageViewMinLodMode = imageViewLodMode;
1377
1378 // Render ideal reference.
1379 {
1380 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH);
1381 sampleTexture(idealDst, refTexture, &texCoord[0], refParams);
1382 }
1383
1384 // Compare this cell
1385 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1386 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1387 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1388 m_texture->getTexture(), &texCoord[0], refParams,
1389 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1390 }
1391 if (numFailedPixels > 0)
1392 {
1393 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1394 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1395 }
1396 return numFailedPixels;
1397 };
1398
1399 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1400 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1401
1402 int numFailedPixels = compareAndLogImages();
1403
1404 if (numFailedPixels > 0 && refParams.imageViewMinLod > 0.0f)
1405 {
1406 numFailedPixels = compareAndLogImages(tcu::IMAGEVIEWMINLODMODE_ALTERNATIVE);
1407 }
1408 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1409
1410 if (numFailedPixels > 0)
1411 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1412
1413 {
1414 const bool isOk = numFailedPixels == 0;
1415 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1416 }
1417 }
1418 }
1419
1420 class TextureCubeMinLodTestInstance : public TextureCubeLodControlTestInstance
1421 {
1422 public:
TextureCubeMinLodTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1423 TextureCubeMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1424 : TextureCubeLodControlTestInstance(context, testParameters)
1425 {
1426 }
1427
1428 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1429 void getReferenceParams (ReferenceParams& params, int cellNdx)
1430 {
1431 params.minLod = getMinLodForCell(cellNdx);
1432 }
1433 };
1434
1435 class TextureCubeMaxLodTestInstance : public TextureCubeLodControlTestInstance
1436 {
1437 public:
TextureCubeMaxLodTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1438 TextureCubeMaxLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1439 : TextureCubeLodControlTestInstance(context, testParameters)
1440 {
1441 }
1442
1443 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1444 void getReferenceParams (ReferenceParams& params, int cellNdx)
1445 {
1446 params.maxLod = getMaxLodForCell(cellNdx);
1447 }
1448 };
1449
1450 class TextureCubeBaseLevelTestInstance : public TextureCubeLodControlTestInstance
1451 {
1452 public:
TextureCubeBaseLevelTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1453 TextureCubeBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1454 : TextureCubeLodControlTestInstance(context, testParameters)
1455 , m_testParam (testParameters)
1456 {
1457 }
1458
1459 protected:
1460 const TextureCubeMipmapTestCaseParameters m_testParam;
1461
getBaseLevel(int cellNdx) const1462 int getBaseLevel (int cellNdx) const
1463 {
1464 const int numLevels = deLog2Floor32(m_texSize)+1;
1465 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels;
1466
1467 return baseLevel;
1468 }
1469
getReferenceParams(ReferenceParams & params,int cellNdx)1470 void getReferenceParams (ReferenceParams& params, int cellNdx)
1471 {
1472 params.baseLevel = getBaseLevel(cellNdx);
1473 }
1474 };
1475
1476 class TextureCubeMaxLevelTestInstance : public TextureCubeLodControlTestInstance
1477 {
1478 public:
TextureCubeMaxLevelTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1479 TextureCubeMaxLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1480 : TextureCubeLodControlTestInstance(context, testParameters)
1481 , m_testParam (testParameters)
1482 {
1483 }
1484
1485 protected:
1486 const TextureCubeMipmapTestCaseParameters m_testParam;
getMaxLevel(int cellNdx) const1487 int getMaxLevel (int cellNdx) const
1488 {
1489 const int numLevels = deLog2Floor32(m_texSize)+1;
1490 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x974e21) % numLevels;
1491
1492 return maxLevel;
1493 }
1494
getReferenceParams(ReferenceParams & params,int cellNdx)1495 void getReferenceParams (ReferenceParams& params, int cellNdx)
1496 {
1497 params.maxLevel = getMaxLevel(cellNdx);
1498 }
1499 };
1500
1501 // Texture3DLodControlTestInstance
1502 class Texture3DLodControlTestInstance : public TestInstance
1503 {
1504 public:
1505 typedef Texture3DMipmapTestCaseParameters ParameterType;
1506
1507 Texture3DLodControlTestInstance (Context& context, const ParameterType& testParameters);
1508 ~Texture3DLodControlTestInstance (void);
1509
1510 virtual tcu::TestStatus iterate (void);
1511
1512 protected:
1513 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL;
1514
1515 const int m_texWidth;
1516 const int m_texHeight;
1517 const int m_texDepth;
1518
1519 private:
1520 Texture3DLodControlTestInstance (const Texture3DLodControlTestInstance& other);
1521 Texture3DLodControlTestInstance& operator= (const Texture3DLodControlTestInstance& other);
1522
1523 const ParameterType m_testParameters;
1524 tcu::Sampler::FilterMode m_minFilter;
1525 TestTexture3DSp m_texture;
1526 TextureRenderer m_renderer;
1527 };
1528
Texture3DLodControlTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1529 Texture3DLodControlTestInstance::Texture3DLodControlTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1530 : TestInstance (context)
1531 , m_texWidth (32)
1532 , m_texHeight (32)
1533 , m_texDepth (32)
1534 , m_testParameters (testParameters)
1535 , m_minFilter (testParameters.minFilter)
1536 , m_texture (DE_NULL)
1537 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4, vk::makeComponentMappingRGBA(), testParameters.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD, testParameters.testType >= util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD)
1538 {
1539 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
1540 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format));
1541 const tcu::Vec4& cScale = fmtInfo.lookupScale;
1542 const tcu::Vec4& cBias = fmtInfo.lookupBias;
1543 const int numLevels = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1;
1544
1545 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(format), m_texWidth, m_texHeight, m_texDepth));
1546
1547 // Fill texture with colored grid.
1548 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
1549 {
1550 const deUint32 step = 0xff / (numLevels-1);
1551 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff);
1552 const deUint32 dec = 0xff - inc;
1553 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff;
1554 const deUint32 color = 0xff000000 | rgb;
1555
1556 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias);
1557 }
1558
1559 m_renderer.add3DTexture(m_texture, testParameters.aspectMask);
1560 }
1561
~Texture3DLodControlTestInstance(void)1562 Texture3DLodControlTestInstance::~Texture3DLodControlTestInstance (void)
1563 {
1564 }
1565
iterate(void)1566 tcu::TestStatus Texture3DLodControlTestInstance::iterate (void)
1567 {
1568 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE;
1569 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE;
1570 const tcu::Sampler::WrapMode wrapR = Sampler::CLAMP_TO_EDGE;
1571 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST;
1572
1573 const tcu::Texture3D& refTexture = m_texture->getTexture();
1574 const tcu::TextureFormat& texFmt = refTexture.getFormat();
1575 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
1576 const int viewportWidth = m_renderer.getRenderWidth();
1577 const int viewportHeight = m_renderer.getRenderHeight();
1578
1579 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter);
1580 ReferenceParams refParams (TEXTURETYPE_3D, sampler);
1581 vector<float> texCoord;
1582 tcu::Surface renderedFrame (viewportWidth, viewportHeight);
1583
1584 // Viewport is divided into 4x4 grid.
1585 const int gridWidth = 4;
1586 const int gridHeight = 4;
1587 const int cellWidth = viewportWidth / gridWidth;
1588 const int cellHeight = viewportHeight / gridHeight;
1589
1590 // Sampling parameters.
1591 refParams.sampler = util::createSampler(wrapS, wrapT, wrapR, m_testParameters.minFilter, magFilter);
1592 refParams.samplerType = getSamplerType(texFmt);
1593 refParams.colorBias = fmtInfo.lookupBias;
1594 refParams.colorScale = fmtInfo.lookupScale;
1595 refParams.maxLevel = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth));
1596
1597 // Render cells.
1598 for (int gridY = 0; gridY < gridHeight; gridY++)
1599 {
1600 for (int gridX = 0; gridX < gridWidth; gridX++)
1601 {
1602 const int curX = cellWidth*gridX;
1603 const int curY = cellHeight*gridY;
1604 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1605 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1606 const int cellNdx = gridY*gridWidth + gridX;
1607
1608 // Compute texcoord.
1609 getBasicTexCoord3D(texCoord, cellNdx);
1610
1611 getReferenceParams(refParams,cellNdx);
1612 //Render
1613 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH);
1614 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel, refParams.imageViewMinLod);
1615 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams);
1616 }
1617 }
1618
1619 // Compare and log
1620 {
1621 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1622 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1623 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR;
1624 tcu::LookupPrecision lookupPrec;
1625 tcu::LodPrecision lodPrec;
1626
1627 lookupPrec.coordBits = tcu::IVec3(20, 20, 20);
1628 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored.
1629 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0)));
1630 lookupPrec.colorMask = getCompareMask(pixelFormat);
1631 lodPrec.derivateBits = 10;
1632 lodPrec.lodBits = 8;
1633
1634 auto compareAndLogImages = [&](tcu::ImageViewMinLodMode imageViewLodMode = tcu::IMAGEVIEWMINLODMODE_PREFERRED)
1635 {
1636 tcu::Surface referenceFrame (viewportWidth, viewportHeight);
1637 tcu::Surface errorMask (viewportWidth, viewportHeight);
1638 int numFailedPixels = 0;
1639
1640 for (int gridY = 0; gridY < gridHeight; gridY++)
1641 {
1642 for (int gridX = 0; gridX < gridWidth; gridX++)
1643 {
1644 const int curX = cellWidth*gridX;
1645 const int curY = cellHeight*gridY;
1646 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth;
1647 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight;
1648 const int cellNdx = gridY*gridWidth + gridX;
1649
1650 getReferenceParams(refParams, cellNdx);
1651
1652 refParams.imageViewMinLodMode = imageViewLodMode;
1653
1654 // Compute texcoord.
1655 if (refParams.samplerType == glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT)
1656 getBasicTexCoord3DImageViewMinlodIntTexCoord(texCoord);
1657 else
1658 getBasicTexCoord3D(texCoord, cellNdx);
1659
1660 // Render ideal result
1661 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH),
1662 refTexture, &texCoord[0], refParams);
1663
1664 // Compare this cell
1665 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH),
1666 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH),
1667 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH),
1668 m_texture->getTexture(), &texCoord[0], refParams,
1669 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog());
1670 }
1671 }
1672 if (numFailedPixels > 0)
1673 {
1674 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame)
1675 << TestLog::Image("ErrorMask", "Error mask", errorMask);
1676 }
1677
1678 return numFailedPixels;
1679 };
1680
1681 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result")
1682 << TestLog::Image("Rendered", "Rendered image", renderedFrame);
1683
1684 int numFailedPixels = compareAndLogImages();
1685
1686 if (numFailedPixels > 0 && refParams.imageViewMinLod > 0.0f)
1687 {
1688 numFailedPixels = compareAndLogImages(tcu::IMAGEVIEWMINLODMODE_ALTERNATIVE);
1689 }
1690 m_context.getTestContext().getLog() << TestLog::EndImageSet;
1691
1692 if (numFailedPixels > 0)
1693 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage;
1694
1695 {
1696 const bool isOk = numFailedPixels == 0;
1697 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail");
1698 }
1699 }
1700 }
1701
1702 class Texture3DMinLodTestInstance : public Texture3DLodControlTestInstance
1703 {
1704 public:
Texture3DMinLodTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1705 Texture3DMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1706 : Texture3DLodControlTestInstance(context, testParameters)
1707 {
1708 }
1709
1710 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1711 void getReferenceParams (ReferenceParams& params, int cellNdx)
1712 {
1713 params.minLod = getMinLodForCell(cellNdx);
1714 }
1715 };
1716
1717 class Texture3DMaxLodTestInstance : public Texture3DLodControlTestInstance
1718 {
1719 public:
Texture3DMaxLodTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1720 Texture3DMaxLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1721 : Texture3DLodControlTestInstance(context, testParameters)
1722 {
1723 }
1724
1725 protected:
getReferenceParams(ReferenceParams & params,int cellNdx)1726 void getReferenceParams (ReferenceParams& params, int cellNdx)
1727 {
1728 params.maxLod = getMaxLodForCell(cellNdx);
1729 }
1730 };
1731
1732 class Texture3DBaseLevelTestInstance : public Texture3DLodControlTestInstance
1733 {
1734 public:
Texture3DBaseLevelTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1735 Texture3DBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1736 : Texture3DLodControlTestInstance(context, testParameters)
1737 ,m_testParam (testParameters)
1738 {
1739 }
1740
1741 protected:
1742 const Texture3DMipmapTestCaseParameters m_testParam;
1743
getBaseLevel(int cellNdx) const1744 int getBaseLevel (int cellNdx) const
1745 {
1746 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
1747 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;
1748
1749 return baseLevel;
1750 }
1751
getReferenceParams(ReferenceParams & params,int cellNdx)1752 void getReferenceParams (ReferenceParams& params, int cellNdx)
1753 {
1754 params.baseLevel = getBaseLevel(cellNdx);
1755 }
1756 };
1757
1758 class Texture3DMaxLevelTestInstance : public Texture3DLodControlTestInstance
1759 {
1760 public:
Texture3DMaxLevelTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1761 Texture3DMaxLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1762 : Texture3DLodControlTestInstance(context, testParameters)
1763 ,m_testParam (testParameters)
1764 {
1765 }
1766
1767 protected:
1768 const Texture3DMipmapTestCaseParameters m_testParam;
1769
getMaxLevel(int cellNdx) const1770 int getMaxLevel (int cellNdx) const
1771 {
1772 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
1773 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x9111e7) % numLevels;
1774
1775 return maxLevel;
1776 }
1777
getReferenceParams(ReferenceParams & params,int cellNdx)1778 void getReferenceParams (ReferenceParams& params, int cellNdx)
1779 {
1780 params.maxLevel = getMaxLevel(cellNdx);
1781 }
1782 };
1783
1784 #ifndef CTS_USES_VULKANSC
1785
1786 class Texture2DImageViewMinLodTestInstance : public Texture2DLodControlTestInstance
1787 {
1788 public:
Texture2DImageViewMinLodTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1789 Texture2DImageViewMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1790 : Texture2DLodControlTestInstance(context, testParameters)
1791 {
1792 }
1793
1794 protected:
1795
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1796 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1797 {
1798 de::Random rnd(cellNdx + 1);
1799
1800 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1801 float minBaseLevel = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1802 return rnd.getFloat(minBaseLevel, (float)maxLevel);
1803 }
1804
getReferenceParams(ReferenceParams & params,int cellNdx)1805 void getReferenceParams (ReferenceParams& params, int cellNdx)
1806 {
1807 params.minLod = getMinLodForCell(cellNdx);
1808 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1809 }
1810 };
1811
1812 class Texture2DImageViewMinLodBaseLevelTestInstance : public Texture2DLodControlTestInstance
1813 {
1814 public:
Texture2DImageViewMinLodBaseLevelTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1815 Texture2DImageViewMinLodBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1816 : Texture2DLodControlTestInstance(context, testParameters)
1817 , m_testParam (testParameters)
1818 {
1819 }
1820
1821 protected:
1822 const Texture2DMipmapTestCaseParameters m_testParam;
1823
getBaseLevel(int cellNdx) const1824 int getBaseLevel (int cellNdx) const
1825 {
1826 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
1827 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;
1828
1829 return baseLevel;
1830 }
1831
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1832 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1833 {
1834 de::Random rnd(cellNdx + 1);
1835
1836 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1837 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1838 return rnd.getFloat(minValue, (float)maxLevel);
1839 }
1840
getReferenceParams(ReferenceParams & params,int cellNdx)1841 void getReferenceParams (ReferenceParams& params, int cellNdx)
1842 {
1843 params.baseLevel = getBaseLevel(cellNdx);
1844 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1845 }
1846 };
1847
1848 class Texture3DImageViewMinLodTestInstance : public Texture3DLodControlTestInstance
1849 {
1850 public:
Texture3DImageViewMinLodTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1851 Texture3DImageViewMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1852 : Texture3DLodControlTestInstance(context, testParameters)
1853 {
1854 }
1855
1856 protected:
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1857 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1858 {
1859 de::Random rnd(cellNdx + 1);
1860
1861 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1862 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1863 return rnd.getFloat(minValue, (float)maxLevel);
1864 }
1865
getReferenceParams(ReferenceParams & params,int cellNdx)1866 void getReferenceParams (ReferenceParams& params, int cellNdx)
1867 {
1868 params.minLod = getMinLodForCell(cellNdx);
1869 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1870 }
1871 };
1872
1873 class Texture3DImageViewMinLodBaseLevelTestInstance : public Texture3DLodControlTestInstance
1874 {
1875 public:
Texture3DImageViewMinLodBaseLevelTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)1876 Texture3DImageViewMinLodBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
1877 : Texture3DLodControlTestInstance(context, testParameters)
1878 , m_testParam (testParameters)
1879 {
1880 }
1881
1882 protected:
1883 const Texture3DMipmapTestCaseParameters m_testParam;
1884
getBaseLevel(int cellNdx) const1885 int getBaseLevel (int cellNdx) const
1886 {
1887 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
1888 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;
1889
1890 return baseLevel;
1891 }
1892
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1893 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1894 {
1895 de::Random rnd(cellNdx + 1);
1896
1897 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1898 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1899 return rnd.getFloat(minValue, (float)maxLevel);
1900 }
1901
getReferenceParams(ReferenceParams & params,int cellNdx)1902 void getReferenceParams (ReferenceParams& params, int cellNdx)
1903 {
1904 params.baseLevel = getBaseLevel(cellNdx);
1905 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1906
1907 }
1908 };
1909
1910 class TextureCubeImageViewMinLodTestInstance : public TextureCubeLodControlTestInstance
1911 {
1912 public:
TextureCubeImageViewMinLodTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1913 TextureCubeImageViewMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1914 : TextureCubeLodControlTestInstance(context, testParameters)
1915 {
1916 }
1917
1918 protected:
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1919 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1920 {
1921 de::Random rnd(cellNdx + 1);
1922
1923 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1924 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1925 return rnd.getFloat(minValue, (float)maxLevel);
1926 }
1927
getReferenceParams(ReferenceParams & params,int cellNdx)1928 void getReferenceParams (ReferenceParams& params, int cellNdx)
1929 {
1930 params.minLod = getMinLodForCell(cellNdx);
1931 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1932 }
1933 };
1934
1935 class TextureCubeImageViewMinLodBaseLevelTestInstance : public TextureCubeLodControlTestInstance
1936 {
1937 public:
TextureCubeImageViewMinLodBaseLevelTestInstance(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)1938 TextureCubeImageViewMinLodBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
1939 : TextureCubeLodControlTestInstance(context, testParameters)
1940 , m_testParam (testParameters)
1941 {
1942 }
1943
1944 protected:
1945 const TextureCubeMipmapTestCaseParameters m_testParam;
1946
getBaseLevel(int cellNdx) const1947 int getBaseLevel (int cellNdx) const
1948 {
1949 const int numLevels = deLog2Floor32(m_texSize)+1;
1950 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels;
1951
1952 return baseLevel;
1953 }
1954
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1955 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1956 {
1957 de::Random rnd(cellNdx + 1);
1958
1959 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1960 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1961 return rnd.getFloat(minValue, (float)maxLevel);
1962 }
1963
getReferenceParams(ReferenceParams & params,int cellNdx)1964 void getReferenceParams (ReferenceParams& params, int cellNdx)
1965 {
1966 params.baseLevel = getBaseLevel(cellNdx);
1967 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
1968 }
1969 };
1970
1971 class Texture2DImageViewMinLodIntTexCoordTestInstance : public Texture2DLodControlTestInstance
1972 {
1973 public:
Texture2DImageViewMinLodIntTexCoordTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)1974 Texture2DImageViewMinLodIntTexCoordTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
1975 : Texture2DLodControlTestInstance(context, testParameters)
1976 , m_testParam (testParameters)
1977 {
1978 }
1979
1980 protected:
1981 const Texture2DMipmapTestCaseParameters m_testParam;
1982
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const1983 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
1984 {
1985 de::Random rnd(cellNdx + 1);
1986
1987 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
1988 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
1989 return rnd.getFloat(minValue, (float)maxLevel);
1990 }
1991
getLodTexelFetch(int cellNdx,int baseLevel,int maxLevel) const1992 int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
1993 {
1994 de::Random rnd(cellNdx + 1);
1995 return rnd.getInt(baseLevel, maxLevel) - baseLevel;
1996 }
1997
getReferenceParams(ReferenceParams & params,int cellNdx)1998 void getReferenceParams (ReferenceParams& params, int cellNdx)
1999 {
2000 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
2001 params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
2002 params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
2003 }
2004 };
2005
2006 class Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance : public Texture2DLodControlTestInstance
2007 {
2008 public:
Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)2009 Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
2010 : Texture2DLodControlTestInstance(context, testParameters)
2011 , m_testParam (testParameters)
2012 {
2013 }
2014
2015 protected:
2016 const Texture2DMipmapTestCaseParameters m_testParam;
2017
getBaseLevel(int cellNdx) const2018 int getBaseLevel (int cellNdx) const
2019 {
2020 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1;
2021 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels;
2022
2023 return baseLevel;
2024 }
2025
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const2026 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
2027 {
2028 de::Random rnd(cellNdx + 1);
2029
2030 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
2031 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
2032 return rnd.getFloat(minValue, (float)maxLevel);
2033 }
2034
getLodTexelFetch(int cellNdx,int baseLevel,int maxLevel) const2035 int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
2036 {
2037 de::Random rnd(cellNdx + 1);
2038 return rnd.getInt(baseLevel, maxLevel) - baseLevel;
2039 }
2040
getReferenceParams(ReferenceParams & params,int cellNdx)2041 void getReferenceParams (ReferenceParams& params, int cellNdx)
2042 {
2043 params.baseLevel = getBaseLevel(cellNdx);
2044 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
2045 params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
2046 params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
2047 }
2048 };
2049
2050 class Texture2DImageViewMinLodIntTexCoordTest : public vkt::TestCase
2051 {
2052 public:
2053 Texture2DImageViewMinLodIntTexCoordTest (tcu::TestContext& testContext,
2054 const string& name,
2055 const string& description,
2056 const Texture2DMipmapTestCaseParameters& params);
2057 ~Texture2DImageViewMinLodIntTexCoordTest (void);
2058 void initPrograms (SourceCollections& sourceCollections) const;
2059 TestInstance* createInstance (Context& context) const;
2060 void checkSupport (Context& context) const;
2061
2062 protected:
2063 const Texture2DMipmapTestCaseParameters m_params;
2064 };
2065
Texture2DImageViewMinLodIntTexCoordTest(tcu::TestContext & testContext,const string & name,const string & description,const Texture2DMipmapTestCaseParameters & params)2066 Texture2DImageViewMinLodIntTexCoordTest::Texture2DImageViewMinLodIntTexCoordTest (tcu::TestContext& testContext,
2067 const string& name,
2068 const string& description,
2069 const Texture2DMipmapTestCaseParameters& params)
2070 : vkt::TestCase (testContext, name, description)
2071 , m_params (params)
2072 {
2073 }
2074
~Texture2DImageViewMinLodIntTexCoordTest(void)2075 Texture2DImageViewMinLodIntTexCoordTest::~Texture2DImageViewMinLodIntTexCoordTest (void)
2076 {
2077 }
2078
initPrograms(SourceCollections & sourceCollections) const2079 void Texture2DImageViewMinLodIntTexCoordTest::initPrograms(SourceCollections& sourceCollections) const
2080 {
2081 static const char* vertShader =
2082 "#version 450\n"
2083 "layout(location = 0) in vec4 a_position;\n"
2084 "layout(location = 1) in vec2 a_texCoord;\n"
2085 "out gl_PerVertex { vec4 gl_Position; };\n"
2086 "\n"
2087 "void main (void)\n"
2088 "{\n"
2089 " gl_Position = a_position;\n"
2090 "}\n";
2091
2092 static const char* fragShader =
2093 "#version 450\n"
2094 "layout(location = 0) out vec4 outColor;\n"
2095 "layout (set=0, binding=0, std140) uniform Block \n"
2096 "{\n"
2097 " float u_bias;\n"
2098 " float u_ref;\n"
2099 " vec4 u_colorScale;\n"
2100 " vec4 u_colorBias;\n"
2101 " int u_lod;\n"
2102 "};\n\n"
2103 "layout (set=1, binding=0) uniform sampler2D u_sampler;\n"
2104 "void main (void)\n"
2105 "{\n"
2106 " ivec2 texCoord = ivec2(0,0);\n" // Sampling always from the same coord, we are only interested on the lod.
2107 " outColor = texelFetch(u_sampler, texCoord, u_lod) * u_colorScale + u_colorBias;\n"
2108 "}\n";
2109 sourceCollections.glslSources.add("vertex_2D_FETCH_LOD") << glu::VertexSource(vertShader);
2110 sourceCollections.glslSources.add("fragment_2D_FETCH_LOD") << glu::FragmentSource(fragShader);
2111 }
2112
checkSupport(Context & context) const2113 void Texture2DImageViewMinLodIntTexCoordTest::checkSupport(Context& context) const
2114 {
2115 DE_ASSERT(m_params.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD);
2116
2117 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2118 context.requireDeviceFunctionality("VK_EXT_robustness2");
2119 vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
2120 imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
2121 imageViewMinLodFeatures.pNext = DE_NULL;
2122
2123 VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features;
2124 robustness2Features.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
2125 robustness2Features.pNext = &imageViewMinLodFeatures;
2126 vk::VkPhysicalDeviceFeatures2 features2;
2127
2128 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2129 features2.pNext = &robustness2Features;
2130
2131 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2132
2133 if (imageViewMinLodFeatures.minLod == DE_FALSE)
2134 TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
2135
2136 if (robustness2Features.robustImageAccess2 == DE_FALSE)
2137 TCU_THROW(NotSupportedError, "VK_EXT_robustness2 robustImageAccess2 feature not supported");
2138 }
2139
createInstance(Context & context) const2140 TestInstance* Texture2DImageViewMinLodIntTexCoordTest::createInstance(Context& context) const
2141 {
2142 if (m_params.testType == util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD)
2143 return new Texture2DImageViewMinLodIntTexCoordTestInstance(context, m_params);
2144 else
2145 return new Texture2DImageViewMinLodBaseLevelIntTexCoordTestInstance(context, m_params);
2146 }
2147
2148 class Texture3DImageViewMinLodIntTexCoordTestInstance : public Texture3DLodControlTestInstance
2149 {
2150 public:
Texture3DImageViewMinLodIntTexCoordTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)2151 Texture3DImageViewMinLodIntTexCoordTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
2152 : Texture3DLodControlTestInstance(context, testParameters)
2153 , m_testParam (testParameters)
2154 {
2155 }
2156
2157 protected:
2158 const Texture3DMipmapTestCaseParameters m_testParam;
2159
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const2160 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
2161 {
2162 de::Random rnd(cellNdx + 1);
2163
2164 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
2165 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
2166 return rnd.getFloat(minValue, (float)maxLevel);
2167 }
2168
getLodTexelFetch(int cellNdx,int baseLevel,int maxLevel) const2169 int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
2170 {
2171 de::Random rnd(cellNdx + 1);
2172 return rnd.getInt(baseLevel, maxLevel) - baseLevel;
2173 }
2174
getReferenceParams(ReferenceParams & params,int cellNdx)2175 void getReferenceParams (ReferenceParams& params, int cellNdx)
2176 {
2177 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
2178 params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
2179 params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
2180 }
2181 };
2182
2183 class Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance : public Texture3DLodControlTestInstance
2184 {
2185 public:
Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)2186 Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
2187 : Texture3DLodControlTestInstance(context, testParameters)
2188 , m_testParam (testParameters)
2189 {
2190 }
2191
2192 protected:
2193 const Texture3DMipmapTestCaseParameters m_testParam;
2194
getBaseLevel(int cellNdx) const2195 int getBaseLevel (int cellNdx) const
2196 {
2197 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1;
2198 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels;
2199
2200 return baseLevel;
2201 }
2202
getImageViewMinLod(int cellNdx,int baseLevel,int maxLevel) const2203 float getImageViewMinLod (int cellNdx, int baseLevel, int maxLevel) const
2204 {
2205 de::Random rnd(cellNdx + 1);
2206
2207 // baselevel + 1.0 as minimum, to test that minLod is working. If we go over the maximum, use that instead.
2208 float minValue = de::min((float)baseLevel + 1.0f, (float)maxLevel);
2209 return rnd.getFloat(minValue, (float)maxLevel);
2210 }
2211
getLodTexelFetch(int cellNdx,int baseLevel,int maxLevel) const2212 int getLodTexelFetch (int cellNdx, int baseLevel, int maxLevel) const
2213 {
2214 de::Random rnd(cellNdx + 1);
2215 return rnd.getInt(baseLevel, maxLevel) - baseLevel;
2216 }
2217
getReferenceParams(ReferenceParams & params,int cellNdx)2218 void getReferenceParams (ReferenceParams& params, int cellNdx)
2219 {
2220 params.baseLevel = getBaseLevel(cellNdx);
2221 params.imageViewMinLod = getImageViewMinLod(cellNdx, params.baseLevel, params.maxLevel);
2222 params.samplerType = glu::TextureTestUtil::SAMPLERTYPE_FETCH_FLOAT;
2223 params.lodTexelFetch = getLodTexelFetch(cellNdx, params.baseLevel, params.maxLevel);
2224 }
2225 };
2226
2227 class Texture3DImageViewMinLodIntTexCoordTest : public vkt::TestCase
2228 {
2229 public:
2230 Texture3DImageViewMinLodIntTexCoordTest (tcu::TestContext& testContext,
2231 const string& name,
2232 const string& description,
2233 const Texture3DMipmapTestCaseParameters& params);
2234 ~Texture3DImageViewMinLodIntTexCoordTest (void);
2235 void initPrograms (SourceCollections& sourceCollections) const;
2236 TestInstance* createInstance (Context& context) const;
2237 void checkSupport (Context& context) const;
2238
2239 protected:
2240 const Texture3DMipmapTestCaseParameters m_params;
2241 };
2242
Texture3DImageViewMinLodIntTexCoordTest(tcu::TestContext & testContext,const string & name,const string & description,const Texture3DMipmapTestCaseParameters & params)2243 Texture3DImageViewMinLodIntTexCoordTest::Texture3DImageViewMinLodIntTexCoordTest (tcu::TestContext& testContext,
2244 const string& name,
2245 const string& description,
2246 const Texture3DMipmapTestCaseParameters& params)
2247 : vkt::TestCase (testContext, name, description)
2248 , m_params (params)
2249 {
2250 }
2251
~Texture3DImageViewMinLodIntTexCoordTest(void)2252 Texture3DImageViewMinLodIntTexCoordTest::~Texture3DImageViewMinLodIntTexCoordTest (void)
2253 {
2254 }
2255
initPrograms(SourceCollections & sourceCollections) const2256 void Texture3DImageViewMinLodIntTexCoordTest::initPrograms(SourceCollections& sourceCollections) const
2257 {
2258 static const char* vertShader =
2259 "#version 450\n"
2260 "layout(location = 0) in vec4 a_position;\n"
2261 "layout(location = 1) in vec3 a_texCoord;\n"
2262 "out gl_PerVertex { vec4 gl_Position; };\n"
2263 "\n"
2264 "void main (void)\n"
2265 "{\n"
2266 " gl_Position = a_position;\n"
2267 "}\n";
2268
2269 static const char* fragShader =
2270 "#version 450\n"
2271 "layout(location = 0) out vec4 outColor;\n"
2272 "layout (set=0, binding=0, std140) uniform Block \n"
2273 "{\n"
2274 " float u_bias;\n"
2275 " float u_ref;\n"
2276 " vec4 u_colorScale;\n"
2277 " vec4 u_colorBias;\n"
2278 " int u_lod;\n"
2279 "};\n\n"
2280 "layout (set=1, binding=0) uniform sampler3D u_sampler;\n"
2281 "void main (void)\n"
2282 "{\n"
2283 " ivec3 texCoord = ivec3(0,0,0);\n" // Sampling always from the same coord, we are only interested on the lod.
2284 " outColor = texelFetch(u_sampler, texCoord, u_lod) * u_colorScale + u_colorBias;\n"
2285 "}\n";
2286 sourceCollections.glslSources.add("vertex_3D_FETCH_LOD") << glu::VertexSource(vertShader);
2287 sourceCollections.glslSources.add("fragment_3D_FETCH_LOD") << glu::FragmentSource(fragShader);
2288 }
2289
checkSupport(Context & context) const2290 void Texture3DImageViewMinLodIntTexCoordTest::checkSupport(Context& context) const
2291 {
2292 DE_ASSERT(m_params.testType > util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD);
2293
2294 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2295 context.requireDeviceFunctionality("VK_EXT_robustness2");
2296 vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
2297 imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
2298 imageViewMinLodFeatures.pNext = DE_NULL;
2299
2300 VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features;
2301 robustness2Features.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
2302 robustness2Features.pNext = &imageViewMinLodFeatures;
2303 vk::VkPhysicalDeviceFeatures2 features2;
2304
2305 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2306 features2.pNext = &robustness2Features;
2307
2308 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2309
2310 if (imageViewMinLodFeatures.minLod == DE_FALSE)
2311 TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
2312
2313 if (robustness2Features.robustImageAccess2 == DE_FALSE)
2314 TCU_THROW(NotSupportedError, "VK_EXT_robustness2 robustImageAccess2 feature not supported");
2315 }
2316
createInstance(Context & context) const2317 TestInstance* Texture3DImageViewMinLodIntTexCoordTest::createInstance(Context& context) const
2318 {
2319 if (m_params.testType == util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD)
2320 return new Texture3DImageViewMinLodIntTexCoordTestInstance(context, m_params);
2321 else
2322 return new Texture3DImageViewMinLodBaseLevelIntTexCoordTestInstance(context, m_params);
2323 }
2324
2325 // Texture gather tests.
2326 enum class GatherMinLod
2327 {
2328 MINLOD_0_1, // 0.1
2329 MINLOD_1_1, // 1.1
2330 };
2331
2332 struct GatherParams
2333 {
2334 uint32_t randomSeed; // Seed for the pseudorandom number generator.
2335 GatherMinLod minLod; // Idea: make it 0.1 or 1.1
2336 int component; // 0, 1, 2, 3 for the gather operation.
2337
getNumericMinLodvkt::texture::__anon60d989fa0111::GatherParams2338 float getNumericMinLod (void) const
2339 {
2340 float lod = 0.0f;
2341
2342 switch (minLod)
2343 {
2344 case GatherMinLod::MINLOD_0_1: lod = 0.1f; break;
2345 case GatherMinLod::MINLOD_1_1: lod = 1.1f; break;
2346 default: DE_ASSERT(false); break;
2347 }
2348
2349 return lod;
2350 }
2351
getMinLodIntegervkt::texture::__anon60d989fa0111::GatherParams2352 uint32_t getMinLodInteger (void) const
2353 {
2354 uint32_t lod = 0u;
2355
2356 switch (minLod)
2357 {
2358 case GatherMinLod::MINLOD_0_1: lod = 0u; break;
2359 case GatherMinLod::MINLOD_1_1: lod = 1u; break;
2360 default: DE_ASSERT(false); break;
2361 }
2362
2363 return lod;
2364 }
2365
needsRobustness2vkt::texture::__anon60d989fa0111::GatherParams2366 bool needsRobustness2 (void) const
2367 {
2368 return (getNumericMinLod() >= 1.0f);
2369 }
2370 };
2371
2372 class TextureGatherMinLodTest : public vkt::TestCase
2373 {
2374 public:
TextureGatherMinLodTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const GatherParams & params)2375 TextureGatherMinLodTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const GatherParams& params)
2376 : vkt::TestCase (testCtx, name, description)
2377 , m_params (params)
2378 {}
~TextureGatherMinLodTest(void)2379 virtual ~TextureGatherMinLodTest (void) {}
2380
2381 void initPrograms (vk::SourceCollections& programCollection) const override;
2382 TestInstance* createInstance (Context& context) const override;
2383 void checkSupport (Context& context) const override;
2384
2385 protected:
2386 GatherParams m_params;
2387 };
2388
2389 class TextureGatherMinLodInstance : public vkt::TestInstance
2390 {
2391 public:
TextureGatherMinLodInstance(Context & context,const GatherParams & params)2392 TextureGatherMinLodInstance (Context& context, const GatherParams& params)
2393 : vkt::TestInstance (context)
2394 , m_params (params)
2395 {}
~TextureGatherMinLodInstance(void)2396 virtual ~TextureGatherMinLodInstance (void) {}
2397
2398 tcu::TestStatus iterate (void) override;
2399
2400 protected:
2401 GatherParams m_params;
2402 };
2403
2404 // Test idea: create texture with 3 levels, each of them having a unique nonzero color. Render gathering the color from a fixed
2405 // position in that texture (center point). Use the minLod parameter when creating the view to control which one should be the
2406 // output color. If minLod is 0.1, minLodInteger should be 0 and gathering from the base level is defined, so we should get the
2407 // output color from the base level. If minLod is 1.1, gathering texels from the base level requires robustness2 and will result in
2408 // zeros instead of the color from levels 0 or 1.
initPrograms(vk::SourceCollections & programCollection) const2409 void TextureGatherMinLodTest::initPrograms (vk::SourceCollections &programCollection) const
2410 {
2411 // Full screen triangle covering the whole viewport.
2412 std::ostringstream vert;
2413 vert
2414 << "#version 450\n"
2415 << "\n"
2416 << "vec2 positions[3] = vec2[](\n"
2417 << " vec2(-1.0, -1.0),\n"
2418 << " vec2(3.0, -1.0),\n"
2419 << " vec2(-1.0, 3.0)\n"
2420 << ");\n"
2421 << "\n"
2422 << "void main (void)\n"
2423 << "{\n"
2424 << " gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);\n"
2425 << "}\n"
2426 ;
2427 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2428
2429 std::ostringstream frag;
2430 frag
2431 << "#version 450\n"
2432 << "\n"
2433 << "layout (location=0) out vec4 outColor;\n"
2434 << "layout (set=0, binding=0) uniform sampler2D u_sampler;\n"
2435 << "\n"
2436 << "void main (void)\n"
2437 << "{\n"
2438 << " const vec2 gatherCoords = vec2(0.5, 0.5);\n"
2439 << " const vec4 gatherRes = textureGather(u_sampler, gatherCoords, " << m_params.component << ");\n"
2440 << " outColor = vec4(gatherRes.xyz, 1.0);\n"
2441 << "}\n";
2442 ;
2443 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2444 }
2445
checkSupport(Context & context) const2446 void TextureGatherMinLodTest::checkSupport (Context& context) const
2447 {
2448 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
2449 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2450
2451 if (m_params.needsRobustness2())
2452 {
2453 context.requireDeviceFunctionality("VK_EXT_robustness2");
2454
2455 VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = initVulkanStructure();
2456 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&robustness2Features);
2457
2458 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2459
2460 if (robustness2Features.robustImageAccess2 == DE_FALSE)
2461 TCU_THROW(NotSupportedError, "robustImageAccess2 not supported");
2462 }
2463 }
2464
createInstance(Context & context) const2465 TestInstance* TextureGatherMinLodTest::createInstance (Context& context) const
2466 {
2467 return new TextureGatherMinLodInstance(context, m_params);
2468 }
2469
2470 // Device helper: this is needed because we sometimes need a custom device with robustImageAccess2.
2471 class DeviceHelper
2472 {
2473 public:
~DeviceHelper()2474 virtual ~DeviceHelper () {}
2475 virtual const DeviceInterface& getDeviceInterface (void) const = 0;
2476 virtual VkDevice getDevice (void) const = 0;
2477 virtual uint32_t getQueueFamilyIndex (void) const = 0;
2478 virtual VkQueue getQueue (void) const = 0;
2479 virtual Allocator& getAllocator (void) const = 0;
2480 };
2481
2482 // This one just reuses the default device from the context.
2483 class ContextDeviceHelper : public DeviceHelper
2484 {
2485 public:
ContextDeviceHelper(Context & context)2486 ContextDeviceHelper (Context& context)
2487 : m_deviceInterface (context.getDeviceInterface())
2488 , m_device (context.getDevice())
2489 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
2490 , m_queue (context.getUniversalQueue())
2491 , m_allocator (context.getDefaultAllocator())
2492 {}
2493
~ContextDeviceHelper()2494 virtual ~ContextDeviceHelper () {}
2495
getDeviceInterface(void) const2496 const DeviceInterface& getDeviceInterface (void) const override { return m_deviceInterface; }
getDevice(void) const2497 VkDevice getDevice (void) const override { return m_device; }
getQueueFamilyIndex(void) const2498 uint32_t getQueueFamilyIndex (void) const override { return m_queueFamilyIndex; }
getQueue(void) const2499 VkQueue getQueue (void) const override { return m_queue; }
getAllocator(void) const2500 Allocator& getAllocator (void) const override { return m_allocator; }
2501
2502 protected:
2503 const DeviceInterface& m_deviceInterface;
2504 const VkDevice m_device;
2505 const uint32_t m_queueFamilyIndex;
2506 const VkQueue m_queue;
2507 Allocator& m_allocator;
2508 };
2509
2510 // This one creates a new device with robustImageAccess2.
2511 class RobustImageAccess2DeviceHelper : public DeviceHelper
2512 {
2513 public:
RobustImageAccess2DeviceHelper(Context & context)2514 RobustImageAccess2DeviceHelper (Context& context)
2515 {
2516 const auto& vkp = context.getPlatformInterface();
2517 const auto& vki = context.getInstanceInterface();
2518 const auto instance = context.getInstance();
2519 const auto physicalDevice = context.getPhysicalDevice();
2520 const auto queuePriority = 1.0f;
2521
2522 // Queue index first.
2523 m_queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2524
2525 // Create a universal queue that supports graphics and compute.
2526 const VkDeviceQueueCreateInfo queueParams =
2527 {
2528 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
2529 DE_NULL, // const void* pNext;
2530 0u, // VkDeviceQueueCreateFlags flags;
2531 m_queueFamilyIndex, // deUint32 queueFamilyIndex;
2532 1u, // deUint32 queueCount;
2533 &queuePriority // const float* pQueuePriorities;
2534 };
2535
2536 const char* extensions[] =
2537 {
2538 "VK_EXT_robustness2",
2539 };
2540
2541 VkPhysicalDeviceImageViewMinLodFeaturesEXT minLodfeatures = initVulkanStructure();
2542 VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = initVulkanStructure(&minLodfeatures);
2543 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&robustness2Features);
2544
2545 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
2546
2547 const VkDeviceCreateInfo deviceCreateInfo =
2548 {
2549 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
2550 &features2, //pNext;
2551 0u, //flags
2552 1u, //queueRecordCount;
2553 &queueParams, //pRequestedQueues;
2554 0u, //layerCount;
2555 nullptr, //ppEnabledLayerNames;
2556 static_cast<uint32_t>(de::arrayLength(extensions)), // deUint32 enabledExtensionCount;
2557 extensions, // const char* const* ppEnabledExtensionNames;
2558 nullptr, //pEnabledFeatures;
2559 };
2560
2561 m_device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &deviceCreateInfo);
2562 m_vkd .reset(new DeviceDriver(vkp, instance, m_device.get()));
2563 m_queue = getDeviceQueue(*m_vkd, *m_device, m_queueFamilyIndex, 0u);
2564 m_allocator .reset(new SimpleAllocator(*m_vkd, m_device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
2565 }
2566
~RobustImageAccess2DeviceHelper()2567 virtual ~RobustImageAccess2DeviceHelper () {}
2568
getDeviceInterface(void) const2569 const DeviceInterface& getDeviceInterface (void) const override { return *m_vkd; }
getDevice(void) const2570 VkDevice getDevice (void) const override { return m_device.get(); }
getQueueFamilyIndex(void) const2571 uint32_t getQueueFamilyIndex (void) const override { return m_queueFamilyIndex; }
getQueue(void) const2572 VkQueue getQueue (void) const override { return m_queue; }
getAllocator(void) const2573 Allocator& getAllocator (void) const override { return *m_allocator; }
2574
2575 protected:
2576 Move<VkDevice> m_device;
2577 std::unique_ptr<DeviceDriver> m_vkd;
2578 deUint32 m_queueFamilyIndex;
2579 VkQueue m_queue;
2580 std::unique_ptr<SimpleAllocator> m_allocator;
2581 };
2582
2583 std::unique_ptr<DeviceHelper> g_robustness2DeviceHelper;
2584 std::unique_ptr<DeviceHelper> g_contextDeviceHelper;
2585
getDeviceHelper(Context & context,bool needsRobustness2)2586 DeviceHelper& getDeviceHelper (Context& context, bool needsRobustness2)
2587 {
2588 if (needsRobustness2)
2589 {
2590 if (!g_robustness2DeviceHelper)
2591 g_robustness2DeviceHelper.reset(new RobustImageAccess2DeviceHelper(context));
2592 return *g_robustness2DeviceHelper;
2593 }
2594
2595 if (!g_contextDeviceHelper)
2596 g_contextDeviceHelper.reset(new ContextDeviceHelper(context));
2597 return *g_contextDeviceHelper;
2598 }
2599
2600 // Cleanup function for the test group.
destroyDeviceHelpers(tcu::TestCaseGroup *)2601 void destroyDeviceHelpers (tcu::TestCaseGroup*)
2602 {
2603 g_robustness2DeviceHelper.reset(nullptr);
2604 g_contextDeviceHelper.reset(nullptr);
2605 }
2606
iterate(void)2607 tcu::TestStatus TextureGatherMinLodInstance::iterate (void)
2608 {
2609 const auto& deviceHelper = getDeviceHelper(m_context, m_params.needsRobustness2());
2610 const auto& vkd = deviceHelper.getDeviceInterface();
2611 const auto device = deviceHelper.getDevice();
2612 const auto queueIndex = deviceHelper.getQueueFamilyIndex();
2613 const auto queue = deviceHelper.getQueue();
2614 auto& alloc = deviceHelper.getAllocator();
2615
2616 const auto imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
2617 const auto tcuFormat = mapVkFormat(imageFormat);
2618 const auto colorExtent = makeExtent3D(1u, 1u, 1u);
2619 const tcu::IVec3 iColorExtent (static_cast<int>(colorExtent.width), static_cast<int>(colorExtent.height), static_cast<int>(colorExtent.depth));
2620 const auto texExtent = makeExtent3D(8u, 8u, 1u);
2621 const auto texMipLevels = 3u;
2622 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
2623 const auto texUsage = (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
2624 const auto minLodF = m_params.getNumericMinLod();
2625 const auto minLodU = m_params.getMinLodInteger();
2626 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f);
2627
2628 // Color attachment: a simple 1x1 image.
2629 const VkImageCreateInfo colorCreateInfo =
2630 {
2631 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2632 nullptr, // const void* pNext;
2633 0u, // VkImageCreateFlags flags;
2634 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2635 imageFormat, // VkFormat format;
2636 colorExtent, // VkExtent3D extent;
2637 1u, // uint32_t mipLevels;
2638 1u, // uint32_t arrayLayers;
2639 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2640 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2641 colorUsage, // VkImageUsageFlags usage;
2642 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2643 0u, // uint32_t queueFamilyIndexCount;
2644 nullptr, // const uint32_t* pQueueFamilyIndices;
2645 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2646 };
2647
2648 ImageWithMemory colorBuffer (vkd, device, alloc, colorCreateInfo, MemoryRequirement::Any);
2649 const auto colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2650 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2651 const auto colorBufferView = makeImageView(vkd, device, colorBuffer.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, colorSRR);
2652
2653 // Texture: an 8x8 image with several mip levels.
2654 const VkImageCreateInfo texCreateInfo =
2655 {
2656 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2657 nullptr, // const void* pNext;
2658 0u, // VkImageCreateFlags flags;
2659 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2660 imageFormat, // VkFormat format;
2661 texExtent, // VkExtent3D extent;
2662 texMipLevels, // uint32_t mipLevels;
2663 1u, // uint32_t arrayLayers;
2664 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2665 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2666 texUsage, // VkImageUsageFlags usage;
2667 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2668 0u, // uint32_t queueFamilyIndexCount;
2669 nullptr, // const uint32_t* pQueueFamilyIndices;
2670 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2671 };
2672
2673 ImageWithMemory texture (vkd, device, alloc, texCreateInfo, MemoryRequirement::Any);
2674 const auto texSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, texMipLevels, 0u, 1u);
2675
2676 DE_ASSERT(texMipLevels > 0u);
2677 DE_ASSERT(minLodU < texMipLevels);
2678
2679 const VkImageViewMinLodCreateInfoEXT texMinLodInfo =
2680 {
2681 VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT, // VkStructureType sType;
2682 nullptr, // const void* pNext;
2683 minLodF, // float minLod;
2684 };
2685
2686 const VkImageViewCreateInfo texViewCreateInfo =
2687 {
2688 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2689 &texMinLodInfo, // const void* pNext;
2690 0u, // VkImageViewCreateFlags flags;
2691 texture.get(), // VkImage image;
2692 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2693 imageFormat, // VkFormat format;
2694 makeComponentMappingRGBA(), // VkComponentMapping components;
2695 texSRR, // VkImageSubresourceRange subresourceRange;
2696 };
2697
2698 const auto texView = createImageView(vkd, device, &texViewCreateInfo);
2699
2700 // Verification buffer for the color attachment.
2701 const auto verifBufferSize = static_cast<VkDeviceSize>(iColorExtent.x() * iColorExtent.y() * iColorExtent.z() * tcu::getPixelSize(tcuFormat));
2702 const auto verifBufferCreateInfo = makeBufferCreateInfo(verifBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2703 BufferWithMemory verifBuffer (vkd, device, alloc, verifBufferCreateInfo, MemoryRequirement::HostVisible);
2704 auto& verifBufferAlloc = verifBuffer.getAllocation();
2705 void* verifBufferData = verifBufferAlloc.getHostPtr();
2706
2707 // Descriptor set layout.
2708 DescriptorSetLayoutBuilder setLayoutBuilder;
2709 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
2710 const auto setLayout = setLayoutBuilder.build(vkd, device);
2711
2712 // Pipeline layout.
2713 const auto pipelineLayout = makePipelineLayout(vkd, device, setLayout.get());
2714
2715 // Sampler.
2716 const VkSamplerCreateInfo samplerCreateInfo =
2717 {
2718 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
2719 nullptr, // const void* pNext;
2720 0u, // VkSamplerCreateFlags flags;
2721 VK_FILTER_LINEAR, // VkFilter magFilter;
2722 VK_FILTER_LINEAR, // VkFilter minFilter;
2723 VK_SAMPLER_MIPMAP_MODE_LINEAR, // VkSamplerMipmapMode mipmapMode;
2724 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeU;
2725 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeV;
2726 VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeW;
2727 0.0f, // float mipLodBias;
2728 VK_FALSE, // VkBool32 anisotropyEnable;
2729 0.0f, // float maxAnisotropy;
2730 VK_FALSE, // VkBool32 compareEnable;
2731 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
2732 0.0f, // float minLod;
2733 static_cast<float>(texMipLevels), // float maxLod;
2734 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
2735 VK_FALSE, // VkBool32 unnormalizedCoordinates;
2736 };
2737 const auto sampler = createSampler(vkd, device, &samplerCreateInfo);
2738
2739 // Descriptor pool and set.
2740 DescriptorPoolBuilder poolBuilder;
2741 poolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2742 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2743 const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());
2744
2745 // Update descriptor set.
2746 DescriptorSetUpdateBuilder setUpdateBuilder;
2747 const auto combinedSamplerInfo = makeDescriptorImageInfo(sampler.get(), texView.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
2748 setUpdateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &combinedSamplerInfo);
2749 setUpdateBuilder.update(vkd, device);
2750
2751 // Render pass and framebuffer.
2752 const auto renderPass = makeRenderPass(vkd, device, imageFormat);
2753 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), colorBufferView.get(), colorExtent.width, colorExtent.height);
2754
2755 // Shader modules.
2756 const auto& binaries = m_context.getBinaryCollection();
2757 const auto vertModule = createShaderModule(vkd, device, binaries.get("vert"));
2758 const auto fragModule = createShaderModule(vkd, device, binaries.get("frag"));
2759
2760 // Viewports and scissors.
2761 std::vector<VkViewport> viewports (1u, makeViewport(colorExtent));
2762 std::vector<VkRect2D> scissors (1u, makeRect2D(colorExtent));
2763
2764 // Pipeline.
2765 const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
2766
2767 const auto pipeline = makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
2768 vertModule.get(), DE_NULL, DE_NULL, DE_NULL, fragModule.get(),
2769 renderPass.get(), viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
2770 0u/*subpass*/, 0u/*patchControlPoints*/, &vertexInputState);
2771
2772 // Command pool and buffer.
2773 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
2774 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2775 const auto cmdBuffer = cmdBufferPtr.get();
2776
2777 beginCommandBuffer(vkd, cmdBuffer);
2778
2779 // Move the whole texture to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
2780 const auto preClearBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture.get(), texSRR);
2781 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preClearBarrier);
2782
2783 // Fill each texture mip level with a different pseudorandom nonzero color.
2784 std::vector<tcu::Vec4> levelColors;
2785 de::Random rnd (m_params.randomSeed);
2786
2787 levelColors.reserve(texMipLevels);
2788
2789 const auto minColor = 0.004f; // Slightly above 1/255.
2790 const auto maxColor = 1.0f;
2791
2792 for (uint32_t level = 0u; level < texMipLevels; ++level)
2793 {
2794 const auto r = rnd.getFloat(minColor, maxColor);
2795 const auto g = rnd.getFloat(minColor, maxColor);
2796 const auto b = rnd.getFloat(minColor, maxColor);
2797 const auto a = rnd.getFloat(minColor, maxColor);
2798 const auto levelColor = makeClearValueColorF32(r, g, b, a).color;
2799 const auto levelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, level, 1u, 0u, 1u);
2800
2801 levelColors.emplace_back(r, g, b, a);
2802 vkd.cmdClearColorImage(cmdBuffer, texture.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &levelColor, 1u, &levelRange);
2803 }
2804
2805 // Move the whole texture to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
2806 const auto postClearBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, texture.get(), texSRR);
2807 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, &postClearBarrier);
2808
2809 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), scissors.at(0u), clearColor);
2810 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
2811 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
2812 vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u); // This has to match the vertex shader.
2813 endRenderPass(vkd, cmdBuffer);
2814
2815 // Copy color buffer to verification buffer.
2816 const auto postColorBarier = makeImageMemoryBarrier(
2817 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2818 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2819 colorBuffer.get(), colorSRR);
2820 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postColorBarier);
2821
2822 const auto copyRegion = makeBufferImageCopy(colorExtent, colorSRL);
2823 vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verifBuffer.get(), 1u, ©Region);
2824
2825 const auto preHostBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2826 cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &preHostBarrier);
2827
2828 endCommandBuffer(vkd, cmdBuffer);
2829 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
2830
2831 // Verify color buffer.
2832 invalidateAlloc(vkd, device, verifBufferAlloc);
2833 tcu::ConstPixelBufferAccess resultAccess (tcuFormat, iColorExtent, verifBufferData);
2834
2835 const auto resultColor = resultAccess.getPixel(0, 0);
2836 const auto srcLevelColor = levelColors.at(minLodU);
2837 const auto compColor = srcLevelColor[m_params.component];
2838 const auto expectedColor = (m_params.needsRobustness2() // This has to match the fragment shader.
2839 ? tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)
2840 : tcu::Vec4(compColor, compColor, compColor, 1.0f));
2841 const auto threshold = (m_params.needsRobustness2()
2842 ? 0.0f
2843 : 0.005f); // 1/255 < 0.005 < 2/255
2844
2845 const auto diff = abs(resultColor - expectedColor);
2846 const tcu::Vec4 thresholdVec (threshold, threshold, threshold, 0.0f);
2847 const auto thresholdMet = tcu::lessThanEqual(diff, thresholdVec);
2848
2849 if (!tcu::boolAll(thresholdMet))
2850 {
2851 std::ostringstream msg;
2852 msg << "Unexpected output buffer color: expected " << expectedColor << " but found " << resultColor << " [diff=" << diff << "]";
2853 TCU_FAIL(msg.str());
2854 }
2855
2856 return tcu::TestStatus::pass("Pass");
2857 }
2858
2859 #endif // CTS_USES_VULKANSC
2860
2861 } // anonymous
2862
2863 #ifndef CTS_USES_VULKANSC
2864
2865 namespace util {
2866
2867 template <>
checkTextureSupport(Context & context,const Texture2DMipmapTestCaseParameters & testParameters)2868 void checkTextureSupport (Context& context, const Texture2DMipmapTestCaseParameters& testParameters)
2869 {
2870 if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
2871 {
2872 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2873 vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
2874 imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
2875 imageViewMinLodFeatures.pNext = DE_NULL;
2876
2877 vk::VkPhysicalDeviceFeatures2 features2;
2878
2879 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2880 features2.pNext = &imageViewMinLodFeatures;
2881
2882 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2883
2884 if (imageViewMinLodFeatures.minLod == DE_FALSE)
2885 TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
2886 }
2887 }
2888
2889 template <>
checkTextureSupport(Context & context,const TextureCubeMipmapTestCaseParameters & testParameters)2890 void checkTextureSupport (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters)
2891 {
2892 if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
2893 {
2894 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2895 vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
2896 imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
2897 imageViewMinLodFeatures.pNext = DE_NULL;
2898
2899 vk::VkPhysicalDeviceFeatures2 features2;
2900
2901 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2902 features2.pNext = &imageViewMinLodFeatures;
2903
2904 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2905
2906 if (imageViewMinLodFeatures.minLod == DE_FALSE)
2907 TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
2908 }
2909 }
2910
2911 template <>
checkTextureSupport(Context & context,const Texture3DMipmapTestCaseParameters & testParameters)2912 void checkTextureSupport (Context& context, const Texture3DMipmapTestCaseParameters& testParameters)
2913 {
2914 if (testParameters.testType != TextureCommonTestCaseParameters::TEST_NORMAL)
2915 {
2916 context.requireDeviceFunctionality("VK_EXT_image_view_min_lod");
2917 vk::VkPhysicalDeviceImageViewMinLodFeaturesEXT imageViewMinLodFeatures;
2918 imageViewMinLodFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT;
2919 imageViewMinLodFeatures.pNext = DE_NULL;
2920
2921 vk::VkPhysicalDeviceFeatures2 features2;
2922
2923 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2924 features2.pNext = &imageViewMinLodFeatures;
2925
2926 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
2927
2928 if (imageViewMinLodFeatures.minLod == DE_FALSE)
2929 TCU_THROW(NotSupportedError, "VK_EXT_image_view_min_lod minLod feature not supported");
2930 }
2931 }
2932
2933 } // util
2934
populateMinLodGatherGroup(tcu::TestCaseGroup * minLodGatherGroup)2935 void populateMinLodGatherGroup (tcu::TestCaseGroup* minLodGatherGroup)
2936 {
2937 using GroupPtr = de::MovePtr<tcu::TestCaseGroup>;
2938
2939 const struct
2940 {
2941 GatherMinLod minLod;
2942 const char* name;
2943 } GatherMinLodCases[] =
2944 {
2945 { GatherMinLod::MINLOD_0_1, "minlod_0_1" },
2946 { GatherMinLod::MINLOD_1_1, "minlod_1_1" },
2947 };
2948
2949 const struct
2950 {
2951 int component;
2952 const char* name;
2953 } ComponentCases[] =
2954 {
2955 { 0, "component_0" },
2956 { 1, "component_1" },
2957 { 2, "component_2" },
2958 { 3, "component_3" },
2959 };
2960
2961 auto& testCtx = minLodGatherGroup->getTestContext();
2962
2963 for (const auto& gatherMinLodCase : GatherMinLodCases)
2964 {
2965 GroupPtr minLodGroup (new tcu::TestCaseGroup(testCtx, gatherMinLodCase.name, ""));
2966
2967 for (const auto& componentCase : ComponentCases)
2968 {
2969 const uint32_t seed = (static_cast<uint32_t>(gatherMinLodCase.minLod) + 1000u) * 1000u
2970 + (static_cast<uint32_t>(componentCase.component) + 1000u);
2971
2972 GatherParams params;
2973 params.randomSeed = seed;
2974 params.minLod = gatherMinLodCase.minLod;
2975 params.component = componentCase.component;
2976
2977 minLodGroup->addChild(new TextureGatherMinLodTest(testCtx, componentCase.name, "", params));
2978 }
2979
2980 minLodGatherGroup->addChild(minLodGroup.release());
2981 }
2982 }
2983
2984 #endif // CTS_USES_VULKANSC
2985
populateTextureMipmappingTests(tcu::TestCaseGroup * textureMipmappingTests)2986 void populateTextureMipmappingTests (tcu::TestCaseGroup* textureMipmappingTests)
2987 {
2988 tcu::TestContext& testCtx = textureMipmappingTests->getTestContext();
2989
2990 static const struct
2991 {
2992 const char* name;
2993 const Sampler::WrapMode mode;
2994 } wrapModes[] =
2995 {
2996 { "clamp", Sampler::CLAMP_TO_EDGE },
2997 { "repeat", Sampler::REPEAT_GL },
2998 { "mirror", Sampler::MIRRORED_REPEAT_GL }
2999 };
3000
3001 static const struct
3002 {
3003 const char* name;
3004 const Sampler::FilterMode mode;
3005 } minFilterModes[] =
3006 {
3007 { "nearest_nearest", Sampler::NEAREST_MIPMAP_NEAREST },
3008 { "linear_nearest", Sampler::LINEAR_MIPMAP_NEAREST },
3009 { "nearest_linear", Sampler::NEAREST_MIPMAP_LINEAR },
3010 { "linear_linear", Sampler::LINEAR_MIPMAP_LINEAR }
3011 };
3012
3013 static const struct
3014 {
3015 const char* name;
3016 const Sampler::FilterMode mode;
3017 } magFilterModes[] =
3018 {
3019 { "nearest", Sampler::NEAREST},
3020 { "linear", Sampler::LINEAR}
3021 };
3022
3023
3024 static const struct
3025 {
3026 const CoordType type;
3027 const char* name;
3028 const char* desc;
3029 } coordTypes[] =
3030 {
3031 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
3032 { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" },
3033 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }
3034 };
3035
3036 static const struct
3037 {
3038 const char* name;
3039 const int width;
3040 const int height;
3041 } tex2DSizes[] =
3042 {
3043 { DE_NULL, 64, 64 }, // Default.
3044 { "npot", 63, 57 },
3045 { "non_square", 32, 64 }
3046 };
3047
3048 static const struct
3049 {
3050 const char* name;
3051 const int width;
3052 const int height;
3053 const int depth;
3054 } tex3DSizes[] =
3055 {
3056 { DE_NULL, 32, 32, 32 }, // Default.
3057 { "npot", 33, 29, 27 }
3058 };
3059
3060 const int cubeMapSize = 64;
3061
3062 static const struct
3063 {
3064 const CoordType type;
3065 const char* name;
3066 const char* desc;
3067 } cubeCoordTypes[] =
3068 {
3069 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" },
3070 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" },
3071 { COORDTYPE_BASIC_BIAS, "bias", "User-supplied bias value" }
3072 };
3073
3074 // 2D cases.
3075 {
3076 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d", "2D Mipmap Filtering"));
3077
3078 de::MovePtr<tcu::TestCaseGroup> biasGroup2D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
3079 de::MovePtr<tcu::TestCaseGroup> minLodGroup2D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
3080 de::MovePtr<tcu::TestCaseGroup> maxLodGroup2D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
3081 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup2D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
3082 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup2D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
3083
3084 #ifndef CTS_USES_VULKANSC
3085 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroup2D (new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
3086 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroup2D (new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
3087 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroup2D (new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));
3088 #endif // CTS_USES_VULKANSC
3089
3090 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
3091 {
3092 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));
3093
3094 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3095 {
3096 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
3097 {
3098 // Add non_square variants to basic cases only.
3099 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1;
3100
3101 for (int size = 0; size < sizeEnd; size++)
3102 {
3103 Texture2DMipmapTestCaseParameters testParameters;
3104
3105 testParameters.coordType = coordTypes[coordType].type;
3106 testParameters.minFilter = minFilterModes[minFilter].mode;
3107 testParameters.wrapS = wrapModes[wrapMode].mode;
3108 testParameters.wrapT = wrapModes[wrapMode].mode;
3109 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
3110 testParameters.width = tex2DSizes[size].width;
3111 testParameters.height = tex2DSizes[size].height;
3112 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3113 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3114
3115 std::ostringstream name;
3116 name << minFilterModes[minFilter].name
3117 << "_" << wrapModes[wrapMode].name;
3118
3119 if (tex2DSizes[size].name)
3120 name << "_" << tex2DSizes[size].name;
3121
3122 coordTypeGroup->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
3123 }
3124 }
3125 }
3126
3127 group2D->addChild(coordTypeGroup.release());
3128 }
3129
3130 // 2D bias variants.
3131 {
3132 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3133 {
3134 Texture2DMipmapTestCaseParameters testParameters;
3135
3136 testParameters.coordType = COORDTYPE_BASIC_BIAS;
3137 testParameters.minFilter = minFilterModes[minFilter].mode;
3138 testParameters.magFilter = minFilterModes[minFilter].mode;
3139 testParameters.wrapS = Sampler::REPEAT_GL;
3140 testParameters.wrapT = Sampler::REPEAT_GL;
3141 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
3142 testParameters.width = tex2DSizes[0].width;
3143 testParameters.height = tex2DSizes[0].height;
3144 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3145 testParameters.programs.push_back(PROGRAM_2D_FLOAT_BIAS);
3146
3147 std::ostringstream name;
3148 name << minFilterModes[minFilter].name;
3149
3150 biasGroup2D->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
3151 }
3152 }
3153
3154 // 2D LOD controls.
3155 {
3156 // MIN_LOD
3157 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3158 {
3159 Texture2DMipmapTestCaseParameters testParameters;
3160 testParameters.minFilter = minFilterModes[minFilter].mode;
3161 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3162 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3163
3164 minLodGroup2D->addChild(new TextureTestCase<Texture2DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3165 }
3166
3167 // MAX_LOD
3168 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3169 {
3170 Texture2DMipmapTestCaseParameters testParameters;
3171 testParameters.minFilter = minFilterModes[minFilter].mode;
3172 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3173 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3174
3175 maxLodGroup2D->addChild(new TextureTestCase<Texture2DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3176 }
3177 }
3178
3179 {
3180 // BASE_LEVEL
3181 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3182 {
3183 Texture2DMipmapTestCaseParameters testParameters;
3184 testParameters.minFilter = minFilterModes[minFilter].mode;
3185 testParameters.minFilterName = minFilterModes[minFilter].name;
3186 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3187 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3188
3189 baseLevelGroup2D->addChild(new TextureTestCase<Texture2DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3190 }
3191
3192 // MAX_LEVEL
3193 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3194 {
3195 Texture2DMipmapTestCaseParameters testParameters;
3196 testParameters.minFilter = minFilterModes[minFilter].mode;
3197 testParameters.minFilterName = minFilterModes[minFilter].name;
3198 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3199 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3200
3201 maxLevelGroup2D->addChild(new TextureTestCase<Texture2DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3202 }
3203 }
3204
3205 // 2D VK_EXT_image_view_min_lod.
3206 #ifndef CTS_USES_VULKANSC
3207 {
3208 // MIN_LOD
3209 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3210 {
3211 Texture2DMipmapTestCaseParameters testParameters;
3212 testParameters.minFilter = minFilterModes[minFilter].mode;
3213 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3214 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3215 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3216
3217 imageViewMinLodGroup2D->addChild(new TextureTestCase<Texture2DImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3218
3219 std::ostringstream name;
3220 name << minFilterModes[minFilter].name << "_integer_texel_coord";
3221 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD;
3222 imageViewMinLodGroup2D->addChild(new Texture2DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
3223 }
3224
3225 // BASE_LEVEL
3226 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3227 {
3228 Texture2DMipmapTestCaseParameters testParameters;
3229 testParameters.minFilter = minFilterModes[minFilter].mode;
3230 testParameters.minFilterName = minFilterModes[minFilter].name;
3231 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3232 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
3233 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3234
3235 imageViewMinLodBaseLevelGroup2D->addChild(new TextureTestCase<Texture2DImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3236
3237 std::ostringstream name;
3238 name << minFilterModes[minFilter].name << "_integer_texel_coord";
3239 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD_BASELEVEL;
3240 imageViewMinLodBaseLevelGroup2D->addChild(new Texture2DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
3241 }
3242
3243 imageViewMinLodExtGroup2D->addChild(imageViewMinLodGroup2D.release());
3244 imageViewMinLodExtGroup2D->addChild(imageViewMinLodBaseLevelGroup2D.release());
3245 }
3246 #endif // CTS_USES_VULKANSC
3247
3248 group2D->addChild(biasGroup2D.release());
3249 group2D->addChild(minLodGroup2D.release());
3250 group2D->addChild(maxLodGroup2D.release());
3251 group2D->addChild(baseLevelGroup2D.release());
3252 group2D->addChild(maxLevelGroup2D.release());
3253 #ifndef CTS_USES_VULKANSC
3254 group2D->addChild(imageViewMinLodExtGroup2D.release());
3255 #endif // CTS_USES_VULKANSC
3256
3257 textureMipmappingTests->addChild(group2D.release());
3258 }
3259
3260 // Cubemap cases.
3261 {
3262 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cubemap", "Cube Mipmap Filtering"));
3263
3264 de::MovePtr<tcu::TestCaseGroup> minLodGroupCube (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
3265 de::MovePtr<tcu::TestCaseGroup> maxLodGroupCube (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
3266 de::MovePtr<tcu::TestCaseGroup> baseLevelGroupCube (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
3267 de::MovePtr<tcu::TestCaseGroup> maxLevelGroupCube (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
3268
3269 #ifndef CTS_USES_VULKANSC
3270 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroupCube (new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
3271 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroupCube (new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
3272 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroupCube (new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));
3273 #endif // CTS_USES_VULKANSC
3274
3275 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++)
3276 {
3277 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc));
3278
3279 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3280 {
3281 for (int magFilter = 0; magFilter < DE_LENGTH_OF_ARRAY(magFilterModes); magFilter++)
3282 {
3283 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
3284 {
3285 TextureCubeMipmapTestCaseParameters testParameters;
3286
3287 testParameters.coordType = cubeCoordTypes[coordType].type;
3288 testParameters.minFilter = minFilterModes[minFilter].mode;
3289 testParameters.magFilter = magFilterModes[magFilter].mode;
3290 testParameters.minFilterName = minFilterModes[minFilter].name;
3291 testParameters.wrapS = wrapModes[wrapMode].mode;
3292 testParameters.wrapT = wrapModes[wrapMode].mode;
3293 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
3294 testParameters.size = cubeMapSize;
3295 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3296
3297 if (testParameters.coordType == COORDTYPE_BASIC_BIAS)
3298 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT_BIAS);
3299 else
3300 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3301
3302 std::ostringstream name;
3303 name << minFilterModes[minFilter].name
3304 << "_" << magFilterModes[magFilter].name
3305 << "_" << wrapModes[wrapMode].name;
3306
3307 coordTypeGroup->addChild(new TextureTestCase<TextureCubeMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
3308 }
3309 }
3310 }
3311
3312 groupCube->addChild(coordTypeGroup.release());
3313 }
3314
3315 // Cubemap LOD controls.
3316 {
3317 // MIN_LOD
3318 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3319 {
3320 TextureCubeMipmapTestCaseParameters testParameters;
3321 testParameters.minFilter = minFilterModes[minFilter].mode;
3322 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3323 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3324
3325 minLodGroupCube->addChild(new TextureTestCase<TextureCubeMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3326 }
3327
3328 // MAX_LOD
3329 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3330 {
3331 TextureCubeMipmapTestCaseParameters testParameters;
3332 testParameters.minFilter = minFilterModes[minFilter].mode;
3333 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3334 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3335
3336 maxLodGroupCube->addChild(new TextureTestCase<TextureCubeMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3337 }
3338 }
3339
3340 {
3341 // BASE_LEVEL
3342 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3343 {
3344 TextureCubeMipmapTestCaseParameters testParameters;
3345 testParameters.minFilter = minFilterModes[minFilter].mode;
3346 testParameters.minFilterName = minFilterModes[minFilter].name;
3347 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3348 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3349
3350 baseLevelGroupCube->addChild(new TextureTestCase<TextureCubeBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3351 }
3352
3353 // MAX_LEVEL
3354 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3355 {
3356 TextureCubeMipmapTestCaseParameters testParameters;
3357 testParameters.minFilter = minFilterModes[minFilter].mode;
3358 testParameters.minFilterName = minFilterModes[minFilter].name;
3359 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3360 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3361
3362 maxLevelGroupCube->addChild(new TextureTestCase<TextureCubeMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3363 }
3364 }
3365
3366 // Cube VK_EXT_image_view_min_lod.
3367 #ifndef CTS_USES_VULKANSC
3368 {
3369 // MIN_LOD
3370 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3371 {
3372 TextureCubeMipmapTestCaseParameters testParameters;
3373 testParameters.minFilter = minFilterModes[minFilter].mode;
3374 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3375 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3376 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3377
3378 imageViewMinLodGroupCube->addChild(new TextureTestCase<TextureCubeImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3379 }
3380
3381 // BASE_LEVEL
3382 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3383 {
3384 TextureCubeMipmapTestCaseParameters testParameters;
3385 testParameters.minFilter = minFilterModes[minFilter].mode;
3386 testParameters.minFilterName = minFilterModes[minFilter].name;
3387 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3388 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
3389 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3390
3391 imageViewMinLodBaseLevelGroupCube->addChild(new TextureTestCase<TextureCubeImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3392 }
3393
3394 imageViewMinLodExtGroupCube->addChild(imageViewMinLodGroupCube.release());
3395 imageViewMinLodExtGroupCube->addChild(imageViewMinLodBaseLevelGroupCube.release());
3396 }
3397 #endif // CTS_USES_VULKANSC
3398
3399 groupCube->addChild(minLodGroupCube.release());
3400 groupCube->addChild(maxLodGroupCube.release());
3401 groupCube->addChild(baseLevelGroupCube.release());
3402 groupCube->addChild(maxLevelGroupCube.release());
3403 #ifndef CTS_USES_VULKANSC
3404 groupCube->addChild(imageViewMinLodExtGroupCube.release());
3405 #endif // CTS_USES_VULKANSC
3406
3407 textureMipmappingTests->addChild(groupCube.release());
3408 }
3409
3410 // 3D cases.
3411 {
3412 de::MovePtr<tcu::TestCaseGroup> group3D (new tcu::TestCaseGroup(testCtx, "3d", "3D Mipmap Filtering"));
3413
3414 de::MovePtr<tcu::TestCaseGroup> biasGroup3D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value"));
3415 de::MovePtr<tcu::TestCaseGroup> minLodGroup3D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod"));
3416 de::MovePtr<tcu::TestCaseGroup> maxLodGroup3D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod"));
3417 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup3D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level"));
3418 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup3D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level"));
3419
3420 #ifndef CTS_USES_VULKANSC
3421 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodExtGroup3D (new tcu::TestCaseGroup(testCtx, "image_view_min_lod", "VK_EXT_image_view_min_lod tests"));
3422 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodGroup3D (new tcu::TestCaseGroup(testCtx, "min_lod", "ImageView's minLod"));
3423 de::MovePtr<tcu::TestCaseGroup> imageViewMinLodBaseLevelGroup3D (new tcu::TestCaseGroup(testCtx, "base_level", "ImageView's minLod with base level different than one"));
3424 #endif // CTS_USES_VULKANSC
3425
3426 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++)
3427 {
3428 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc));
3429
3430 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3431 {
3432 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++)
3433 {
3434 // Add other size variants to basic cases only.
3435 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1;
3436
3437 Texture3DMipmapTestCaseParameters testParameters;
3438
3439 testParameters.coordType = coordTypes[coordType].type;
3440 testParameters.minFilter = minFilterModes[minFilter].mode;
3441 testParameters.minFilterName = minFilterModes[minFilter].name;
3442 testParameters.wrapR = wrapModes[wrapMode].mode;
3443 testParameters.wrapS = wrapModes[wrapMode].mode;
3444 testParameters.wrapT = wrapModes[wrapMode].mode;
3445 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
3446 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3447 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3448
3449 for (int size = 0; size < sizeEnd; size++)
3450 {
3451 testParameters.width = tex3DSizes[size].width;
3452 testParameters.height = tex3DSizes[size].height;
3453 testParameters.depth = tex3DSizes[size].depth;
3454
3455 std::ostringstream name;
3456 name << minFilterModes[minFilter].name
3457 << "_" << wrapModes[wrapMode].name;
3458
3459 if (tex3DSizes[size].name)
3460 name << "_" << tex3DSizes[size].name;
3461
3462 coordTypeGroup->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters));
3463 }
3464 }
3465 }
3466
3467 group3D->addChild(coordTypeGroup.release());
3468 }
3469
3470 // 3D bias variants.
3471 {
3472 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3473 {
3474 Texture3DMipmapTestCaseParameters testParameters;
3475 testParameters.coordType = COORDTYPE_BASIC_BIAS;
3476 testParameters.minFilter = minFilterModes[minFilter].mode;
3477 testParameters.wrapR = Sampler::REPEAT_GL;
3478 testParameters.wrapS = Sampler::REPEAT_GL;
3479 testParameters.wrapT = Sampler::REPEAT_GL;
3480 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
3481 testParameters.width = tex3DSizes[0].width;
3482 testParameters.height = tex3DSizes[0].height;
3483 testParameters.depth = tex3DSizes[0].depth;
3484 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3485 testParameters.programs.push_back(PROGRAM_3D_FLOAT_BIAS);
3486
3487 biasGroup3D->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3488 }
3489 }
3490
3491 // 3D LOD controls.
3492 {
3493 // MIN_LOD
3494 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3495 {
3496 Texture3DMipmapTestCaseParameters testParameters;
3497 testParameters.minFilter = minFilterModes[minFilter].mode;
3498 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3499 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3500
3501 minLodGroup3D->addChild(new TextureTestCase<Texture3DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3502 }
3503
3504 // MAX_LOD
3505 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3506 {
3507 Texture3DMipmapTestCaseParameters testParameters;
3508 testParameters.minFilter = minFilterModes[minFilter].mode;
3509 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3510 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3511
3512 maxLodGroup3D->addChild(new TextureTestCase<Texture3DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3513 }
3514 }
3515
3516 {
3517 // BASE_LEVEL
3518 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3519 {
3520 Texture3DMipmapTestCaseParameters testParameters;
3521 testParameters.minFilter = minFilterModes[minFilter].mode;
3522 testParameters.minFilterName = minFilterModes[minFilter].name;
3523 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3524 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3525
3526 baseLevelGroup3D->addChild(new TextureTestCase<Texture3DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3527 }
3528
3529 // MAX_LEVEL
3530 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3531 {
3532 Texture3DMipmapTestCaseParameters testParameters;
3533 testParameters.minFilter = minFilterModes[minFilter].mode;
3534 testParameters.minFilterName = minFilterModes[minFilter].name;
3535 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3536 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3537
3538 maxLevelGroup3D->addChild(new TextureTestCase<Texture3DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3539 }
3540 }
3541
3542 // 3D VK_EXT_image_view_min_lod.
3543 #ifndef CTS_USES_VULKANSC
3544 {
3545 // MIN_LOD
3546 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3547 {
3548 Texture3DMipmapTestCaseParameters testParameters;
3549 testParameters.minFilter = minFilterModes[minFilter].mode;
3550 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3551 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3552 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3553
3554 imageViewMinLodGroup3D->addChild(new TextureTestCase<Texture3DImageViewMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3555
3556 std::ostringstream name;
3557 name << minFilterModes[minFilter].name << "_integer_texel_coord";
3558 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD;
3559 imageViewMinLodGroup3D->addChild(new Texture3DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
3560 }
3561
3562 // BASE_LEVEL
3563 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++)
3564 {
3565 Texture3DMipmapTestCaseParameters testParameters;
3566 testParameters.minFilter = minFilterModes[minFilter].mode;
3567 testParameters.minFilterName = minFilterModes[minFilter].name;
3568 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3569 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
3570 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD;
3571
3572
3573 imageViewMinLodBaseLevelGroup3D->addChild(new TextureTestCase<Texture3DImageViewMinLodBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters));
3574
3575 std::ostringstream name;
3576 name << minFilterModes[minFilter].name << "_integer_texel_coord";
3577 testParameters.testType = util::TextureCommonTestCaseParameters::TEST_IMAGE_VIEW_MINLOD_INT_TEX_COORD_BASELEVEL;
3578 imageViewMinLodBaseLevelGroup3D->addChild(new Texture3DImageViewMinLodIntTexCoordTest(testCtx, name.str().c_str(), "", testParameters));
3579 }
3580
3581 imageViewMinLodExtGroup3D->addChild(imageViewMinLodGroup3D.release());
3582 imageViewMinLodExtGroup3D->addChild(imageViewMinLodBaseLevelGroup3D.release());
3583 }
3584 #endif // CTS_USES_VULKANSC
3585
3586 group3D->addChild(biasGroup3D.release());
3587 group3D->addChild(minLodGroup3D.release());
3588 group3D->addChild(maxLodGroup3D.release());
3589 group3D->addChild(baseLevelGroup3D.release());
3590 group3D->addChild(maxLevelGroup3D.release());
3591 #ifndef CTS_USES_VULKANSC
3592 group3D->addChild(imageViewMinLodExtGroup3D.release());
3593 #endif // CTS_USES_VULKANSC
3594
3595 textureMipmappingTests->addChild(group3D.release());
3596 }
3597
3598 #ifndef CTS_USES_VULKANSC
3599 {
3600 const auto minLodGatherGroup = createTestGroup(testCtx, "min_lod_gather", "Test minLod with textureGather operations", populateMinLodGatherGroup, destroyDeviceHelpers);
3601 textureMipmappingTests->addChild(minLodGatherGroup);
3602 }
3603 #endif // CTS_USES_VULKANSC
3604 }
3605
createTextureMipmappingTests(tcu::TestContext & testCtx)3606 tcu::TestCaseGroup* createTextureMipmappingTests (tcu::TestContext& testCtx)
3607 {
3608 return createTestGroup(testCtx, "mipmap", "Texture mipmapping tests.", populateTextureMipmappingTests);
3609 }
3610
3611 } // texture
3612 } // vkt
3613