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