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::__anon004d537b0111::Texture2DFilteringTestInstance::FilterCase205 FilterCase (void)
206 : textureIndex(-1)
207 {
208 }
209
FilterCasevkt::texture::__anon004d537b0111::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::__anon004d537b0111::TextureCubeFilteringTestInstance::FilterCase422 FilterCase (void)
423 : textureIndex(-1)
424 {
425 }
426
FilterCasevkt::texture::__anon004d537b0111::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::__anon004d537b0111::Texture2DArrayFilteringTestInstance::FilterCase669 FilterCase (void)
670 : textureIndex(-1)
671 {
672 }
673
FilterCasevkt::texture::__anon004d537b0111::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::__anon004d537b0111::Texture3DFilteringTestInstance::FilterCase893 FilterCase (void)
894 : textureIndex(-1)
895 {
896 }
897
FilterCasevkt::texture::__anon004d537b0111::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 // 2D Texture Filtering
1239 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d"));
1240
1241 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1242 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1243 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1244
1245 // Formats.
1246 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1247 {
1248 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1249 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1250
1251 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); filterNdx++)
1252 {
1253 const Sampler::FilterMode minFilter = minFilterModes2D[filterNdx].mode;
1254 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR && minFilter != Sampler::CUBIC;
1255 const string name = minFilterModes2D[filterNdx].name;
1256 Texture2DTestCaseParameters testParameters;
1257
1258 testParameters.format = filterableFormatsByType[fmtNdx].format;
1259 testParameters.minFilter = minFilter;
1260 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1261 testParameters.mipmaps = true;
1262
1263 testParameters.wrapS = Sampler::REPEAT_GL;
1264 testParameters.wrapT = Sampler::REPEAT_GL;
1265 testParameters.width = 64;
1266 testParameters.height = 64;
1267
1268 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1269 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
1270
1271 // Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
1272 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1273 {
1274 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1275 }
1276 }
1277 formatsGroup->addChild(filterGroup.release());
1278 }
1279
1280 // Sizes.
1281 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
1282 {
1283 const string filterGroupName = de::toString(sizes2D[sizeNdx].width) + "x" + de::toString(sizes2D[sizeNdx].height);
1284 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1285
1286 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); filterNdx++)
1287 {
1288 const Sampler::FilterMode minFilter = minFilterModes2D[filterNdx].mode;
1289 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR && minFilter != Sampler::CUBIC;
1290 const string name = minFilterModes2D[filterNdx].name;
1291 Texture2DTestCaseParameters testParameters;
1292
1293 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1294 testParameters.minFilter = minFilter;
1295 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1296 testParameters.mipmaps = true;
1297
1298 testParameters.wrapS = Sampler::REPEAT_GL;
1299 testParameters.wrapT = Sampler::REPEAT_GL;
1300 testParameters.width = sizes2D[sizeNdx].width;
1301 testParameters.height = sizes2D[sizeNdx].height;
1302
1303 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1304 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1305
1306 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1307 }
1308 sizesGroup->addChild(filterGroup.release());
1309 }
1310
1311 // Wrap modes.
1312 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes2D); minFilterNdx++)
1313 {
1314 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes2D[minFilterNdx].name));
1315
1316 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); magFilterNdx++)
1317 {
1318 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes2D[magFilterNdx].name));
1319
1320 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1321 {
1322 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name));
1323
1324 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1325 {
1326 const string name = wrapModes[wrapTNdx].name;
1327 Texture2DTestCaseParameters testParameters;
1328
1329 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1330 testParameters.minFilter = minFilterModes2D[minFilterNdx].mode;
1331 testParameters.magFilter = magFilterModes2D[magFilterNdx].mode;
1332 testParameters.mipmaps = true;
1333
1334 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1335 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1336 testParameters.width = 63;
1337 testParameters.height = 57;
1338
1339 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1340 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1341
1342 wrapSGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1343 }
1344 magFilterGroup->addChild(wrapSGroup.release());
1345 }
1346 minFilterGroup->addChild(magFilterGroup.release());
1347 }
1348 combinationsGroup->addChild(minFilterGroup.release());
1349 }
1350
1351 group2D->addChild(formatsGroup.release());
1352 group2D->addChild(sizesGroup.release());
1353 group2D->addChild(combinationsGroup.release());
1354
1355 textureFilteringTests->addChild(group2D.release());
1356 }
1357
1358 // Unnormalized texture filtering.
1359 {
1360 de::MovePtr<tcu::TestCaseGroup> groupUnnormal (new tcu::TestCaseGroup(testCtx, "unnormal", "Unnormalized Texture Filtering"));
1361
1362 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1363 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1364
1365 // Formats.
1366 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1367 {
1368 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1369 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1370
1371 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); filterNdx++)
1372 {
1373 const Sampler::FilterMode magFilter = magFilterModes2D[filterNdx].mode;
1374 const string name = magFilterModes2D[filterNdx].name;
1375 Texture2DTestCaseParameters testParameters;
1376
1377 testParameters.unnormal = true;
1378
1379 testParameters.format = filterableFormatsByType[fmtNdx].format;
1380 testParameters.minFilter = magFilter;
1381 testParameters.magFilter = magFilter;
1382 testParameters.mipmaps = false;
1383
1384 testParameters.wrapS = ((fmtNdx ^ filterNdx) & 1) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1385 testParameters.wrapT = ((fmtNdx ^ filterNdx) & 2) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1386 testParameters.width = 64;
1387 testParameters.height = 64;
1388
1389 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1390 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2D);
1391
1392 // Some combinations of the tests have to be skipped due to the restrictions of the verifiers.
1393 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1394 {
1395 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1396 }
1397 }
1398 formatsGroup->addChild(filterGroup.release());
1399 }
1400
1401 // Sizes.
1402 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
1403 {
1404 const string filterGroupName = de::toString(sizes2D[sizeNdx].width) + "x" + de::toString(sizes2D[sizeNdx].height);
1405 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1406
1407 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(magFilterModes2D); filterNdx++)
1408 {
1409 const Sampler::FilterMode magFilter = magFilterModes2D[filterNdx].mode;
1410 const string name = magFilterModes2D[filterNdx].name;
1411 Texture2DTestCaseParameters testParameters;
1412
1413 testParameters.unnormal = true;
1414 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1415 testParameters.minFilter = magFilter;
1416 testParameters.magFilter = magFilter;
1417 testParameters.mipmaps = false;
1418
1419 testParameters.wrapS = ((sizeNdx ^ filterNdx) & 1) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1420 testParameters.wrapT = ((sizeNdx ^ filterNdx) & 2) ? Sampler::CLAMP_TO_EDGE : Sampler::CLAMP_TO_BORDER;
1421 testParameters.width = sizes2D[sizeNdx].width;
1422 testParameters.height = sizes2D[sizeNdx].height;
1423
1424 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1425 testParameters.programs.push_back(PROGRAM_2D_FLOAT);
1426
1427 filterGroup->addChild(new TextureTestCase<Texture2DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1428 }
1429 sizesGroup->addChild(filterGroup.release());
1430 }
1431
1432 groupUnnormal->addChild(formatsGroup.release());
1433 groupUnnormal->addChild(sizesGroup.release());
1434
1435 textureFilteringTests->addChild(groupUnnormal.release());
1436 }
1437
1438 // Cube map texture filtering.
1439 {
1440 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cube", "Cube Map Texture Filtering"));
1441
1442 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Texture Formats"));
1443 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1444 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1445 de::MovePtr<tcu::TestCaseGroup> onlyFaceInteriorGroup (new tcu::TestCaseGroup(testCtx, "no_edges_visible", "Don't sample anywhere near a face's edges"));
1446
1447 // Formats.
1448 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1449 {
1450 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1451 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1452
1453 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1454 {
1455 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1456 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1457 const string name = minFilterModes[filterNdx].name;
1458 TextureCubeFilteringTestCaseParameters testParameters;
1459
1460 testParameters.format = filterableFormatsByType[fmtNdx].format;
1461 testParameters.minFilter = minFilter;
1462 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1463
1464 testParameters.wrapS = Sampler::REPEAT_GL;
1465 testParameters.wrapT = Sampler::REPEAT_GL;
1466 testParameters.onlySampleFaceInterior = false;
1467 testParameters.size = 64;
1468
1469 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1470 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].programCube);
1471
1472 // Some tests have to be skipped due to the restrictions of the verifiers.
1473 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1474 {
1475 filterGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1476 }
1477 }
1478 formatsGroup->addChild(filterGroup.release());
1479 }
1480
1481 // Sizes.
1482 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizesCube); sizeNdx++)
1483 {
1484 const string filterGroupName = de::toString(sizesCube[sizeNdx].size) + "x" + de::toString(sizesCube[sizeNdx].size);
1485 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1486
1487 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1488 {
1489 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1490 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1491 const string name = minFilterModes[filterNdx].name;
1492 TextureCubeFilteringTestCaseParameters testParameters;
1493
1494 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1495 testParameters.minFilter = minFilter;
1496 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1497 testParameters.wrapS = Sampler::REPEAT_GL;
1498 testParameters.wrapT = Sampler::REPEAT_GL;
1499 testParameters.onlySampleFaceInterior = false;
1500 testParameters.size = sizesCube[sizeNdx].size;
1501
1502 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1503 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1504
1505 filterGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1506
1507 }
1508 sizesGroup->addChild(filterGroup.release());
1509 }
1510
1511 // Filter/wrap mode combinations.
1512 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1513 {
1514 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name));
1515
1516 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1517 {
1518 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name));
1519
1520 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1521 {
1522 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name));
1523
1524 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1525 {
1526 const string name = wrapModes[wrapTNdx].name;
1527 TextureCubeFilteringTestCaseParameters testParameters;
1528
1529 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1530 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1531 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1532 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1533 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1534 testParameters.onlySampleFaceInterior = false;
1535 testParameters.size = 63;
1536
1537 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1538 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1539
1540 wrapSGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1541 }
1542 magFilterGroup->addChild(wrapSGroup.release());
1543 }
1544 minFilterGroup->addChild(magFilterGroup.release());
1545 }
1546 combinationsGroup->addChild(minFilterGroup.release());
1547 }
1548
1549 // Cases with no visible cube edges.
1550 for (int isLinearI = 0; isLinearI <= 1; isLinearI++)
1551 {
1552 const bool isLinear = isLinearI != 0;
1553 const string name = isLinear ? "linear" : "nearest";
1554 TextureCubeFilteringTestCaseParameters testParameters;
1555
1556 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1557 testParameters.minFilter = isLinear ? Sampler::LINEAR : Sampler::NEAREST;
1558 testParameters.magFilter = isLinear ? Sampler::LINEAR : Sampler::NEAREST;
1559 testParameters.wrapS = Sampler::REPEAT_GL;
1560 testParameters.wrapT = Sampler::REPEAT_GL;
1561 testParameters.onlySampleFaceInterior = true;
1562 testParameters.size = 63;
1563
1564 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1565 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT);
1566
1567 onlyFaceInteriorGroup->addChild(new TextureTestCase<TextureCubeFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1568 }
1569
1570 groupCube->addChild(formatsGroup.release());
1571 groupCube->addChild(sizesGroup.release());
1572 groupCube->addChild(combinationsGroup.release());
1573 groupCube->addChild(onlyFaceInteriorGroup.release());
1574
1575 textureFilteringTests->addChild(groupCube.release());
1576 }
1577
1578 // 2D array texture filtering.
1579 {
1580 de::MovePtr<tcu::TestCaseGroup> group2DArray (new tcu::TestCaseGroup(testCtx, "2d_array", "2D Array Texture Filtering"));
1581
1582 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "2D Array Texture Formats"));
1583 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1584 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1585
1586 // Formats.
1587 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1588 {
1589 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1590 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1591
1592 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1593 {
1594 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1595 const char* const filterName = minFilterModes[filterNdx].name;
1596 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1597 const char* const formatName = filterableFormatsByType[fmtNdx].name;
1598 const string name = string(formatName) + "_" + filterName;
1599 Texture2DArrayTestCaseParameters testParameters;
1600
1601 testParameters.format = filterableFormatsByType[fmtNdx].format;
1602 testParameters.minFilter = minFilter;
1603 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1604
1605 testParameters.wrapS = Sampler::REPEAT_GL;
1606 testParameters.wrapT = Sampler::REPEAT_GL;
1607 testParameters.width = 128;
1608 testParameters.height = 128;
1609 testParameters.numLayers = 8;
1610
1611 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1612 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program2DArray);
1613
1614 // Some tests have to be skipped due to the restrictions of the verifiers.
1615 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1616 {
1617 filterGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1618 }
1619 }
1620 formatsGroup->addChild(filterGroup.release());
1621 }
1622
1623 // Sizes.
1624 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2DArray); sizeNdx++)
1625 {
1626 const string filterGroupName = de::toString(sizes2DArray[sizeNdx].width) + "x" + de::toString(sizes2DArray[sizeNdx].height) + "x" + de::toString(sizes2DArray[sizeNdx].numLayers);
1627 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1628
1629 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1630 {
1631 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1632 const char* const filterName = minFilterModes[filterNdx].name;
1633 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1634 const string name = filterName;
1635 Texture2DArrayTestCaseParameters testParameters;
1636
1637 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1638 testParameters.minFilter = minFilter;
1639 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1640 testParameters.wrapS = Sampler::REPEAT_GL;
1641 testParameters.wrapT = Sampler::REPEAT_GL;
1642 testParameters.width = sizes2DArray[sizeNdx].width;
1643 testParameters.height = sizes2DArray[sizeNdx].height;
1644 testParameters.numLayers = sizes2DArray[sizeNdx].numLayers;
1645
1646 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1647 testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
1648
1649 filterGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1650 }
1651 sizesGroup->addChild(filterGroup.release());
1652 }
1653
1654 // Wrap modes.
1655 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1656 {
1657 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name));
1658
1659 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1660 {
1661 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name));
1662
1663 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1664 {
1665 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name));
1666
1667 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1668 {
1669 const string name = wrapModes[wrapTNdx].name;
1670 Texture2DArrayTestCaseParameters testParameters;
1671
1672 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1673 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1674 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1675 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1676 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1677 testParameters.width = 123;
1678 testParameters.height = 107;
1679 testParameters.numLayers = 7;
1680
1681 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1682 testParameters.programs.push_back(PROGRAM_2D_ARRAY_FLOAT);
1683
1684 wrapSGroup->addChild(new TextureTestCase<Texture2DArrayFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1685 }
1686 magFilterGroup->addChild(wrapSGroup.release());
1687 }
1688 minFilterGroup->addChild(magFilterGroup.release());
1689 }
1690 combinationsGroup->addChild(minFilterGroup.release());
1691 }
1692
1693 group2DArray->addChild(formatsGroup.release());
1694 group2DArray->addChild(sizesGroup.release());
1695 group2DArray->addChild(combinationsGroup.release());
1696
1697 textureFilteringTests->addChild(group2DArray.release());
1698 }
1699
1700 // 3D texture filtering.
1701 {
1702 de::MovePtr<tcu::TestCaseGroup> group3D (new tcu::TestCaseGroup(testCtx, "3d", "3D Texture Filtering"));
1703
1704 de::MovePtr<tcu::TestCaseGroup> formatsGroup (new tcu::TestCaseGroup(testCtx, "formats", "3D Texture Formats"));
1705 de::MovePtr<tcu::TestCaseGroup> sizesGroup (new tcu::TestCaseGroup(testCtx, "sizes", "Texture Sizes"));
1706 de::MovePtr<tcu::TestCaseGroup> combinationsGroup (new tcu::TestCaseGroup(testCtx, "combinations", "Filter and wrap mode combinations"));
1707
1708 // Formats.
1709 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
1710 {
1711 const string filterGroupName = filterableFormatsByType[fmtNdx].name;
1712 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1713
1714 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1715 {
1716 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1717 const char* const filterName = minFilterModes[filterNdx].name;
1718 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1719 const char* const formatName = filterableFormatsByType[fmtNdx].name;
1720 const string name = string(formatName) + "_" + filterName;
1721 Texture3DTestCaseParameters testParameters;
1722
1723 testParameters.format = filterableFormatsByType[fmtNdx].format;
1724 testParameters.minFilter = minFilter;
1725 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1726
1727 testParameters.wrapS = Sampler::REPEAT_GL;
1728 testParameters.wrapT = Sampler::REPEAT_GL;
1729 testParameters.wrapR = Sampler::REPEAT_GL;
1730 testParameters.width = 64;
1731 testParameters.height = 64;
1732 testParameters.depth = 64;
1733
1734 testParameters.aspectMask = filterableFormatsByType[fmtNdx].aspectMask;
1735 testParameters.programs.push_back(filterableFormatsByType[fmtNdx].program3D);
1736
1737 // Some tests have to be skipped due to the restrictions of the verifiers.
1738 if (verifierCanBeUsed(testParameters.format, testParameters.minFilter, testParameters.magFilter))
1739 {
1740 filterGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1741 }
1742 }
1743 formatsGroup->addChild(filterGroup.release());
1744 }
1745
1746 // Sizes.
1747 for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes3D); sizeNdx++)
1748 {
1749 const string filterGroupName = de::toString(sizes3D[sizeNdx].width) + "x" + de::toString(sizes3D[sizeNdx].height) + "x" + de::toString(sizes3D[sizeNdx].depth);
1750 de::MovePtr<tcu::TestCaseGroup> filterGroup (new tcu::TestCaseGroup(testCtx, filterGroupName.c_str()));
1751
1752 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
1753 {
1754 const Sampler::FilterMode minFilter = minFilterModes[filterNdx].mode;
1755 const char* const filterName = minFilterModes[filterNdx].name;
1756 const bool isMipmap = minFilter != Sampler::NEAREST && minFilter != Sampler::LINEAR;
1757 const string name = filterName;
1758 Texture3DTestCaseParameters testParameters;
1759
1760 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1761 testParameters.minFilter = minFilter;
1762 testParameters.magFilter = isMipmap ? Sampler::LINEAR : minFilter;
1763 testParameters.wrapS = Sampler::REPEAT_GL;
1764 testParameters.wrapT = Sampler::REPEAT_GL;
1765 testParameters.wrapR = Sampler::REPEAT_GL;
1766 testParameters.width = sizes3D[sizeNdx].width;
1767 testParameters.height = sizes3D[sizeNdx].height;
1768 testParameters.depth = sizes3D[sizeNdx].depth;
1769
1770 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1771 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
1772
1773 filterGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1774 }
1775 sizesGroup->addChild(filterGroup.release());
1776 }
1777
1778 // Wrap modes.
1779 for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
1780 {
1781 de::MovePtr<tcu::TestCaseGroup> minFilterGroup(new tcu::TestCaseGroup(testCtx, minFilterModes[minFilterNdx].name));
1782
1783 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
1784 {
1785 de::MovePtr<tcu::TestCaseGroup> magFilterGroup(new tcu::TestCaseGroup(testCtx, magFilterModes[magFilterNdx].name));
1786
1787 for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
1788 {
1789 de::MovePtr<tcu::TestCaseGroup> wrapSGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapSNdx].name));
1790
1791 for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
1792 {
1793 de::MovePtr<tcu::TestCaseGroup> wrapTGroup(new tcu::TestCaseGroup(testCtx, wrapModes[wrapTNdx].name));
1794
1795 for (int wrapRNdx = 0; wrapRNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapRNdx++)
1796 {
1797 const string name = wrapModes[wrapRNdx].name;
1798 Texture3DTestCaseParameters testParameters;
1799
1800 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
1801 testParameters.minFilter = minFilterModes[minFilterNdx].mode;
1802 testParameters.magFilter = magFilterModes[magFilterNdx].mode;
1803 testParameters.wrapS = wrapModes[wrapSNdx].mode;
1804 testParameters.wrapT = wrapModes[wrapTNdx].mode;
1805 testParameters.wrapR = wrapModes[wrapRNdx].mode;
1806 testParameters.width = 63;
1807 testParameters.height = 57;
1808 testParameters.depth = 67;
1809
1810 testParameters.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1811 testParameters.programs.push_back(PROGRAM_3D_FLOAT);
1812
1813 wrapTGroup->addChild(new TextureTestCase<Texture3DFilteringTestInstance>(testCtx, name.c_str(), testParameters));
1814 }
1815 wrapSGroup->addChild(wrapTGroup.release());
1816 }
1817 magFilterGroup->addChild(wrapSGroup.release());
1818 }
1819 minFilterGroup->addChild(magFilterGroup.release());
1820 }
1821 combinationsGroup->addChild(minFilterGroup.release());
1822 }
1823
1824 group3D->addChild(formatsGroup.release());
1825 group3D->addChild(sizesGroup.release());
1826 group3D->addChild(combinationsGroup.release());
1827
1828 textureFilteringTests->addChild(group3D.release());
1829 }
1830 }
1831
createTextureFilteringTests(tcu::TestContext & testCtx)1832 tcu::TestCaseGroup* createTextureFilteringTests (tcu::TestContext& testCtx)
1833 {
1834 return createTestGroup(testCtx, "filtering", populateTextureFilteringTests);
1835 }
1836
1837 } // texture
1838 } // vkt
1839