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 (c) 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 Texture filtering tests.
24 *//*--------------------------------------------------------------------*/
25
26 #include "tcuVectorUtil.hpp"
27 #include "tcuTexVerifierUtil.hpp"
28 #include "vkImageUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestCaseUtil.hpp"
35 #include "vktTestGroupUtil.hpp"
36 #include "vktTextureFilteringTests.hpp"
37 #include "vktTextureTestUtil.hpp"
38 #include <string>
39 #include <vector>
40
41 using namespace vk;
42
43 namespace vkt
44 {
45 namespace texture
46 {
47 namespace util
48 {
49
50 template <>
checkTextureSupport(Context & context,const Texture2DTestCaseParameters & testParameters)51 void checkTextureSupport (Context& context, const Texture2DTestCaseParameters& testParameters)
52 {
53 if (testParameters.minFilter == tcu::Sampler::Sampler::CUBIC || testParameters.minFilter == tcu::Sampler::Sampler::CUBIC_MIPMAP_NEAREST || testParameters.minFilter == tcu::Sampler::Sampler::CUBIC_MIPMAP_LINEAR ||
54 testParameters.magFilter == tcu::Sampler::Sampler::CUBIC)
55 {
56 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
57
58 // check if image format supports cubic filtering
59 const vk::VkPhysicalDeviceImageViewImageFormatInfoEXT imageViewImageFormatInfo =
60 {
61 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT, // VkStructureType sType;
62 DE_NULL, // void* pNext;
63 VK_IMAGE_VIEW_TYPE_2D // VkImageViewType imageViewType;
64 };
65
66 const vk::VkPhysicalDeviceImageFormatInfo2 formatInfo =
67 {
68 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // VkStructureType sType;
69 &imageViewImageFormatInfo, // const void* pNext;
70 testParameters.format, // VkFormat format;
71 VK_IMAGE_TYPE_2D, // VkImageType type;
72 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
73 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
74 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
75 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
76 0u // VkImageCreateFlags flags;
77 };
78
79 vk::VkFilterCubicImageViewImageFormatPropertiesEXT cubicImageViewProperties =
80 {
81 VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT, // VkStructureType sType;
82 DE_NULL, // void* pNext;
83 DE_FALSE, // VkBool32 filterCubic;
84 DE_FALSE // VkBool32 filterCubicMinmax;
85 };
86
87 vk::VkImageFormatProperties2 formatProperties =
88 {
89 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, // VkStructureType sType;
90 &cubicImageViewProperties, // void* pNext;
91 vk::VkImageFormatProperties() // VkImageFormatProperties imageFormatProperties;
92 };
93
94 const vk::VkResult res = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &formatInfo, &formatProperties);
95 if (res == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
96 TCU_THROW(NotSupportedError, "Image format not supported");
97 VK_CHECK(res);
98
99 if (!cubicImageViewProperties.filterCubic)
100 TCU_THROW(NotSupportedError, "Image format does not support cubic filtering");
101
102 VkFormatProperties formatProps;
103 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), testParameters.format, &formatProps);
104 if ((formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT) == 0)
105 TCU_THROW(NotSupportedError, "Format properties do not support cubic filtering feature");
106 }
107
108 if (testParameters.wrapS == tcu::Sampler::Sampler::MIRRORED_ONCE || testParameters.wrapT == tcu::Sampler::Sampler::MIRRORED_ONCE)
109 context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
110
111 #ifndef CTS_USES_VULKANSC
112 if (testParameters.format == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 && context.getRGBA10X6FormatsFeaturesEXT().formatRgba10x6WithoutYCbCrSampler == VK_FALSE)
113 TCU_THROW(NotSupportedError, "formatRgba10x6WithoutYCbCrSampler not supported");
114 #endif
115 }
116
117 template <>
checkTextureSupport(Context & context,const TextureCubeTestCaseParameters & testParameters)118 void checkTextureSupport (Context& context, const TextureCubeTestCaseParameters& testParameters)
119 {
120 if (testParameters.wrapS == tcu::Sampler::Sampler::MIRRORED_ONCE || testParameters.wrapT == tcu::Sampler::Sampler::MIRRORED_ONCE)
121 context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
122 }
123
124 template <>
checkTextureSupport(Context & context,const Texture2DArrayTestCaseParameters & testParameters)125 void checkTextureSupport (Context& context, const Texture2DArrayTestCaseParameters& testParameters)
126 {
127 if (testParameters.wrapS == tcu::Sampler::Sampler::MIRRORED_ONCE || testParameters.wrapT == tcu::Sampler::Sampler::MIRRORED_ONCE)
128 context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
129
130 #ifndef CTS_USES_VULKANSC
131 bool mipmaps = (deLog2Floor32(de::max(testParameters.width, testParameters.height)) + 1) > 1 || testParameters.mipmaps;
132 if (testParameters.format == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 && mipmaps && context.getRGBA10X6FormatsFeaturesEXT().formatRgba10x6WithoutYCbCrSampler == VK_FALSE)
133 TCU_THROW(NotSupportedError, "formatRgba10x6WithoutYCbCrSampler not supported");
134 #endif
135 }
136
137 template <>
checkTextureSupport(Context & context,const Texture3DTestCaseParameters & testParameters)138 void checkTextureSupport (Context& context, const Texture3DTestCaseParameters& testParameters)
139 {
140 if (testParameters.wrapS == tcu::Sampler::Sampler::MIRRORED_ONCE || testParameters.wrapT == tcu::Sampler::Sampler::MIRRORED_ONCE || testParameters.wrapR == tcu::Sampler::Sampler::MIRRORED_ONCE)
141 context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
142
143 #ifndef CTS_USES_VULKANSC
144 if (testParameters.format == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 && context.getRGBA10X6FormatsFeaturesEXT().formatRgba10x6WithoutYCbCrSampler == VK_FALSE)
145 TCU_THROW(NotSupportedError, "formatRgba10x6WithoutYCbCrSampler not supported");
146 #endif
147 }
148
149 template <>
checkTextureSupport(Context & context,const TextureCubeFilteringTestCaseParameters & testParameters)150 void checkTextureSupport (Context& context, const TextureCubeFilteringTestCaseParameters& testParameters)
151 {
152 #ifndef CTS_USES_VULKANSC
153 if (testParameters.format == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 && context.getRGBA10X6FormatsFeaturesEXT().formatRgba10x6WithoutYCbCrSampler == VK_FALSE)
154 TCU_THROW(NotSupportedError, "formatRgba10x6WithoutYCbCrSampler not supported");
155 #else
156 DE_UNREF(context);
157 DE_UNREF(testParameters);
158 #endif
159 }
160
161 } // util
162
163 namespace
164 {
165
166 using std::vector;
167 using std::string;
168 using tcu::TestLog;
169 using tcu::Sampler;
170
171 using namespace texture::util;
172 using namespace glu::TextureTestUtil;
173
174 enum
175 {
176 TEXCUBE_VIEWPORT_SIZE = 28,
177
178 TEX2D_VIEWPORT_WIDTH = 64,
179 TEX2D_VIEWPORT_HEIGHT = 64,
180
181 TEX3D_VIEWPORT_WIDTH = 64,
182 TEX3D_VIEWPORT_HEIGHT = 64,
183 };
184
185 class Texture2DFilteringTestInstance : public TestInstance
186 {
187 public:
188 typedef Texture2DTestCaseParameters ParameterType;
189
190 Texture2DFilteringTestInstance (Context& context, const ParameterType& testParameters);
191 ~Texture2DFilteringTestInstance (void);
192
193 virtual tcu::TestStatus iterate (void);
194 private:
195 Texture2DFilteringTestInstance (const Texture2DFilteringTestInstance& other);
196 Texture2DFilteringTestInstance& operator= (const Texture2DFilteringTestInstance& other);
197
198 struct FilterCase
199 {
200 int textureIndex;
201
202 tcu::Vec2 minCoord;
203 tcu::Vec2 maxCoord;
204
FilterCasevkt::texture::__anon9a19a5410111::Texture2DFilteringTestInstance::FilterCase205 FilterCase (void)
206 : textureIndex(-1)
207 {
208 }
209
FilterCasevkt::texture::__anon9a19a5410111::Texture2DFilteringTestInstance::FilterCase210 FilterCase (int tex_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
211 : textureIndex (tex_)
212 , minCoord (minCoord_)
213 , maxCoord (maxCoord_)
214 {
215 }
216 };
217
218 const ParameterType m_testParameters;
219 vector<TestTexture2DSp> m_textures;
220 vector<FilterCase> m_cases;
221 TextureRenderer m_renderer;
222 int m_caseNdx;
223 };
224
Texture2DFilteringTestInstance(Context & context,const ParameterType & testParameters)225 Texture2DFilteringTestInstance::Texture2DFilteringTestInstance (Context& context, const ParameterType& testParameters)
226 : TestInstance (context)
227 , m_testParameters (testParameters)
228 , m_renderer (context, testParameters.sampleCount, TEX2D_VIEWPORT_WIDTH, TEX2D_VIEWPORT_HEIGHT)
229 , m_caseNdx (0)
230 {
231 const bool mipmaps = m_testParameters.mipmaps;
232 const int numLevels = mipmaps ? deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1 : 1;
233 const tcu::TextureFormat texFormat = vk::mapVkFormat(m_testParameters.format);
234 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat);
235 tcu::Vec4 cBias, cScale;
236 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
237 {
238 const tcu::TextureFormat texFormatStencil = vk::mapVkFormat(VK_FORMAT_S8_UINT);
239 const tcu::TextureFormatInfo fmtInfoStencil = tcu::getTextureFormatInfo(texFormatStencil);
240 cBias = fmtInfoStencil.valueMin;
241 cScale = fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
242 }
243 else
244 {
245 cBias = fmtInfo.valueMin;
246 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
247 }
248
249 // Create 2 textures.
250 m_textures.reserve(2);
251 for (int ndx = 0; ndx < 2; ndx++)
252 if (mipmaps)
253 m_textures.push_back(TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height)));
254 else
255 m_textures.push_back(TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, 1)));
256
257 // Fill first gradient texture.
258 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
259 {
260 const tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
261 const tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
262
263 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
264 tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), gMin, gMax);
265 else
266 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
267 }
268
269 // Fill second with grid texture.
270 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
271 {
272 const deUint32 step = 0x00ffffff / numLevels;
273 const deUint32 rgb = step*levelNdx;
274 const deUint32 colorA = 0xff000000 | rgb;
275 const deUint32 colorB = 0xff000000 | ~rgb;
276
277 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
278 tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
279 else
280 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
281 }
282
283 // Upload.
284 for (vector<TestTexture2DSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
285 {
286 m_renderer.add2DTexture(*i, testParameters.aspectMask);
287 }
288
289 // Compute cases.
290 {
291 const struct
292 {
293 const int texNdx;
294 const float lodX;
295 const float lodY;
296 const float oX;
297 const float oY;
298 } cases[] =
299 {
300 { 0, 1.6f, 2.9f, -1.0f, -2.7f },
301 { 0, -2.0f, -1.35f, -0.2f, 0.7f },
302 { 1, 0.14f, 0.275f, -1.5f, -1.1f },
303 { 1, -0.92f, -2.64f, 0.4f, -0.1f },
304 };
305
306 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
307 {
308 const int texNdx = de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
309 const float lodX = cases[caseNdx].lodX;
310 const float lodY = cases[caseNdx].lodY;
311 const float oX = cases[caseNdx].oX;
312 const float oY = cases[caseNdx].oY;
313 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[texNdx]->getTexture().getWidth());
314 const float sY = deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[texNdx]->getTexture().getHeight());
315
316 m_cases.push_back(FilterCase(texNdx, tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
317 }
318 }
319 }
320
~Texture2DFilteringTestInstance(void)321 Texture2DFilteringTestInstance::~Texture2DFilteringTestInstance (void)
322 {
323 }
324
iterate(void)325 tcu::TestStatus Texture2DFilteringTestInstance::iterate (void)
326 {
327 tcu::TestLog& log = m_context.getTestContext().getLog();
328 const pipeline::TestTexture2D& texture = m_renderer.get2DTexture(m_cases[m_caseNdx].textureIndex);
329 const tcu::TextureFormat texFmt = texture.getTextureFormat();
330 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
331 const FilterCase& curCase = m_cases[m_caseNdx];
332 ReferenceParams refParams (TEXTURETYPE_2D);
333 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
334 vector<float> texCoord;
335
336 // Setup params for reference.
337
338 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter, !m_testParameters.unnormal);
339 if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
340 {
341 refParams.sampler.depthStencilMode = tcu::Sampler::MODE_STENCIL;
342 refParams.samplerType = SAMPLERTYPE_UINT;
343 }
344 else
345 refParams.samplerType = getSamplerType(texFmt);
346 refParams.colorBias = fmtInfo.lookupBias;
347 refParams.colorScale = fmtInfo.lookupScale;
348 refParams.unnormal = m_testParameters.unnormal;
349
350 // Compute texture coordinates.
351 log << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
352 computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);
353
354 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], refParams);
355
356 {
357 const bool isNearestOnly = m_testParameters.minFilter == Sampler::NEAREST && m_testParameters.magFilter == Sampler::NEAREST;
358 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
359 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
360 const tcu::IVec4 colorBits = max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
361 tcu::LodPrecision lodPrecision;
362 tcu::LookupPrecision lookupPrecision;
363
364 lodPrecision.derivateBits = 18;
365 lodPrecision.lodBits = 6;
366 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
367 lookupPrecision.coordBits = tcu::IVec3(20,20,0);
368 lookupPrecision.uvwBits = tcu::IVec3(7,7,0);
369 lookupPrecision.colorMask = getCompareMask(pixelFormat);
370
371 #ifdef CTS_USES_VULKANSC
372 if (m_context.getTestContext().getCommandLine().isSubProcess())
373 #endif // CTS_USES_VULKANSC
374 {
375 const bool isHighQuality = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture2DView)texture.getTexture(),
376 &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
377
378 if (!isHighQuality)
379 {
380 // Evaluate against lower precision requirements.
381 lodPrecision.lodBits = 4;
382 lookupPrecision.uvwBits = tcu::IVec3(4,4,0);
383
384 log << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
385
386 const bool isOk = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture2DView)texture.getTexture(),
387 &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
388
389 if (!isOk)
390 {
391 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
392 return tcu::TestStatus::fail("Image verification failed");
393 }
394 }
395 }
396 }
397
398 m_caseNdx += 1;
399 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
400 }
401
402 class TextureCubeFilteringTestInstance : public TestInstance
403 {
404 public:
405 typedef TextureCubeFilteringTestCaseParameters ParameterType;
406
407 TextureCubeFilteringTestInstance (Context& context, const ParameterType& testParameters);
408 ~TextureCubeFilteringTestInstance (void);
409
410 virtual tcu::TestStatus iterate (void);
411
412 private:
413 TextureCubeFilteringTestInstance (const TextureCubeFilteringTestInstance& other);
414 TextureCubeFilteringTestInstance& operator= (const TextureCubeFilteringTestInstance& other);
415
416 struct FilterCase
417 {
418 int textureIndex;
419 tcu::Vec2 bottomLeft;
420 tcu::Vec2 topRight;
421
FilterCasevkt::texture::__anon9a19a5410111::TextureCubeFilteringTestInstance::FilterCase422 FilterCase (void)
423 : textureIndex(-1)
424 {
425 }
426
FilterCasevkt::texture::__anon9a19a5410111::TextureCubeFilteringTestInstance::FilterCase427 FilterCase (int tex_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
428 : textureIndex (tex_)
429 , bottomLeft (bottomLeft_)
430 , topRight (topRight_)
431 {
432 }
433 };
434
435 const ParameterType m_testParameters;
436 vector<TestTextureCubeSp> m_textures;
437 vector<FilterCase> m_cases;
438 TextureRenderer m_renderer;
439 int m_caseNdx;
440 };
441
TextureCubeFilteringTestInstance(Context & context,const ParameterType & testParameters)442 TextureCubeFilteringTestInstance::TextureCubeFilteringTestInstance (Context& context, const ParameterType& testParameters)
443 : TestInstance (context)
444 , m_testParameters (testParameters)
445 , m_renderer (context, testParameters.sampleCount, TEXCUBE_VIEWPORT_SIZE, TEXCUBE_VIEWPORT_SIZE)
446 , m_caseNdx (0)
447 {
448 const int numLevels = deLog2Floor32(m_testParameters.size)+1;
449 const tcu::TextureFormat texFormat = vk::mapVkFormat(m_testParameters.format);
450 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat);
451 tcu::Vec4 cBias, cScale;
452 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
453 {
454 const tcu::TextureFormat texFormatStencil = vk::mapVkFormat(VK_FORMAT_S8_UINT);
455 const tcu::TextureFormatInfo fmtInfoStencil = tcu::getTextureFormatInfo(texFormatStencil);
456 cBias = fmtInfoStencil.valueMin;
457 cScale = fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
458 }
459 else
460 {
461 cBias = fmtInfo.valueMin;
462 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
463 }
464
465 m_textures.reserve(2);
466 for (int ndx = 0; ndx < 2; ndx++)
467 m_textures.push_back(TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size)));
468
469 // Fill first with gradient texture.
470 static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
471 {
472 { tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
473 { tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
474 { tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
475 { tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
476 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
477 { tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) } // positive z
478 };
479
480 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
481 {
482 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
483 {
484 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
485 tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, face), tcu::Sampler::MODE_STENCIL), gradients[face][0] * cScale + cBias, gradients[face][1] * cScale + cBias);
486 else
487 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, face), gradients[face][0] * cScale + cBias, gradients[face][1] * cScale + cBias);
488 }
489 }
490
491 // Fill second with grid texture.
492 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
493 {
494 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
495 {
496 const deUint32 step = 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
497 const deUint32 rgb = step*levelNdx*face;
498 const deUint32 colorA = 0xff000000 | rgb;
499 const deUint32 colorB = 0xff000000 | ~rgb;
500
501 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
502
503 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
504 tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, face), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
505 else
506 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, face), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
507 }
508 }
509
510 // Upload.
511 for (vector<TestTextureCubeSp>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
512 {
513 m_renderer.addCubeTexture(*i, testParameters.aspectMask);
514 }
515
516 // Compute cases
517 {
518 const int tex0 = 0;
519 const int tex1 = m_textures.size() > 1 ? 1 : 0;
520
521 if (m_testParameters.onlySampleFaceInterior)
522 {
523 m_cases.push_back(FilterCase(tex0, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f))); // minification
524 m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.5f, 0.65f), tcu::Vec2(0.8f, 0.8f))); // magnification
525 m_cases.push_back(FilterCase(tex1, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f))); // minification
526 m_cases.push_back(FilterCase(tex1, tcu::Vec2(0.2f, 0.2f), tcu::Vec2(0.6f, 0.5f))); // magnification
527 }
528 else
529 {
530 m_cases.push_back(FilterCase(tex0, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f))); // minification
531
532 m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f))); // magnification
533 m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f))); // minification
534 m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f))); // magnification
535 }
536 }
537 }
538
~TextureCubeFilteringTestInstance(void)539 TextureCubeFilteringTestInstance::~TextureCubeFilteringTestInstance (void)
540 {
541 }
542
getFaceDesc(const tcu::CubeFace face)543 const char* getFaceDesc (const tcu::CubeFace face)
544 {
545 switch (face)
546 {
547 case tcu::CUBEFACE_NEGATIVE_X: return "-X";
548 case tcu::CUBEFACE_POSITIVE_X: return "+X";
549 case tcu::CUBEFACE_NEGATIVE_Y: return "-Y";
550 case tcu::CUBEFACE_POSITIVE_Y: return "+Y";
551 case tcu::CUBEFACE_NEGATIVE_Z: return "-Z";
552 case tcu::CUBEFACE_POSITIVE_Z: return "+Z";
553 default:
554 DE_ASSERT(false);
555 return DE_NULL;
556 }
557 }
558
iterate(void)559 tcu::TestStatus TextureCubeFilteringTestInstance::iterate (void)
560 {
561 tcu::TestLog& log = m_context.getTestContext().getLog();
562
563 const pipeline::TestTextureCube& texture = m_renderer.getCubeTexture(m_cases[m_caseNdx].textureIndex);
564 const tcu::TextureFormat texFmt = texture.getTextureFormat();
565 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
566 const FilterCase& curCase = m_cases[m_caseNdx];
567 ReferenceParams refParams (TEXTURETYPE_CUBE);
568
569 // Params for reference computation.
570 refParams.sampler = util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_testParameters.minFilter, m_testParameters.magFilter);
571 if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
572 {
573 refParams.sampler.depthStencilMode = tcu::Sampler::MODE_STENCIL;
574 refParams.samplerType = SAMPLERTYPE_UINT;
575 }
576 else
577 refParams.samplerType = getSamplerType(texFmt);
578 refParams.sampler.seamlessCubeMap = true;
579 refParams.lodMode = LODMODE_EXACT;
580 refParams.colorBias = fmtInfo.lookupBias;
581 refParams.colorScale = fmtInfo.lookupScale;
582
583 log << TestLog::Message << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight << TestLog::EndMessage;
584
585 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
586 {
587 const tcu::CubeFace face = tcu::CubeFace(faceNdx);
588 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
589 vector<float> texCoord;
590
591 computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);
592
593 log << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;
594
595 // \todo Log texture coordinates.
596
597 m_renderer.renderQuad(rendered, curCase.textureIndex, &texCoord[0], refParams);
598
599 {
600 const bool isNearestOnly = m_testParameters.minFilter == Sampler::NEAREST && m_testParameters.magFilter == Sampler::NEAREST;
601 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
602 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
603 const tcu::IVec4 colorBits = max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
604 tcu::LodPrecision lodPrecision;
605 tcu::LookupPrecision lookupPrecision;
606
607 lodPrecision.derivateBits = 10;
608 lodPrecision.lodBits = 5;
609 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
610 lookupPrecision.coordBits = tcu::IVec3(10,10,10);
611 lookupPrecision.uvwBits = tcu::IVec3(6,6,0);
612 lookupPrecision.colorMask = getCompareMask(pixelFormat);
613
614 #ifdef CTS_USES_VULKANSC
615 if (m_context.getTestContext().getCommandLine().isSubProcess())
616 #endif // CTS_USES_VULKANSC
617 {
618 const bool isHighQuality = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::TextureCubeView)texture.getTexture(),
619 &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
620
621 if (!isHighQuality)
622 {
623 // Evaluate against lower precision requirements.
624 lodPrecision.lodBits = 4;
625 lookupPrecision.uvwBits = tcu::IVec3(4,4,0);
626
627 log << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
628
629 const bool isOk = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::TextureCubeView)texture.getTexture(),
630 &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
631
632 if (!isOk)
633 {
634 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
635 return tcu::TestStatus::fail("Image verification failed");
636 }
637 }
638 }
639 }
640 }
641
642 m_caseNdx += 1;
643 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
644 }
645
646 // 2D array filtering
647
648 class Texture2DArrayFilteringTestInstance : public TestInstance
649 {
650 public:
651 typedef Texture2DArrayTestCaseParameters ParameterType;
652
653 Texture2DArrayFilteringTestInstance (Context& context, const ParameterType& testParameters);
654 ~Texture2DArrayFilteringTestInstance (void);
655
656 virtual tcu::TestStatus iterate (void);
657
658 private:
659 Texture2DArrayFilteringTestInstance (const Texture2DArrayFilteringTestInstance&);
660 Texture2DArrayFilteringTestInstance& operator= (const Texture2DArrayFilteringTestInstance&);
661
662 struct FilterCase
663 {
664 int textureIndex;
665 tcu::Vec2 lod;
666 tcu::Vec2 offset;
667 tcu::Vec2 layerRange;
668
FilterCasevkt::texture::__anon9a19a5410111::Texture2DArrayFilteringTestInstance::FilterCase669 FilterCase (void)
670 : textureIndex(-1)
671 {
672 }
673
FilterCasevkt::texture::__anon9a19a5410111::Texture2DArrayFilteringTestInstance::FilterCase674 FilterCase (const int tex_, const tcu::Vec2& lod_, const tcu::Vec2& offset_, const tcu::Vec2& layerRange_)
675 : textureIndex (tex_)
676 , lod (lod_)
677 , offset (offset_)
678 , layerRange (layerRange_)
679 {
680 }
681 };
682
683 const ParameterType m_testParameters;
684 vector<TestTexture2DArraySp> m_textures;
685 vector<FilterCase> m_cases;
686 TextureRenderer m_renderer;
687 int m_caseNdx;
688 };
689
Texture2DArrayFilteringTestInstance(Context & context,const ParameterType & testParameters)690 Texture2DArrayFilteringTestInstance::Texture2DArrayFilteringTestInstance (Context& context, const ParameterType& testParameters)
691 : TestInstance (context)
692 , m_testParameters (testParameters)
693 , m_renderer (context, testParameters.sampleCount, TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT)
694 , m_caseNdx (0)
695 {
696 const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height)) + 1;
697 const tcu::TextureFormat texFormat = vk::mapVkFormat(m_testParameters.format);
698 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat);
699 tcu::Vec4 cBias, cScale;
700 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
701 {
702 const tcu::TextureFormat texFormatStencil = vk::mapVkFormat(VK_FORMAT_S8_UINT);
703 const tcu::TextureFormatInfo fmtInfoStencil = tcu::getTextureFormatInfo(texFormatStencil);
704 cBias = fmtInfoStencil.valueMin;
705 cScale = fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
706 }
707 else
708 {
709 cBias = fmtInfo.valueMin;
710 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
711 }
712
713 // Create textures.
714 m_textures.reserve(2);
715 for (int ndx = 0; ndx < 2; ndx++)
716 m_textures.push_back(TestTexture2DArraySp(new pipeline::TestTexture2DArray(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.numLayers)));
717
718 const tcu::IVec4 levelSwz[] =
719 {
720 tcu::IVec4(0,1,2,3),
721 tcu::IVec4(2,1,3,0),
722 tcu::IVec4(3,0,1,2),
723 tcu::IVec4(1,3,2,0),
724 };
725
726 // Fill first gradient texture (gradient direction varies between layers).
727 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
728 {
729 for (int layerNdx = 0; layerNdx < m_testParameters.numLayers; layerNdx++)
730 {
731 const tcu::IVec4 swz = levelSwz[layerNdx%DE_LENGTH_OF_ARRAY(levelSwz)];
732 const tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
733 const tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
734
735 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
736 tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, layerNdx), tcu::Sampler::MODE_STENCIL), gMin, gMax);
737 else
738 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, layerNdx), gMin, gMax);
739 }
740 }
741
742 // Fill second with grid texture (each layer has unique colors).
743 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
744 {
745 for (int layerNdx = 0; layerNdx < m_testParameters.numLayers; layerNdx++)
746 {
747 const deUint32 step = 0x00ffffff / (numLevels*m_testParameters.numLayers - 1);
748 const deUint32 rgb = step * (levelNdx + layerNdx*numLevels);
749 const deUint32 colorA = 0xff000000 | rgb;
750 const deUint32 colorB = 0xff000000 | ~rgb;
751
752 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
753 tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, layerNdx), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
754 else
755 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, layerNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
756 }
757 }
758
759 // Upload.
760 for (vector<TestTexture2DArraySp>::const_iterator i = m_textures.begin(); i != m_textures.end(); i++)
761 {
762 m_renderer.add2DArrayTexture(*i, testParameters.aspectMask);
763 }
764
765 // Test cases
766 m_cases.push_back(FilterCase(0, tcu::Vec2( 1.5f, 2.8f ), tcu::Vec2(-1.0f, -2.7f), tcu::Vec2(-0.5f, float(m_testParameters.numLayers)+0.5f)));
767 m_cases.push_back(FilterCase(1, tcu::Vec2( 0.2f, 0.175f), tcu::Vec2(-2.0f, -3.7f), tcu::Vec2(-0.5f, float(m_testParameters.numLayers)+0.5f)));
768 m_cases.push_back(FilterCase(1, tcu::Vec2(-0.8f, -2.3f ), tcu::Vec2( 0.2f, -0.1f), tcu::Vec2(float(m_testParameters.numLayers)+0.5f, -0.5f)));
769 m_cases.push_back(FilterCase(0, tcu::Vec2(-2.0f, -1.5f ), tcu::Vec2(-0.1f, 0.9f), tcu::Vec2(1.50001f, 1.49999f)));
770 }
771
~Texture2DArrayFilteringTestInstance(void)772 Texture2DArrayFilteringTestInstance::~Texture2DArrayFilteringTestInstance (void)
773 {
774 }
775
iterate(void)776 tcu::TestStatus Texture2DArrayFilteringTestInstance::iterate (void)
777 {
778 tcu::TestLog& log = m_context.getTestContext().getLog();
779
780 const FilterCase& curCase = m_cases[m_caseNdx];
781 const pipeline::TestTexture2DArray& texture = m_renderer.get2DArrayTexture(curCase.textureIndex);
782 const tcu::TextureFormat texFmt = texture.getTextureFormat();
783 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
784 ReferenceParams refParams (TEXTURETYPE_2D_ARRAY);
785 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
786 tcu::Vec3 texCoord[4];
787 const float* const texCoordPtr = (const float*)&texCoord[0];
788
789 // Params for reference computation.
790
791 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter);
792 if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
793 {
794 refParams.sampler.depthStencilMode = tcu::Sampler::MODE_STENCIL;
795 refParams.samplerType = SAMPLERTYPE_UINT;
796 }
797 else
798 refParams.samplerType = getSamplerType(texFmt);
799 refParams.lodMode = LODMODE_EXACT;
800 refParams.colorBias = fmtInfo.lookupBias;
801 refParams.colorScale = fmtInfo.lookupScale;
802
803 // Compute texture coordinates.
804 log << TestLog::Message << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;
805
806 {
807 const float lodX = curCase.lod.x();
808 const float lodY = curCase.lod.y();
809 const float oX = curCase.offset.x();
810 const float oY = curCase.offset.y();
811 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[0]->getTexture().getWidth());
812 const float sY = deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[0]->getTexture().getHeight());
813 const float l0 = curCase.layerRange.x();
814 const float l1 = curCase.layerRange.y();
815
816 texCoord[0] = tcu::Vec3(oX, oY, l0);
817 texCoord[1] = tcu::Vec3(oX, oY+sY, l0*0.5f + l1*0.5f);
818 texCoord[2] = tcu::Vec3(oX+sX, oY, l0*0.5f + l1*0.5f);
819 texCoord[3] = tcu::Vec3(oX+sX, oY+sY, l1);
820 }
821
822 m_renderer.renderQuad(rendered, curCase.textureIndex, texCoordPtr, refParams);
823
824 {
825
826 const bool isNearestOnly = m_testParameters.minFilter == Sampler::NEAREST && m_testParameters.magFilter == Sampler::NEAREST;
827 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
828 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
829 const tcu::IVec4 colorBits = max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
830 tcu::LodPrecision lodPrecision;
831 tcu::LookupPrecision lookupPrecision;
832
833 lodPrecision.derivateBits = 18;
834 lodPrecision.lodBits = 6;
835 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
836 lookupPrecision.coordBits = tcu::IVec3(20,20,20);
837 lookupPrecision.uvwBits = tcu::IVec3(7,7,0);
838 lookupPrecision.colorMask = getCompareMask(pixelFormat);
839
840 #ifdef CTS_USES_VULKANSC
841 if (m_context.getTestContext().getCommandLine().isSubProcess())
842 #endif // CTS_USES_VULKANSC
843 {
844 const bool isHighQuality = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture2DArrayView)texture.getTexture(),
845 texCoordPtr, refParams, lookupPrecision, lodPrecision, pixelFormat);
846
847 if (!isHighQuality)
848 {
849 // Evaluate against lower precision requirements.
850 lodPrecision.lodBits = 4;
851 lookupPrecision.uvwBits = tcu::IVec3(4,4,0);
852
853 log << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
854
855 const bool isOk = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture2DArrayView)texture.getTexture(),
856 texCoordPtr, refParams, lookupPrecision, lodPrecision, pixelFormat);
857
858 if (!isOk)
859 {
860 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
861 return tcu::TestStatus::fail("Image verification failed");
862 }
863 }
864 }
865 }
866
867 m_caseNdx += 1;
868 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
869 }
870
871 // 3D filtering
872
873 class Texture3DFilteringTestInstance : public TestInstance
874 {
875 public:
876 typedef Texture3DTestCaseParameters ParameterType;
877
878 Texture3DFilteringTestInstance (Context& context, const ParameterType& testParameters);
879 ~Texture3DFilteringTestInstance (void);
880
881 virtual tcu::TestStatus iterate (void);
882
883 private:
884 Texture3DFilteringTestInstance (const Texture3DFilteringTestInstance& other);
885 Texture3DFilteringTestInstance& operator= (const Texture3DFilteringTestInstance& other);
886
887 struct FilterCase
888 {
889 int textureIndex;
890 tcu::Vec3 lod;
891 tcu::Vec3 offset;
892
FilterCasevkt::texture::__anon9a19a5410111::Texture3DFilteringTestInstance::FilterCase893 FilterCase (void)
894 : textureIndex(-1)
895 {
896 }
897
FilterCasevkt::texture::__anon9a19a5410111::Texture3DFilteringTestInstance::FilterCase898 FilterCase (const int tex_, const tcu::Vec3& lod_, const tcu::Vec3& offset_)
899 : textureIndex (tex_)
900 , lod (lod_)
901 , offset (offset_)
902 {
903 }
904 };
905
906 const ParameterType m_testParameters;
907 vector<TestTexture3DSp> m_textures;
908 vector<FilterCase> m_cases;
909 TextureRenderer m_renderer;
910 int m_caseNdx;
911 };
912
Texture3DFilteringTestInstance(Context & context,const ParameterType & testParameters)913 Texture3DFilteringTestInstance::Texture3DFilteringTestInstance (Context& context, const ParameterType& testParameters)
914 : TestInstance (context)
915 , m_testParameters (testParameters)
916 , m_renderer (context, testParameters.sampleCount, TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT)
917 , m_caseNdx (0)
918 {
919 const int numLevels = deLog2Floor32(de::max(de::max(m_testParameters.width, m_testParameters.height), m_testParameters.depth)) + 1;
920 const tcu::TextureFormat texFormat = vk::mapVkFormat(m_testParameters.format);
921 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFormat);
922 tcu::Vec4 cBias, cScale;
923 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
924 {
925 const tcu::TextureFormat texFormatStencil = vk::mapVkFormat(VK_FORMAT_S8_UINT);
926 const tcu::TextureFormatInfo fmtInfoStencil = tcu::getTextureFormatInfo(texFormatStencil);
927 cBias = fmtInfoStencil.valueMin;
928 cScale = fmtInfoStencil.valueMax - fmtInfoStencil.valueMin;
929 }
930 else
931 {
932 cBias = fmtInfo.valueMin;
933 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
934 }
935
936 // Create textures.
937 m_textures.reserve(2);
938 for (int ndx = 0; ndx < 2; ndx++)
939 m_textures.push_back(TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.depth)));
940
941 // Fill first gradient texture.
942 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
943 {
944 const tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
945 const tcu::Vec4 gMax = tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)*cScale + cBias;
946
947 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
948 tcu::fillWithComponentGradients(getEffectiveDepthStencilAccess(m_textures[0]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), gMin, gMax);
949 else
950 tcu::fillWithComponentGradients(m_textures[0]->getLevel(levelNdx, 0), gMin, gMax);
951
952 }
953
954 // Fill second with grid texture.
955 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
956 {
957 const deUint32 step = 0x00ffffff / numLevels;
958 const deUint32 rgb = step*levelNdx;
959 const deUint32 colorA = 0xff000000 | rgb;
960 const deUint32 colorB = 0xff000000 | ~rgb;
961
962 if (texFormat.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
963 tcu::fillWithGrid(getEffectiveDepthStencilAccess(m_textures[1]->getLevel(levelNdx, 0), tcu::Sampler::MODE_STENCIL), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
964 else
965 tcu::fillWithGrid(m_textures[1]->getLevel(levelNdx, 0), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
966
967 }
968
969 // Upload.
970 for (vector<TestTexture3DSp>::const_iterator i = m_textures.begin(); i != m_textures.end(); i++)
971 {
972 m_renderer.add3DTexture(*i, testParameters.aspectMask);
973 }
974
975 // Test cases
976 m_cases.push_back(FilterCase(0, tcu::Vec3(1.5f, 2.8f, 1.0f), tcu::Vec3(-1.0f, -2.7f, -2.275f)));
977 m_cases.push_back(FilterCase(0, tcu::Vec3(-2.0f, -1.5f, -1.8f), tcu::Vec3(-0.1f, 0.9f, -0.25f)));
978 m_cases.push_back(FilterCase(1, tcu::Vec3(0.2f, 0.175f, 0.3f), tcu::Vec3(-2.0f, -3.7f, -1.825f)));
979 m_cases.push_back(FilterCase(1, tcu::Vec3(-0.8f, -2.3f, -2.5f), tcu::Vec3(0.2f, -0.1f, 1.325f)));
980 }
981
~Texture3DFilteringTestInstance(void)982 Texture3DFilteringTestInstance::~Texture3DFilteringTestInstance (void)
983 {
984 }
985
iterate(void)986 tcu::TestStatus Texture3DFilteringTestInstance::iterate (void)
987 {
988 tcu::TestLog& log = m_context.getTestContext().getLog();
989
990 const pipeline::TestTexture3D& texture = m_renderer.get3DTexture(m_cases[m_caseNdx].textureIndex);
991 const tcu::TextureFormat texFmt = texture.getTextureFormat();
992 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt);
993 const FilterCase& curCase = m_cases[m_caseNdx];
994 ReferenceParams refParams (TEXTURETYPE_3D);
995 tcu::Surface rendered (m_renderer.getRenderWidth(), m_renderer.getRenderHeight());
996 tcu::Vec3 texCoord[4];
997 const float* const texCoordPtr = (const float*)&texCoord[0];
998
999 // Params for reference computation.
1000 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.wrapR, m_testParameters.minFilter, m_testParameters.magFilter);
1001 if (texFmt.order == tcu::TextureFormat::DS && m_testParameters.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
1002 {
1003 refParams.sampler.depthStencilMode = tcu::Sampler::MODE_STENCIL;
1004 refParams.samplerType = SAMPLERTYPE_UINT;
1005 }
1006 else
1007 refParams.samplerType = getSamplerType(texFmt);
1008 refParams.lodMode = LODMODE_EXACT;
1009 refParams.colorBias = fmtInfo.lookupBias;
1010 refParams.colorScale = fmtInfo.lookupScale;
1011
1012 // Compute texture coordinates.
1013 log << TestLog::Message << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;
1014
1015 {
1016 const float lodX = curCase.lod.x();
1017 const float lodY = curCase.lod.y();
1018 const float lodZ = curCase.lod.z();
1019 const float oX = curCase.offset.x();
1020 const float oY = curCase.offset.y();
1021 const float oZ = curCase.offset.z();
1022 const float sX = deFloatExp2(lodX) * float(m_renderer.getRenderWidth()) / float(m_textures[0]->getTexture().getWidth());
1023 const float sY = deFloatExp2(lodY) * float(m_renderer.getRenderHeight()) / float(m_textures[0]->getTexture().getHeight());
1024 const float sZ = deFloatExp2(lodZ) * float(de::max(m_renderer.getRenderWidth(), m_renderer.getRenderHeight())) / float(m_textures[0]->getTexture().getDepth());
1025
1026 texCoord[0] = tcu::Vec3(oX, oY, oZ);
1027 texCoord[1] = tcu::Vec3(oX, oY+sY, oZ + sZ*0.5f);
1028 texCoord[2] = tcu::Vec3(oX+sX, oY, oZ + sZ*0.5f);
1029 texCoord[3] = tcu::Vec3(oX+sX, oY+sY, oZ + sZ);
1030 }
1031
1032 m_renderer.renderQuad(rendered, curCase.textureIndex, texCoordPtr, refParams);
1033
1034 {
1035 const bool isNearestOnly = m_testParameters.minFilter == Sampler::NEAREST && m_testParameters.magFilter == Sampler::NEAREST;
1036 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
1037 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]);
1038 const tcu::IVec4 colorBits = max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
1039 tcu::LodPrecision lodPrecision;
1040 tcu::LookupPrecision lookupPrecision;
1041
1042 lodPrecision.derivateBits = 18;
1043 lodPrecision.lodBits = 6;
1044 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
1045 lookupPrecision.coordBits = tcu::IVec3(20,20,20);
1046 lookupPrecision.uvwBits = tcu::IVec3(7,7,7);
1047 lookupPrecision.colorMask = getCompareMask(pixelFormat);
1048
1049 #ifdef CTS_USES_VULKANSC
1050 if (m_context.getTestContext().getCommandLine().isSubProcess())
1051 #endif // CTS_USES_VULKANSC
1052 {
1053 const bool isHighQuality = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture3DView)texture.getTexture(),
1054 texCoordPtr, refParams, lookupPrecision, lodPrecision, pixelFormat);
1055
1056 if (!isHighQuality)
1057 {
1058 // Evaluate against lower precision requirements.
1059 lodPrecision.lodBits = 4;
1060 lookupPrecision.uvwBits = tcu::IVec3(4,4,4);
1061
1062 log << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;
1063
1064 const bool isOk = verifyTextureResult(m_context.getTestContext(), rendered.getAccess(), (tcu::Texture3DView)texture.getTexture(),
1065 texCoordPtr, refParams, lookupPrecision, lodPrecision, pixelFormat);
1066
1067 if (!isOk)
1068 {
1069 log << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
1070 return tcu::TestStatus::fail("Image verification failed");
1071 }
1072 }
1073 }
1074 }
1075
1076 m_caseNdx += 1;
1077 return m_caseNdx < (int)m_cases.size() ? tcu::TestStatus::incomplete() : tcu::TestStatus::pass("Pass");
1078 }
1079
verifierCanBeUsed(const VkFormat format,const Sampler::FilterMode minFilter,const Sampler::FilterMode magFilter)1080 bool verifierCanBeUsed(const VkFormat format, const Sampler::FilterMode minFilter, const Sampler::FilterMode magFilter)
1081 {
1082 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1083 const tcu::TextureChannelClass textureChannelClass = tcu::getTextureChannelClass(textureFormat.type);
1084
1085 return !(!(textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
1086 textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
1087 textureChannelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) &&
1088 (tcu::TexVerifierUtil::isLinearFilter(minFilter) || tcu::TexVerifierUtil::isLinearFilter(magFilter) ||
1089 tcu::TexVerifierUtil::isCubicFilter(minFilter) || tcu::TexVerifierUtil::isCubicFilter(magFilter)));
1090 }
1091
1092 } // anonymous
1093
populateTextureFilteringTests(tcu::TestCaseGroup * textureFilteringTests)1094 void populateTextureFilteringTests (tcu::TestCaseGroup* textureFilteringTests)
1095 {
1096 tcu::TestContext& testCtx = textureFilteringTests->getTestContext();
1097
1098 static const struct
1099 {
1100 const char* const name;
1101 const Sampler::WrapMode mode;
1102 } wrapModes[] =
1103 {
1104 { "repeat", Sampler::REPEAT_GL },
1105 { "mirrored_repeat", Sampler::MIRRORED_REPEAT_GL },
1106 { "clamp_to_edge", Sampler::CLAMP_TO_EDGE },
1107 { "clamp_to_border", Sampler::CLAMP_TO_BORDER },
1108 { "mirror_clamp_to_edge", Sampler::MIRRORED_ONCE }
1109 };
1110
1111 struct FilterModes
1112 {
1113 const char* const name;
1114 const Sampler::FilterMode mode;
1115 };
1116
1117 static const FilterModes minFilterModes[] =
1118 {
1119 { "nearest", Sampler::NEAREST },
1120 { "linear", Sampler::LINEAR },
1121 { "nearest_mipmap_nearest", Sampler::NEAREST_MIPMAP_NEAREST },
1122 { "linear_mipmap_nearest", Sampler::LINEAR_MIPMAP_NEAREST },
1123 { "nearest_mipmap_linear", Sampler::NEAREST_MIPMAP_LINEAR },
1124 { "linear_mipmap_linear", Sampler::LINEAR_MIPMAP_LINEAR }
1125 };
1126
1127 static const FilterModes magFilterModes[] =
1128 {
1129 { "nearest", Sampler::NEAREST },
1130 { "linear", Sampler::LINEAR }
1131 };
1132
1133 static const FilterModes minFilterModes2D[] =
1134 {
1135 { "nearest", Sampler::NEAREST },
1136 { "linear", Sampler::LINEAR },
1137 { "cubic", Sampler::CUBIC },
1138 { "nearest_mipmap_nearest", Sampler::NEAREST_MIPMAP_NEAREST },
1139 { "linear_mipmap_nearest", Sampler::LINEAR_MIPMAP_NEAREST },
1140 { "nearest_mipmap_linear", Sampler::NEAREST_MIPMAP_LINEAR },
1141 { "linear_mipmap_linear", Sampler::LINEAR_MIPMAP_LINEAR },
1142 { "cubic_mipmap_nearest", Sampler::CUBIC_MIPMAP_NEAREST },
1143 { "cubic_mipmap_linear", Sampler::CUBIC_MIPMAP_LINEAR }
1144 };
1145
1146 static const FilterModes magFilterModes2D[] =
1147 {
1148 { "nearest", Sampler::NEAREST },
1149 { "linear", Sampler::LINEAR },
1150 { "cubic", Sampler::CUBIC }
1151 };
1152
1153 static const struct
1154 {
1155 const int width;
1156 const int height;
1157 } sizes2D[] =
1158 {
1159 { 4, 8 },
1160 { 32, 64 },
1161 { 128, 128 },
1162 { 3, 7 },
1163 { 31, 55 },
1164 { 127, 99 }
1165 };
1166
1167 static const struct
1168 {
1169 const int size;
1170 } sizesCube[] =
1171 {
1172 { 8 },
1173 { 64 },
1174 { 128 },
1175 { 7 },
1176 { 63 }
1177 };
1178
1179 static const struct
1180 {
1181 const int width;
1182 const int height;
1183 const int numLayers;
1184 } sizes2DArray[] =
1185 {
1186 { 4, 8, 8 },
1187 { 32, 64, 16 },
1188 { 128, 32, 64 },
1189 { 3, 7, 5 },
1190 { 63, 63, 63 }
1191 };
1192
1193 static const struct
1194 {
1195 const int width;
1196 const int height;
1197 const int depth;
1198 } sizes3D[] =
1199 {
1200 { 4, 8, 8 },
1201 { 32, 64, 16 },
1202 { 128, 32, 64 },
1203 { 3, 7, 5 },
1204 { 63, 63, 63 }
1205 };
1206
1207 static const struct
1208 {
1209 const char* const name;
1210 const VkFormat format;
1211 const VkImageAspectFlags aspectMask;
1212 const Program program2D;
1213 const Program programCube;
1214 const Program program2DArray;
1215 const Program program3D;
1216 } filterableFormatsByType[] =
1217 {
1218 { "r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1219 { "b10g11r11_ufloat", VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1220 { "e5b9g9r9_ufloat", VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1221 { "r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1222 { "r8g8b8a8_snorm", VK_FORMAT_R8G8B8A8_SNORM, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1223 { "r5g6b5_unorm", VK_FORMAT_R5G6B5_UNORM_PACK16, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1224 { "r10x6g10x6b10x6a10x6_unorm", VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1225 { "r4g4b4a4_unorm", VK_FORMAT_R4G4B4A4_UNORM_PACK16, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1226 { "a4r4g4b4_unorm", VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1227 { "a4b4g4r4_unorm", VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1228 { "r5g5b5a1_unorm", VK_FORMAT_R5G5B5A1_UNORM_PACK16, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1229 { "a8b8g8r8_srgb", VK_FORMAT_A8B8G8R8_SRGB_PACK32, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1230 { "a1r5g5b5_unorm", VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_IMAGE_ASPECT_COLOR_BIT, PROGRAM_2D_FLOAT, PROGRAM_CUBE_FLOAT, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_3D_FLOAT },
1231 { "s8_uint", VK_FORMAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT, PROGRAM_2D_UINT, PROGRAM_CUBE_UINT, PROGRAM_2D_ARRAY_UINT, PROGRAM_3D_UINT },
1232 { "d24_unorm_s8_uint_stencil", VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT, PROGRAM_2D_UINT, PROGRAM_CUBE_UINT, PROGRAM_2D_ARRAY_UINT, PROGRAM_3D_UINT },
1233 { "d32_sfloat_s8_uint_stencil", VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT, PROGRAM_2D_UINT, PROGRAM_CUBE_UINT, PROGRAM_2D_ARRAY_UINT, PROGRAM_3D_UINT }
1234 };
1235
1236 // 2D texture filtering.
1237 {
1238 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d", "2D Texture Filtering"));
1239
1240 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1241 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1242 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1243
1244 // Formats.
1245 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1246 {
1247 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1248 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1249
1250 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); filterNdx++)
1251 {
1252 const Sampler::FilterMode minFilter = minFilterModes2D[filterNdx].mode;
1253 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR && minFilter != Sampler::CUBIC;
1254 const string name = minFilterModes2D[filterNdx].name;
1255 Texture2DTestCaseParameters testParameters;
1256
1257 testParameters.format = filterableFormatsByType[fmtNdx].format;
1258 testParameters.minFilter = minFilter;
1259 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1260 testParameters.mipmaps = true;
1261
1262 testParameters.wrapS = Sampler::REPEAT_GL;
1263 testParameters.wrapT = Sampler::REPEAT_GL;
1264 testParameters.width = 64;
1265 testParameters.height = 64;
1266
1267 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1268 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
1269
1270 // Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
1271 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1272 {
1273 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1274 }
1275 }
1276 formatsGroup->addChild(filterGroup.release());
1277 }
1278
1279 // Sizes.
1280 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
1281 {
1282 const string filterGroupName = de::toString(sizes2D[sizeNdx].width) + "x" + de::toString(sizes2D[sizeNdx].height);
1283 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1284
1285 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); filterNdx++)
1286 {
1287 const Sampler::FilterMode minFilter = minFilterModes2D[filterNdx].mode;
1288 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR && minFilter != Sampler::CUBIC;
1289 const string name = minFilterModes2D[filterNdx].name;
1290 Texture2DTestCaseParameters testParameters;
1291
1292 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1293 testParameters.minFilter = minFilter;
1294 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1295 testParameters.mipmaps = true;
1296
1297 testParameters.wrapS = Sampler::REPEAT_GL;
1298 testParameters.wrapT = Sampler::REPEAT_GL;
1299 testParameters.width = sizes2D[sizeNdx].width;
1300 testParameters.height = sizes2D[sizeNdx].height;
1301
1302 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1303 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1304
1305 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1306 }
1307 sizesGroup->addChild(filterGroup.release());
1308 }
1309
1310 // Wrap modes.
1311 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); minFilterNdx++)
1312 {
1313 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes2D[minFilterNdx].name, ""));
1314
1315 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); magFilterNdx++)
1316 {
1317 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes2D[magFilterNdx].name, ""));
1318
1319 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1320 {
1321 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name, ""));
1322
1323 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1324 {
1325 const string name = wrapModes[wrapTNdx].name;
1326 Texture2DTestCaseParameters testParameters;
1327
1328 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1329 testParameters.minFilter = minFilterModes2D[minFilterNdx].mode;
1330 testParameters.magFilter = magFilterModes2D[magFilterNdx].mode;
1331 testParameters.mipmaps = true;
1332
1333 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1334 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1335 testParameters.width = 63;
1336 testParameters.height = 57;
1337
1338 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1339 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1340
1341 wrapSGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1342 }
1343 magFilterGroup->addChild(wrapSGroup.release());
1344 }
1345 minFilterGroup->addChild(magFilterGroup.release());
1346 }
1347 combinationsGroup->addChild(minFilterGroup.release());
1348 }
1349
1350 group2D->addChild(formatsGroup.release());
1351 group2D->addChild(sizesGroup.release());
1352 group2D->addChild(combinationsGroup.release());
1353
1354 textureFilteringTests->addChild(group2D.release());
1355 }
1356
1357 // Unnormalized texture filtering.
1358 {
1359 de::MovePtr<tcu::TestCaseGroup> groupUnnormal (new tcu::TestCaseGroup(testCtx, "unnormal", "Unnormalized Texture Filtering"));
1360
1361 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1362 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1363
1364 // Formats.
1365 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1366 {
1367 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1368 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1369
1370 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); filterNdx++)
1371 {
1372 const Sampler::FilterMode magFilter = magFilterModes2D[filterNdx].mode;
1373 const string name = magFilterModes2D[filterNdx].name;
1374 Texture2DTestCaseParameters testParameters;
1375
1376 testParameters.unnormal = true;
1377
1378 testParameters.format = filterableFormatsByType[fmtNdx].format;
1379 testParameters.minFilter = magFilter;
1380 testParameters.magFilter = magFilter;
1381 testParameters.mipmaps = false;
1382
1383 testParameters.wrapS = ((fmtNdx ^ filterNdx) & 1) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1384 testParameters.wrapT = ((fmtNdx ^ filterNdx) & 2) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1385 testParameters.width = 64;
1386 testParameters.height = 64;
1387
1388 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1389 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
1390
1391 // Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
1392 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1393 {
1394 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1395 }
1396 }
1397 formatsGroup->addChild(filterGroup.release());
1398 }
1399
1400 // Sizes.
1401 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
1402 {
1403 const string filterGroupName = de::toString(sizes2D[sizeNdx].width) + "x" + de::toString(sizes2D[sizeNdx].height);
1404 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1405
1406 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); filterNdx++)
1407 {
1408 const Sampler::FilterMode magFilter = magFilterModes2D[filterNdx].mode;
1409 const string name = magFilterModes2D[filterNdx].name;
1410 Texture2DTestCaseParameters testParameters;
1411
1412 testParameters.unnormal = true;
1413 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1414 testParameters.minFilter = magFilter;
1415 testParameters.magFilter = magFilter;
1416 testParameters.mipmaps = false;
1417
1418 testParameters.wrapS = ((sizeNdx ^ filterNdx) & 1) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1419 testParameters.wrapT = ((sizeNdx ^ filterNdx) & 2) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1420 testParameters.width = sizes2D[sizeNdx].width;
1421 testParameters.height = sizes2D[sizeNdx].height;
1422
1423 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1424 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1425
1426 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1427 }
1428 sizesGroup->addChild(filterGroup.release());
1429 }
1430
1431 groupUnnormal->addChild(formatsGroup.release());
1432 groupUnnormal->addChild(sizesGroup.release());
1433
1434 textureFilteringTests->addChild(groupUnnormal.release());
1435 }
1436
1437 // Cube map texture filtering.
1438 {
1439 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cube", "Cube Map Texture Filtering"));
1440
1441 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1442 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1443 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1444 de::MovePtr<tcu::TestCaseGroup> onlyFaceInteriorGroup (new tcu::TestCaseGroup(testCtx, "no_edges_visible", "Don't sample anywhere near a face's edges"));
1445
1446 // Formats.
1447 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1448 {
1449 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1450 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1451
1452 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1453 {
1454 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1455 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1456 const string name = minFilterModes[filterNdx].name;
1457 TextureCubeFilteringTestCaseParameters testParameters;
1458
1459 testParameters.format = filterableFormatsByType[fmtNdx].format;
1460 testParameters.minFilter = minFilter;
1461 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1462
1463 testParameters.wrapS = Sampler::REPEAT_GL;
1464 testParameters.wrapT = Sampler::REPEAT_GL;
1465 testParameters.onlySampleFaceInterior = false;
1466 testParameters.size = 64;
1467
1468 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1469 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].programCube);
1470
1471 // Some tests have to be skipped due to the restrictions of the verifiers.
1472 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1473 {
1474 filterGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1475 }
1476 }
1477 formatsGroup->addChild(filterGroup.release());
1478 }
1479
1480 // Sizes.
1481 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizesCube); sizeNdx++)
1482 {
1483 const string filterGroupName = de::toString(sizesCube[sizeNdx].size) + "x" + de::toString(sizesCube[sizeNdx].size);
1484 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1485
1486 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1487 {
1488 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1489 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1490 const string name = minFilterModes[filterNdx].name;
1491 TextureCubeFilteringTestCaseParameters testParameters;
1492
1493 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1494 testParameters.minFilter = minFilter;
1495 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1496 testParameters.wrapS = Sampler::REPEAT_GL;
1497 testParameters.wrapT = Sampler::REPEAT_GL;
1498 testParameters.onlySampleFaceInterior = false;
1499 testParameters.size = sizesCube[sizeNdx].size;
1500
1501 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1502 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1503
1504 filterGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1505
1506 }
1507 sizesGroup->addChild(filterGroup.release());
1508 }
1509
1510 // Filter/wrap mode combinations.
1511 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1512 {
1513 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name, ""));
1514
1515 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1516 {
1517 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name, ""));
1518
1519 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1520 {
1521 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name, ""));
1522
1523 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1524 {
1525 const string name = wrapModes[wrapTNdx].name;
1526 TextureCubeFilteringTestCaseParameters testParameters;
1527
1528 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1529 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1530 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1531 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1532 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1533 testParameters.onlySampleFaceInterior = false;
1534 testParameters.size = 63;
1535
1536 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1537 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1538
1539 wrapSGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1540 }
1541 magFilterGroup->addChild(wrapSGroup.release());
1542 }
1543 minFilterGroup->addChild(magFilterGroup.release());
1544 }
1545 combinationsGroup->addChild(minFilterGroup.release());
1546 }
1547
1548 // Cases with no visible cube edges.
1549 for (int isLinearI = 0; isLinearI <= 1; isLinearI++)
1550 {
1551 const bool isLinear = isLinearI != 0;
1552 const string name = isLinear ? "linear" : "nearest";
1553 TextureCubeFilteringTestCaseParameters testParameters;
1554
1555 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1556 testParameters.minFilter = isLinear ? Sampler::LINEAR : Sampler::NEAREST;
1557 testParameters.magFilter = isLinear ? Sampler::LINEAR : Sampler::NEAREST;
1558 testParameters.wrapS = Sampler::REPEAT_GL;
1559 testParameters.wrapT = Sampler::REPEAT_GL;
1560 testParameters.onlySampleFaceInterior = true;
1561 testParameters.size = 63;
1562
1563 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1564 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1565
1566 onlyFaceInteriorGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1567 }
1568
1569 groupCube->addChild(formatsGroup.release());
1570 groupCube->addChild(sizesGroup.release());
1571 groupCube->addChild(combinationsGroup.release());
1572 groupCube->addChild(onlyFaceInteriorGroup.release());
1573
1574 textureFilteringTests->addChild(groupCube.release());
1575 }
1576
1577 // 2D array texture filtering.
1578 {
1579 de::MovePtr<tcu::TestCaseGroup> group2DArray (new tcu::TestCaseGroup(testCtx, "2d_array", "2D Array Texture Filtering"));
1580
1581 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Array Texture Formats"));
1582 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1583 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1584
1585 // Formats.
1586 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1587 {
1588 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1589 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1590
1591 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1592 {
1593 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1594 const char* const filterName = minFilterModes[filterNdx].name;
1595 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1596 const char* const formatName = filterableFormatsByType[fmtNdx].name;
1597 const string name = string(formatName) + "_" + filterName;
1598 Texture2DArrayTestCaseParameters testParameters;
1599
1600 testParameters.format = filterableFormatsByType[fmtNdx].format;
1601 testParameters.minFilter = minFilter;
1602 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1603
1604 testParameters.wrapS = Sampler::REPEAT_GL;
1605 testParameters.wrapT = Sampler::REPEAT_GL;
1606 testParameters.width = 128;
1607 testParameters.height = 128;
1608 testParameters.numLayers = 8;
1609
1610 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1611 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2DArray);
1612
1613 // Some tests have to be skipped due to the restrictions of the verifiers.
1614 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1615 {
1616 filterGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1617 }
1618 }
1619 formatsGroup->addChild(filterGroup.release());
1620 }
1621
1622 // Sizes.
1623 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2DArray); sizeNdx++)
1624 {
1625 const string filterGroupName = de::toString(sizes2DArray[sizeNdx].width) + "x" + de::toString(sizes2DArray[sizeNdx].height) + "x" + de::toString(sizes2DArray[sizeNdx].numLayers);
1626 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1627
1628 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1629 {
1630 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1631 const char* const filterName = minFilterModes[filterNdx].name;
1632 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1633 const string name = filterName;
1634 Texture2DArrayTestCaseParameters testParameters;
1635
1636 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1637 testParameters.minFilter = minFilter;
1638 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1639 testParameters.wrapS = Sampler::REPEAT_GL;
1640 testParameters.wrapT = Sampler::REPEAT_GL;
1641 testParameters.width = sizes2DArray[sizeNdx].width;
1642 testParameters.height = sizes2DArray[sizeNdx].height;
1643 testParameters.numLayers = sizes2DArray[sizeNdx].numLayers;
1644
1645 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1646 testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
1647
1648 filterGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1649 }
1650 sizesGroup->addChild(filterGroup.release());
1651 }
1652
1653 // Wrap modes.
1654 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1655 {
1656 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name, ""));
1657
1658 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1659 {
1660 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name, ""));
1661
1662 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1663 {
1664 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name, ""));
1665
1666 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1667 {
1668 const string name = wrapModes[wrapTNdx].name;
1669 Texture2DArrayTestCaseParameters testParameters;
1670
1671 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1672 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1673 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1674 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1675 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1676 testParameters.width = 123;
1677 testParameters.height = 107;
1678 testParameters.numLayers = 7;
1679
1680 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1681 testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
1682
1683 wrapSGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1684 }
1685 magFilterGroup->addChild(wrapSGroup.release());
1686 }
1687 minFilterGroup->addChild(magFilterGroup.release());
1688 }
1689 combinationsGroup->addChild(minFilterGroup.release());
1690 }
1691
1692 group2DArray->addChild(formatsGroup.release());
1693 group2DArray->addChild(sizesGroup.release());
1694 group2DArray->addChild(combinationsGroup.release());
1695
1696 textureFilteringTests->addChild(group2DArray.release());
1697 }
1698
1699 // 3D texture filtering.
1700 {
1701 de::MovePtr<tcu::TestCaseGroup> group3D (new tcu::TestCaseGroup(testCtx, "3d", "3D Texture Filtering"));
1702
1703 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "3D Texture Formats"));
1704 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1705 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1706
1707 // Formats.
1708 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1709 {
1710 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1711 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1712
1713 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1714 {
1715 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1716 const char* const filterName = minFilterModes[filterNdx].name;
1717 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1718 const char* const formatName = filterableFormatsByType[fmtNdx].name;
1719 const string name = string(formatName) + "_" + filterName;
1720 Texture3DTestCaseParameters testParameters;
1721
1722 testParameters.format = filterableFormatsByType[fmtNdx].format;
1723 testParameters.minFilter = minFilter;
1724 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1725
1726 testParameters.wrapS = Sampler::REPEAT_GL;
1727 testParameters.wrapT = Sampler::REPEAT_GL;
1728 testParameters.wrapR = Sampler::REPEAT_GL;
1729 testParameters.width = 64;
1730 testParameters.height = 64;
1731 testParameters.depth = 64;
1732
1733 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1734 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program3D);
1735
1736 // Some tests have to be skipped due to the restrictions of the verifiers.
1737 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1738 {
1739 filterGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1740 }
1741 }
1742 formatsGroup->addChild(filterGroup.release());
1743 }
1744
1745 // Sizes.
1746 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes3D); sizeNdx++)
1747 {
1748 const string filterGroupName = de::toString(sizes3D[sizeNdx].width) + "x" + de::toString(sizes3D[sizeNdx].height) + "x" + de::toString(sizes3D[sizeNdx].depth);
1749 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str(), ""));
1750
1751 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1752 {
1753 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1754 const char* const filterName = minFilterModes[filterNdx].name;
1755 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1756 const string name = filterName;
1757 Texture3DTestCaseParameters testParameters;
1758
1759 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1760 testParameters.minFilter = minFilter;
1761 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1762 testParameters.wrapS = Sampler::REPEAT_GL;
1763 testParameters.wrapT = Sampler::REPEAT_GL;
1764 testParameters.wrapR = Sampler::REPEAT_GL;
1765 testParameters.width = sizes3D[sizeNdx].width;
1766 testParameters.height = sizes3D[sizeNdx].height;
1767 testParameters.depth = sizes3D[sizeNdx].depth;
1768
1769 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1770 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
1771
1772 filterGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1773 }
1774 sizesGroup->addChild(filterGroup.release());
1775 }
1776
1777 // Wrap modes.
1778 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1779 {
1780 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name, ""));
1781
1782 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1783 {
1784 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name, ""));
1785
1786 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1787 {
1788 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name, ""));
1789
1790 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1791 {
1792 de::MovePtr<tcu::TestCaseGroup> wrapTGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapTNdx].name, ""));
1793
1794 for (int wrapRNdx = 0; wrapRNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapRNdx++)
1795 {
1796 const string name = wrapModes[wrapRNdx].name;
1797 Texture3DTestCaseParameters testParameters;
1798
1799 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1800 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1801 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1802 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1803 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1804 testParameters.wrapR = wrapModes[wrapRNdx].mode;
1805 testParameters.width = 63;
1806 testParameters.height = 57;
1807 testParameters.depth = 67;
1808
1809 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1810 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
1811
1812 wrapTGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), "", testParameters));
1813 }
1814 wrapSGroup->addChild(wrapTGroup.release());
1815 }
1816 magFilterGroup->addChild(wrapSGroup.release());
1817 }
1818 minFilterGroup->addChild(magFilterGroup.release());
1819 }
1820 combinationsGroup->addChild(minFilterGroup.release());
1821 }
1822
1823 group3D->addChild(formatsGroup.release());
1824 group3D->addChild(sizesGroup.release());
1825 group3D->addChild(combinationsGroup.release());
1826
1827 textureFilteringTests->addChild(group3D.release());
1828 }
1829 }
1830
createTextureFilteringTests(tcu::TestContext & testCtx)1831 tcu::TestCaseGroup* createTextureFilteringTests (tcu::TestContext& testCtx)
1832 {
1833 return createTestGroup(testCtx, "filtering", "Texture filtering tests.", populateTextureFilteringTests);
1834 }
1835
1836 } // texture
1837 } // vkt
1838