1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Sampler Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineSamplerTests.hpp"
26 #include "vktPipelineImageSamplingInstance.hpp"
27 #ifndef CTS_USES_VULKANSC
28 #include "vktPipelineSamplerBorderSwizzleTests.hpp"
29 #endif // CTS_USES_VULKANSC
30 #include "vktPipelineImageUtil.hpp"
31 #include "vktPipelineVertexUtil.hpp"
32 #include "vktTestCase.hpp"
33
34 #include "vkImageUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkBarrierUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkImageWithMemory.hpp"
43 #include "vkBufferWithMemory.hpp"
44
45 #include "tcuPlatform.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuTestLog.hpp"
48 #include "tcuMaybe.hpp"
49
50 #include "deStringUtil.hpp"
51 #include "deMemory.h"
52
53 #include <iomanip>
54 #include <sstream>
55 #include <vector>
56 #include <string>
57 #include <memory>
58 #include <utility>
59 #include <algorithm>
60
61 namespace vkt
62 {
63 namespace pipeline
64 {
65
66 using namespace vk;
67 using de::MovePtr;
68
69 namespace
70 {
71
72 class SamplerViewType
73 {
74 public:
SamplerViewType(vk::VkImageViewType type, bool normalized = true)75 SamplerViewType (vk::VkImageViewType type, bool normalized = true)
76 : m_viewType(type), m_normalized(normalized)
77 {
78 if (!normalized)
79 DE_ASSERT(type == vk::VK_IMAGE_VIEW_TYPE_2D || type == vk::VK_IMAGE_VIEW_TYPE_1D);
80 }
81
operator vk::VkImageViewType() const82 operator vk::VkImageViewType () const
83 {
84 return m_viewType;
85 }
86
isNormalized() const87 bool isNormalized () const
88 {
89 return m_normalized;
90 }
91
92 private:
93 vk::VkImageViewType m_viewType;
94 bool m_normalized;
95 };
96
97 class SamplerTest : public vkt::TestCase
98 {
99 public:
100 SamplerTest (tcu::TestContext& testContext,
101 const char* name,
102 const char* description,
103 PipelineConstructionType pipelineConstructionType,
104 SamplerViewType imageViewType,
105 VkFormat imageFormat,
106 int imageSize,
107 float samplerLod,
108 bool separateStencilUsage,
109 bool sampleStencil);
~SamplerTest(void)110 virtual ~SamplerTest (void) {}
111
112 virtual ImageSamplingInstanceParams getImageSamplingInstanceParams (SamplerViewType imageViewType,
113 VkFormat imageFormat,
114 int imageSize,
115 float samplerLod,
116 bool separateStencilUsage,
117 bool sampleStencil) const;
118
119 tcu::Vec4 swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const;
120 virtual void initPrograms (SourceCollections& sourceCollections) const;
121 virtual void checkSupport (Context& context) const;
122 virtual TestInstance* createInstance (Context& context) const;
123 virtual tcu::UVec2 getRenderSize (SamplerViewType viewType) const;
124 virtual std::vector<Vertex4Tex4> createVertices (void) const;
125 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
126 virtual VkComponentMapping getComponentMapping (void) const;
127
128 static std::string getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type, bool sampleStencil);
129 static tcu::IVec3 getImageSize (SamplerViewType viewType, int size);
130 static int getArraySize (SamplerViewType viewType);
131
132 protected:
133 PipelineConstructionType m_pipelineConstructionType;
134 SamplerViewType m_imageViewType;
135 VkFormat m_imageFormat;
136 int m_imageSize;
137 float m_samplerLod;
138 bool m_separateStencilUsage;
139 bool m_sampleStencil;
140 };
141
142 class SamplerMagFilterTest : public SamplerTest
143 {
144 public:
145 SamplerMagFilterTest (tcu::TestContext& testContext,
146 const char* name,
147 const char* description,
148 PipelineConstructionType pipelineConstructionType,
149 SamplerViewType imageViewType,
150 VkFormat imageFormat,
151 VkFilter magFilter,
152 bool separateStencilUsage);
~SamplerMagFilterTest(void)153 virtual ~SamplerMagFilterTest (void) {}
154 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
155
156 private:
157 VkFilter m_magFilter;
158 };
159
160 class SamplerMinFilterTest : public SamplerTest
161 {
162 public:
163 SamplerMinFilterTest (tcu::TestContext& testContext,
164 const char* name,
165 const char* description,
166 PipelineConstructionType pipelineConstructionType,
167 SamplerViewType imageViewType,
168 VkFormat imageFormat,
169 VkFilter minFilter,
170 bool separateStencilUsage);
~SamplerMinFilterTest(void)171 virtual ~SamplerMinFilterTest (void) {}
172 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
173
174 private:
175 VkFilter m_minFilter;
176 };
177
178 class SamplerMagReduceFilterTest : public SamplerMagFilterTest
179 {
180 public:
181 SamplerMagReduceFilterTest (tcu::TestContext& testContext,
182 const char* name,
183 const char* description,
184 PipelineConstructionType pipelineConstructionType,
185 SamplerViewType imageViewType,
186 VkFormat imageFormat,
187 VkComponentMapping componentMapping,
188 VkSamplerReductionMode reductionMode,
189 bool separateStencilUsage);
190
~SamplerMagReduceFilterTest(void)191 virtual ~SamplerMagReduceFilterTest (void) {}
192 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
193 virtual VkComponentMapping getComponentMapping (void) const;
194
195 private:
196 const VkSamplerReductionModeCreateInfo m_reductionCreaterInfo;
197 VkComponentMapping m_componentMapping;
198 };
199
200 class SamplerMinReduceFilterTest : public SamplerMinFilterTest
201 {
202 public:
203 SamplerMinReduceFilterTest (tcu::TestContext& testContext,
204 const char* name,
205 const char* description,
206 PipelineConstructionType pipelineConstructionType,
207 SamplerViewType imageViewType,
208 VkFormat imageFormat,
209 VkComponentMapping componentMapping,
210 VkSamplerReductionMode reductionMode,
211 bool separateStencilUsage);
212
~SamplerMinReduceFilterTest(void)213 virtual ~SamplerMinReduceFilterTest (void) {}
214 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
215 virtual VkComponentMapping getComponentMapping (void) const;
216
217 private:
218 const VkSamplerReductionModeCreateInfo m_reductionCreaterInfo;
219 VkComponentMapping m_componentMapping;
220 };
221
222 class SamplerLodTest : public SamplerTest
223 {
224 public:
225 SamplerLodTest (tcu::TestContext& testContext,
226 const char* name,
227 const char* description,
228 PipelineConstructionType pipelineConstructionType,
229 SamplerViewType imageViewType,
230 VkFormat imageFormat,
231 VkSamplerMipmapMode mipmapMode,
232 float minLod,
233 float maxLod,
234 float mipLodBias,
235 float samplerLod,
236 bool separateStencilUsage);
~SamplerLodTest(void)237 virtual ~SamplerLodTest (void) {}
238 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
239 virtual void checkSupport (Context& context) const;
240
241 private:
242 VkSamplerMipmapMode m_mipmapMode;
243 float m_minLod;
244 float m_maxLod;
245 float m_mipLodBias;
246 };
247
checkSupport(Context& context) const248 void SamplerLodTest::checkSupport (Context& context) const
249 {
250 SamplerTest::checkSupport(context);
251
252 #ifndef CTS_USES_VULKANSC
253 if (m_mipLodBias != 0.0f && context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
254 !context.getPortabilitySubsetFeatures().samplerMipLodBias)
255 {
256 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Sampler mipmap LOD bias is not supported by this implementation");
257 }
258 #endif // CTS_USES_VULKANSC
259 }
260
261 class SamplerAddressModesTest : public SamplerTest
262 {
263 public:
264 SamplerAddressModesTest (tcu::TestContext& testContext,
265 const char* name,
266 const char* description,
267 PipelineConstructionType pipelineConstructionType,
268 SamplerViewType imageViewType,
269 VkFormat imageFormat,
270 VkSamplerAddressMode addressU,
271 VkSamplerAddressMode addressV,
272 VkSamplerAddressMode addressW,
273 VkBorderColor borderColor,
274 rr::GenericVec4 customBorderColorValue,
275 bool customBorderColorFormatless,
276 bool separateStencilUsage,
277 bool sampleStencil);
~SamplerAddressModesTest(void)278 virtual ~SamplerAddressModesTest (void) {}
279 virtual tcu::UVec2 getRenderSize (SamplerViewType viewType) const;
280 virtual std::vector<Vertex4Tex4> createVertices (void) const;
281 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
282
283 VkSamplerCustomBorderColorCreateInfoEXT getSamplerCustomBorderColorCreateInfo (VkFormat format, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless) const;
284
285 private:
286 VkSamplerAddressMode m_addressU;
287 VkSamplerAddressMode m_addressV;
288 VkSamplerAddressMode m_addressW;
289 VkBorderColor m_borderColor;
290
291 const VkSamplerCustomBorderColorCreateInfoEXT m_customBorderColorCreateInfo;
292 };
293
294
295 // SamplerTest
296
SamplerTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, int imageSize, float samplerLod, bool separateStencilUsage, bool sampleStencil)297 SamplerTest::SamplerTest (tcu::TestContext& testContext,
298 const char* name,
299 const char* description,
300 PipelineConstructionType pipelineConstructionType,
301 SamplerViewType imageViewType,
302 VkFormat imageFormat,
303 int imageSize,
304 float samplerLod,
305 bool separateStencilUsage,
306 bool sampleStencil)
307 : vkt::TestCase (testContext, name, description)
308 , m_pipelineConstructionType (pipelineConstructionType)
309 , m_imageViewType (imageViewType)
310 , m_imageFormat (imageFormat)
311 , m_imageSize (imageSize)
312 , m_samplerLod (samplerLod)
313 , m_separateStencilUsage (separateStencilUsage)
314 , m_sampleStencil (sampleStencil)
315 {
316 // Can't do both at the same time with the current code.
317 DE_ASSERT(!separateStencilUsage || !sampleStencil);
318 }
319
getImageSamplingInstanceParams(SamplerViewType imageViewType, VkFormat imageFormat, int imageSize, float samplerLod, bool separateStencilUsage, bool sampleStencil) const320 ImageSamplingInstanceParams SamplerTest::getImageSamplingInstanceParams (SamplerViewType imageViewType,
321 VkFormat imageFormat,
322 int imageSize,
323 float samplerLod,
324 bool separateStencilUsage,
325 bool sampleStencil) const
326 {
327 const tcu::UVec2 renderSize = getRenderSize(imageViewType);
328 const std::vector<Vertex4Tex4> vertices = createVertices();
329 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
330 const VkComponentMapping componentMapping = getComponentMapping();
331
332 const auto isDSFormat = isDepthStencilFormat(imageFormat);
333 const auto tcuFormat = (isDSFormat ? mapVkFormat(imageFormat) : tcu::TextureFormat());
334 const auto hasDepth = (isDSFormat && tcu::hasDepthComponent(tcuFormat.order));
335 const auto hasStencil = (isDSFormat && tcu::hasStencilComponent(tcuFormat.order));
336 const auto imageAspect = (isDSFormat ? (sampleStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT) : VK_IMAGE_ASPECT_COLOR_BIT);
337 const deUint32 mipLevels = (imageViewType.isNormalized() ? static_cast<deUint32>(deLog2Floor32(imageSize)) + 1u : 1u);
338
339 DE_UNREF(hasDepth); // For debug builds.
340 DE_UNREF(hasStencil); // For debug builds.
341 DE_ASSERT(imageAspect != VK_IMAGE_ASPECT_DEPTH_BIT || hasDepth);
342 DE_ASSERT(imageAspect != VK_IMAGE_ASPECT_STENCIL_BIT || hasStencil);
343
344 const VkImageSubresourceRange subresourceRange =
345 {
346 imageAspect, // VkImageAspectFlags aspectMask;
347 0u, // deUint32 baseMipLevel;
348 mipLevels, // deUint32 mipLevels;
349 0u, // deUint32 baseArrayLayer;
350 (deUint32)SamplerTest::getArraySize(imageViewType) // deUint32 arraySize;
351 };
352
353 return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat,
354 getImageSize(imageViewType, imageSize),
355 getArraySize(imageViewType),
356 componentMapping, subresourceRange,
357 samplerParams, samplerLod, vertices, separateStencilUsage);
358 }
359
checkSupport(Context& context) const360 void SamplerTest::checkSupport (Context& context) const
361 {
362 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
363 checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_samplerLod, m_separateStencilUsage, m_sampleStencil));
364 }
365
swizzle(tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const366 tcu::Vec4 SamplerTest::swizzle (tcu::Vec4 inputData, VkComponentMapping componentMapping, float zeroOrOneValue) const
367 {
368 // Remove VK_COMPONENT_SWIZZLE_IDENTITY to avoid addressing channelValues[0]
369 const vk::VkComponentMapping nonIdentityMapping =
370 {
371 componentMapping.r == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_R : componentMapping.r,
372 componentMapping.g == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_G : componentMapping.g,
373 componentMapping.b == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_B : componentMapping.b,
374 componentMapping.a == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_A : componentMapping.a
375
376 };
377 // array map with enum VkComponentSwizzle
378 const float channelValues[] =
379 {
380 -1.0f, // impossible
381 zeroOrOneValue, // SWIZZLE_0
382 zeroOrOneValue, // SWIZZLE_1
383 inputData.x(),
384 inputData.y(),
385 inputData.z(),
386 inputData.w(),
387 -1.0f
388 };
389
390 return tcu::Vec4(channelValues[nonIdentityMapping.r],
391 channelValues[nonIdentityMapping.g],
392 channelValues[nonIdentityMapping.b],
393 channelValues[nonIdentityMapping.a]);
394 }
395
initPrograms(SourceCollections& sourceCollections) const396 void SamplerTest::initPrograms (SourceCollections& sourceCollections) const
397 {
398 std::ostringstream vertexSrc;
399 std::ostringstream fragmentSrc;
400 const char* texCoordSwizzle = DE_NULL;
401 tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat))
402 : mapVkFormat(m_imageFormat);
403 tcu::Vec4 lookupScale;
404 tcu::Vec4 lookupBias;
405
406 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias, m_sampleStencil);
407
408 tcu::Vec4 swizzledScale = swizzle(lookupScale, getComponentMapping(), 1.0f);
409 tcu::Vec4 swizzledBias = swizzle(lookupBias, getComponentMapping(), 0.0f);
410
411 switch (m_imageViewType)
412 {
413 case VK_IMAGE_VIEW_TYPE_1D:
414 texCoordSwizzle = "x";
415 break;
416 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
417 case VK_IMAGE_VIEW_TYPE_2D:
418 texCoordSwizzle = "xy";
419 break;
420 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
421 case VK_IMAGE_VIEW_TYPE_3D:
422 case VK_IMAGE_VIEW_TYPE_CUBE:
423 texCoordSwizzle = "xyz";
424 break;
425 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
426 texCoordSwizzle = "xyzw";
427 break;
428 default:
429 DE_ASSERT(false);
430 break;
431 }
432
433 vertexSrc << "#version 440\n"
434 << "layout(location = 0) in vec4 position;\n"
435 << "layout(location = 1) in vec4 texCoords;\n"
436 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
437 << "out gl_PerVertex {\n"
438 << " vec4 gl_Position;\n"
439 << "};\n"
440 << "void main (void)\n"
441 << "{\n"
442 << " gl_Position = position;\n"
443 << " vtxTexCoords = texCoords;\n"
444 << "}\n";
445
446 fragmentSrc << "#version 440\n"
447 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType, m_sampleStencil) << " texSampler;\n"
448 << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
449 << "layout(location = 0) out highp vec4 fragColor;\n"
450 << "void main (void)\n"
451 << "{\n"
452 << " fragColor = ";
453
454 if (m_samplerLod > 0.0f || !m_imageViewType.isNormalized())
455 {
456 DE_ASSERT(m_imageViewType.isNormalized() || (m_samplerLod == 0.0f && !m_imageViewType.isNormalized()));
457 fragmentSrc << "textureLod(texSampler, vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
458 }
459 else
460 {
461 fragmentSrc << "texture(texSampler, vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
462 }
463
464 fragmentSrc << " * vec4" << std::scientific << swizzledScale << " + vec4" << swizzledBias << ";\n"
465 << "}\n";
466
467 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
468 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
469 }
470
createInstance(Context& context) const471 TestInstance* SamplerTest::createInstance (Context& context) const
472 {
473 return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_samplerLod, m_separateStencilUsage, m_sampleStencil));
474 }
475
getRenderSize(SamplerViewType viewType) const476 tcu::UVec2 SamplerTest::getRenderSize (SamplerViewType viewType) const
477 {
478 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
479 {
480 return tcu::UVec2(16u, 16u);
481 }
482 else
483 {
484 return tcu::UVec2(16u * 3u, 16u * 2u);
485 }
486 }
487
createVertices(void) const488 std::vector<Vertex4Tex4> SamplerTest::createVertices (void) const
489 {
490 std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(m_imageViewType);
491 // Adjust texture coordinate to avoid doing NEAREST filtering exactly on texel boundaries.
492 // TODO: Would be nice to base this on number of texels and subtexel precision. But this
493 // seems to work.
494 for (unsigned int i = 0; i < vertices.size(); ++i) {
495 vertices[i].texCoord += tcu::Vec4(0.002f, 0.002f, 0.002f, 0.0f);
496 if (!m_imageViewType.isNormalized()) {
497 const float imageSize = static_cast<float>(m_imageSize);
498 for (int j = 0; j < tcu::Vec4::SIZE; ++j)
499 vertices[i].texCoord[j] *= imageSize;
500 }
501 }
502 return vertices;
503 }
504
getSamplerCreateInfo(void) const505 VkSamplerCreateInfo SamplerTest::getSamplerCreateInfo (void) const
506 {
507 const VkSamplerCreateInfo defaultSamplerParams =
508 {
509 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
510 DE_NULL, // const void* pNext;
511 0u, // VkSamplerCreateFlags flags;
512 VK_FILTER_NEAREST, // VkFilter magFilter;
513 VK_FILTER_NEAREST, // VkFilter minFilter;
514 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
515 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
516 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
517 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
518 0.0f, // float mipLodBias;
519 VK_FALSE, // VkBool32 anisotropyEnable;
520 1.0f, // float maxAnisotropy;
521 false, // VkBool32 compareEnable;
522 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
523 0.0f, // float minLod;
524 (m_imageViewType.isNormalized() ? 0.25f : 0.0f), // float maxLod;
525 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat, m_sampleStencil), // VkBorderColor borderColor;
526 !m_imageViewType.isNormalized(), // VkBool32 unnormalizedCoordinates;
527 };
528
529 return defaultSamplerParams;
530 }
531
getComponentMapping(void) const532 VkComponentMapping SamplerTest::getComponentMapping (void) const
533 {
534 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
535 return componentMapping;
536 }
537
getGlslSamplerType(const tcu::TextureFormat& format, SamplerViewType type, bool sampleStencil)538 std::string SamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type, bool sampleStencil)
539 {
540 std::ostringstream samplerType;
541
542 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER || sampleStencil)
543 samplerType << "u";
544 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
545 samplerType << "i";
546
547 switch (type)
548 {
549 case VK_IMAGE_VIEW_TYPE_1D:
550 samplerType << "sampler1D";
551 break;
552
553 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
554 samplerType << "sampler1DArray";
555 break;
556
557 case VK_IMAGE_VIEW_TYPE_2D:
558 samplerType << "sampler2D";
559 break;
560
561 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
562 samplerType << "sampler2DArray";
563 break;
564
565 case VK_IMAGE_VIEW_TYPE_3D:
566 samplerType << "sampler3D";
567 break;
568
569 case VK_IMAGE_VIEW_TYPE_CUBE:
570 samplerType << "samplerCube";
571 break;
572
573 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
574 samplerType << "samplerCubeArray";
575 break;
576
577 default:
578 DE_FATAL("Unknown image view type");
579 break;
580 }
581
582 return samplerType.str();
583 }
584
getImageSize(SamplerViewType viewType, int size)585 tcu::IVec3 SamplerTest::getImageSize (SamplerViewType viewType, int size)
586 {
587 switch (viewType)
588 {
589 case VK_IMAGE_VIEW_TYPE_1D:
590 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
591 return tcu::IVec3(size, 1, 1);
592
593 case VK_IMAGE_VIEW_TYPE_3D:
594 return tcu::IVec3(size, size, 4);
595
596 default:
597 break;
598 }
599
600 return tcu::IVec3(size, size, 1);
601 }
602
getArraySize(SamplerViewType viewType)603 int SamplerTest::getArraySize (SamplerViewType viewType)
604 {
605 switch (viewType)
606 {
607 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
608 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
609 case VK_IMAGE_VIEW_TYPE_CUBE:
610 return 6;
611
612 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
613 return 36;
614
615 default:
616 break;
617 }
618
619 return 1;
620 }
621
622
623 // SamplerMagFilterTest
624
SamplerMagFilterTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkFilter magFilter, bool separateStencilUsage)625 SamplerMagFilterTest::SamplerMagFilterTest (tcu::TestContext& testContext,
626 const char* name,
627 const char* description,
628 PipelineConstructionType pipelineConstructionType,
629 SamplerViewType imageViewType,
630 VkFormat imageFormat,
631 VkFilter magFilter,
632 bool separateStencilUsage)
633 : SamplerTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, 8, 0.0f, separateStencilUsage, false)
634 , m_magFilter (magFilter)
635 {
636 }
637
getSamplerCreateInfo(void) const638 VkSamplerCreateInfo SamplerMagFilterTest::getSamplerCreateInfo (void) const
639 {
640 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
641 samplerParams.magFilter = m_magFilter;
642
643 return samplerParams;
644 }
645
646
647 // SamplerMinFilterTest
648
SamplerMinFilterTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkFilter minFilter, bool separateStencilUsage)649 SamplerMinFilterTest::SamplerMinFilterTest (tcu::TestContext& testContext,
650 const char* name,
651 const char* description,
652 PipelineConstructionType pipelineConstructionType,
653 SamplerViewType imageViewType,
654 VkFormat imageFormat,
655 VkFilter minFilter,
656 bool separateStencilUsage)
657 : SamplerTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, 32, 0.0f, separateStencilUsage, false)
658 , m_minFilter (minFilter)
659 {
660 }
661
getSamplerCreateInfo(void) const662 VkSamplerCreateInfo SamplerMinFilterTest::getSamplerCreateInfo (void) const
663 {
664 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
665 samplerParams.minFilter = m_minFilter;
666 // set minLod to epsilon, to force use of the minFilter
667 samplerParams.minLod = 0.01f;
668
669 return samplerParams;
670 }
671
672
673 namespace
674 {
675
getSamplerReductionCreateInfo(VkSamplerReductionMode reductionMode)676 VkSamplerReductionModeCreateInfo getSamplerReductionCreateInfo (VkSamplerReductionMode reductionMode)
677 {
678 const VkSamplerReductionModeCreateInfo ret =
679 {
680 VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, // VkStructureType sType
681 DE_NULL, // const void* pNext
682 reductionMode // VkSamplerReductionMode reductionMode
683 };
684 return ret;
685 }
686
687 }
688
689
690 // SamplerMagReduceFilterTest
691
SamplerMagReduceFilterTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkComponentMapping componentMapping, VkSamplerReductionMode reductionMode, bool separateStencilUsage)692 SamplerMagReduceFilterTest::SamplerMagReduceFilterTest (tcu::TestContext& testContext,
693 const char* name,
694 const char* description,
695 PipelineConstructionType pipelineConstructionType,
696 SamplerViewType imageViewType,
697 VkFormat imageFormat,
698 VkComponentMapping componentMapping,
699 VkSamplerReductionMode reductionMode,
700 bool separateStencilUsage)
701 : SamplerMagFilterTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
702 , m_reductionCreaterInfo (getSamplerReductionCreateInfo(reductionMode))
703 , m_componentMapping (componentMapping)
704 {
705 }
706
getSamplerCreateInfo(void) const707 VkSamplerCreateInfo SamplerMagReduceFilterTest::getSamplerCreateInfo (void) const
708 {
709 VkSamplerCreateInfo samplerParams = SamplerMagFilterTest::getSamplerCreateInfo();
710
711 samplerParams.pNext = &m_reductionCreaterInfo;
712
713 return samplerParams;
714 }
715
getComponentMapping(void) const716 VkComponentMapping SamplerMagReduceFilterTest::getComponentMapping (void) const
717 {
718 return m_componentMapping;
719 }
720
721 // SamplerMinReduceFilterTest
722
SamplerMinReduceFilterTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkComponentMapping componentMapping, VkSamplerReductionMode reductionMode, bool separateStencilUsage)723 SamplerMinReduceFilterTest::SamplerMinReduceFilterTest (tcu::TestContext& testContext,
724 const char* name,
725 const char* description,
726 PipelineConstructionType pipelineConstructionType,
727 SamplerViewType imageViewType,
728 VkFormat imageFormat,
729 VkComponentMapping componentMapping,
730 VkSamplerReductionMode reductionMode,
731 bool separateStencilUsage)
732 : SamplerMinFilterTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage)
733 , m_reductionCreaterInfo (getSamplerReductionCreateInfo(reductionMode))
734 , m_componentMapping (componentMapping)
735 {
736 }
737
getSamplerCreateInfo(void) const738 VkSamplerCreateInfo SamplerMinReduceFilterTest::getSamplerCreateInfo (void) const
739 {
740 VkSamplerCreateInfo samplerParams = SamplerMinFilterTest::getSamplerCreateInfo();
741
742 samplerParams.pNext = &m_reductionCreaterInfo;
743
744 return samplerParams;
745 }
746
getComponentMapping(void) const747 VkComponentMapping SamplerMinReduceFilterTest::getComponentMapping (void) const
748 {
749 return m_componentMapping;
750 }
751
752 // SamplerLodTest
753
SamplerLodTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode, float minLod, float maxLod, float mipLodBias, float samplerLod, bool separateStencilUsage)754 SamplerLodTest::SamplerLodTest (tcu::TestContext& testContext,
755 const char* name,
756 const char* description,
757 PipelineConstructionType pipelineConstructionType,
758 SamplerViewType imageViewType,
759 VkFormat imageFormat,
760 VkSamplerMipmapMode mipmapMode,
761 float minLod,
762 float maxLod,
763 float mipLodBias,
764 float samplerLod,
765 bool separateStencilUsage)
766 : SamplerTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, 32, samplerLod, separateStencilUsage, false)
767 , m_mipmapMode (mipmapMode)
768 , m_minLod (minLod)
769 , m_maxLod (maxLod)
770 , m_mipLodBias (mipLodBias)
771 {
772 }
773
getSamplerCreateInfo(void) const774 VkSamplerCreateInfo SamplerLodTest::getSamplerCreateInfo (void) const
775 {
776 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
777
778 samplerParams.mipmapMode = m_mipmapMode;
779 samplerParams.minLod = m_minLod;
780 samplerParams.maxLod = m_maxLod;
781 samplerParams.mipLodBias = m_mipLodBias;
782
783 return samplerParams;
784 }
785
786
787 // SamplerAddressModesTest
788
SamplerAddressModesTest(tcu::TestContext& testContext, const char* name, const char* description, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkSamplerAddressMode addressU, VkSamplerAddressMode addressV, VkSamplerAddressMode addressW, VkBorderColor borderColor, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless, bool separateStencilUsage, bool sampleStencil)789 SamplerAddressModesTest::SamplerAddressModesTest (tcu::TestContext& testContext,
790 const char* name,
791 const char* description,
792 PipelineConstructionType pipelineConstructionType,
793 SamplerViewType imageViewType,
794 VkFormat imageFormat,
795 VkSamplerAddressMode addressU,
796 VkSamplerAddressMode addressV,
797 VkSamplerAddressMode addressW,
798 VkBorderColor borderColor,
799 rr::GenericVec4 customBorderColorValue,
800 bool customBorderColorFormatless,
801 bool separateStencilUsage,
802 bool sampleStencil)
803 : SamplerTest (testContext, name, description, pipelineConstructionType, imageViewType, imageFormat, 8, 0.0f, separateStencilUsage, sampleStencil)
804 , m_addressU (addressU)
805 , m_addressV (addressV)
806 , m_addressW (addressW)
807 , m_borderColor (borderColor)
808 , m_customBorderColorCreateInfo (getSamplerCustomBorderColorCreateInfo(imageFormat, customBorderColorValue, customBorderColorFormatless))
809 {
810 }
811
getRenderSize(SamplerViewType viewType) const812 tcu::UVec2 SamplerAddressModesTest::getRenderSize (SamplerViewType viewType) const
813 {
814 return 4u * SamplerTest::getRenderSize(viewType);
815 }
816
createVertices(void) const817 std::vector<Vertex4Tex4> SamplerAddressModesTest::createVertices (void) const
818 {
819 std::vector<Vertex4Tex4> vertices = SamplerTest::createVertices();
820
821 switch (m_imageViewType)
822 {
823 case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
824 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
825 vertices[vertexNdx].texCoord.x() = (vertices[vertexNdx].texCoord.x() - 0.5f) * 4.0f;
826
827 break;
828
829 case VK_IMAGE_VIEW_TYPE_2D:
830 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
831 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
832 vertices[vertexNdx].texCoord.xy() = (vertices[vertexNdx].texCoord.swizzle(0, 1) - tcu::Vec2(0.5f)) * 4.0f;
833
834 break;
835
836 case VK_IMAGE_VIEW_TYPE_3D:
837 for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
838 vertices[vertexNdx].texCoord.xyz() = (vertices[vertexNdx].texCoord.swizzle(0, 1, 2) - tcu::Vec3(0.5f)) * 4.0f;
839
840 break;
841
842 case VK_IMAGE_VIEW_TYPE_CUBE:
843 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
844 break;
845
846 default:
847 DE_ASSERT(false);
848 }
849
850 return vertices;
851 }
852
getSamplerCreateInfo(void) const853 VkSamplerCreateInfo SamplerAddressModesTest::getSamplerCreateInfo (void) const
854 {
855 VkSamplerCreateInfo samplerParams = SamplerTest::getSamplerCreateInfo();
856 samplerParams.addressModeU = m_addressU;
857 samplerParams.addressModeV = m_addressV;
858 samplerParams.addressModeW = m_addressW;
859 samplerParams.borderColor = m_borderColor;
860
861 if (m_borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
862 m_borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT)
863 {
864 samplerParams.pNext = &m_customBorderColorCreateInfo;
865 }
866
867 return samplerParams;
868 }
869
getSamplerCustomBorderColorCreateInfo(VkFormat format, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless) const870 VkSamplerCustomBorderColorCreateInfoEXT SamplerAddressModesTest::getSamplerCustomBorderColorCreateInfo (VkFormat format, rr::GenericVec4 customBorderColorValue, bool customBorderColorFormatless) const
871 {
872 const VkSamplerCustomBorderColorCreateInfoEXT defaultSamplerCustomBorderColorParams =
873 {
874 VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
875 DE_NULL,
876 mapVkColor(customBorderColorValue),
877 customBorderColorFormatless ? VK_FORMAT_UNDEFINED : format
878 };
879
880 return defaultSamplerCustomBorderColorParams;
881 }
882
883
884 // Utilities to create test nodes
885
getFormatCaseName(const VkFormat format)886 std::string getFormatCaseName (const VkFormat format)
887 {
888 const std::string fullName = getFormatName(format);
889
890 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
891
892 return de::toLower(fullName.substr(10));
893 }
894
createSamplerMagFilterTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)895 MovePtr<tcu::TestCaseGroup> createSamplerMagFilterTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
896 {
897 MovePtr<tcu::TestCaseGroup> samplerMagFilterTests (new tcu::TestCaseGroup(testCtx, "mag_filter", "Tests for magnification filter"));
898
899 if (imageViewType.isNormalized() && (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat))))
900 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "linear", "Magnifies image using VK_FILTER_LINEAR", pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage));
901 samplerMagFilterTests->addChild(new SamplerMagFilterTest(testCtx, "nearest", "Magnifies image using VK_FILTER_NEAREST", pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_NEAREST, separateStencilUsage));
902
903 return samplerMagFilterTests;
904 }
905
createSamplerMinFilterTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)906 MovePtr<tcu::TestCaseGroup> createSamplerMinFilterTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
907 {
908 MovePtr<tcu::TestCaseGroup> samplerMinFilterTests (new tcu::TestCaseGroup(testCtx, "min_filter", "Tests for minification filter"));
909
910 if (imageViewType.isNormalized() && (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat))))
911 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "linear", "Minifies image using VK_FILTER_LINEAR", pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_LINEAR, separateStencilUsage));
912 samplerMinFilterTests->addChild(new SamplerMinFilterTest(testCtx, "nearest", "Minifies image using VK_FILTER_NEAREST", pipelineConstructionType, imageViewType, imageFormat, VK_FILTER_NEAREST, separateStencilUsage));
913
914 return samplerMinFilterTests;
915 }
916
917 const VkComponentMapping reduceFilterComponentMappings[] =
918 {
919 // filterMinmaxImageComponentMapping == false - compatible mappings:
920 { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO },
921 { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO },
922
923 // other mappings
924 { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
925 { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A },
926 { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R },
927 };
928
getShortComponentSwizzleName(VkComponentSwizzle componentSwizzle)929 static std::string getShortComponentSwizzleName (VkComponentSwizzle componentSwizzle)
930 {
931 const std::string fullName = getComponentSwizzleName(componentSwizzle);
932 const char* prefix = "VK_COMPONENT_SWIZZLE_";
933
934 DE_ASSERT(de::beginsWith(fullName, prefix));
935
936 return de::toLower(fullName.substr(deStrnlen(prefix, -1)));
937 }
938
getComponentMappingGroupName(const VkComponentMapping& componentMapping)939 static std::string getComponentMappingGroupName (const VkComponentMapping& componentMapping)
940 {
941 std::ostringstream name;
942
943 name << "comp_";
944
945 name << getShortComponentSwizzleName(componentMapping.r) << "_"
946 << getShortComponentSwizzleName(componentMapping.g) << "_"
947 << getShortComponentSwizzleName(componentMapping.b) << "_"
948 << getShortComponentSwizzleName(componentMapping.a);
949
950 return name.str();
951 }
952
createSamplerMagReduceFilterTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)953 MovePtr<tcu::TestCaseGroup> createSamplerMagReduceFilterTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
954 {
955 MovePtr<tcu::TestCaseGroup> samplerMagReduceFilterTests (new tcu::TestCaseGroup(testCtx, "mag_reduce", "Tests for magnification reduce filter"));
956
957 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
958 {
959 const VkComponentMapping& mapping = reduceFilterComponentMappings[i];
960
961 MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
962
963 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
964 {
965 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "average", "Magnifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, separateStencilUsage));
966 }
967 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "min", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN, separateStencilUsage));
968 componentGroup->addChild(new SamplerMagReduceFilterTest(testCtx, "max", "Magnifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX, separateStencilUsage));
969 samplerMagReduceFilterTests->addChild(componentGroup.release());
970 }
971 return samplerMagReduceFilterTests;
972 }
973
createSamplerMinReduceFilterTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)974 MovePtr<tcu::TestCaseGroup> createSamplerMinReduceFilterTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
975 {
976 MovePtr<tcu::TestCaseGroup> samplerMinReduceFilterTests (new tcu::TestCaseGroup(testCtx, "min_reduce", "Tests for minification reduce filter"));
977
978 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(reduceFilterComponentMappings); ++i)
979 {
980 const VkComponentMapping& mapping = reduceFilterComponentMappings[i];
981
982 MovePtr<tcu::TestCaseGroup> componentGroup (new tcu::TestCaseGroup(testCtx, getComponentMappingGroupName(mapping).c_str(), "Group for given view component mapping"));
983
984 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
985 {
986 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "average", "Minifies image using VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, separateStencilUsage));
987 }
988 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "min", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MIN", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MIN, separateStencilUsage));
989 componentGroup->addChild(new SamplerMinReduceFilterTest(testCtx, "max", "Minifies and reduces image using VK_SAMPLER_REDUCTION_MODE_MAX", pipelineConstructionType, imageViewType, imageFormat, mapping, VK_SAMPLER_REDUCTION_MODE_MAX, separateStencilUsage));
990 samplerMinReduceFilterTests->addChild(componentGroup.release());
991 }
992 return samplerMinReduceFilterTests;
993 }
994
createSamplerLodTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode, bool separateStencilUsage)995 MovePtr<tcu::TestCaseGroup> createSamplerLodTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, VkSamplerMipmapMode mipmapMode, bool separateStencilUsage)
996 {
997 struct TestCaseConfig
998 {
999 const char* name;
1000 const char* description;
1001 float minLod;
1002 float maxLod;
1003 float mipLodBias;
1004 float lod;
1005 };
1006
1007 TestCaseConfig testCaseConfigs [] =
1008 {
1009 { "equal_min_3_max_3", "minLod = 3, maxLod = 3, mipLodBias = 0, lod = 0", 3.0f, 3.0f, 0.0f, 0.0f },
1010 { "select_min_1", "minLod = 1, maxLod = 5, mipLodBias = 0, lod = 0", 1.0f, 5.0f, 0.0f, 0.0f },
1011 { "select_max_4", "minLod = 0, maxLod = 4, mipLodBias = 0, lod = 5", 0.0f, 4.0f, 0.0f, 5.0f },
1012 { "select_bias_2_1", "minLod = 0, maxLod = 2.1, mipLodBias = 5.0, lod = 0", 0.0f, 2.1f, 5.0f, 0.0f },
1013 { "select_bias_2_5", "minLod = 0, maxLod = 5, mipLodBias = 2.5, lod = 0", 0.0f, 5.0f, 2.5f, 0.00001f },
1014 { "select_bias_3_1", "minLod = 0, maxLod = 5, mipLodBias = -0.9, lod = 4.0", 0.0f, 5.0f, -0.9f, 4.0f },
1015 { "select_bias_3_7", "minLod = 0, maxLod = 5, mipLodBias = 3.0, lod = 0.7", 0.0f, 5.0f, 3.0f, 0.7f },
1016 };
1017
1018 MovePtr<tcu::TestCaseGroup> samplerLodTests (new tcu::TestCaseGroup(testCtx, "lod", "Tests for sampler LOD"));
1019
1020 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
1021 {
1022 const TestCaseConfig& config = testCaseConfigs[configNdx];
1023
1024 samplerLodTests->addChild(new SamplerLodTest(testCtx, config.name, config.description, pipelineConstructionType, imageViewType, imageFormat, mipmapMode, config.minLod, config.maxLod, config.mipLodBias, config.lod, separateStencilUsage));
1025 }
1026
1027 return samplerLodTests;
1028 }
1029
createSamplerMipmapTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)1030 MovePtr<tcu::TestCaseGroup> createSamplerMipmapTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
1031 {
1032 MovePtr<tcu::TestCaseGroup> samplerMipmapTests (new tcu::TestCaseGroup(testCtx, "mipmap", "Tests for mipmap modes"));
1033
1034 // Mipmap mode: nearest
1035 MovePtr<tcu::TestCaseGroup> mipmapNearestTests (new tcu::TestCaseGroup(testCtx, "nearest", "Uses VK_TEX_MIPMAP_MODE_NEAREST"));
1036 mipmapNearestTests->addChild(createSamplerLodTests(testCtx, pipelineConstructionType, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_NEAREST, separateStencilUsage).release());
1037 samplerMipmapTests->addChild(mipmapNearestTests.release());
1038
1039 // Mipmap mode: linear
1040 if (isCompressedFormat(imageFormat) || (!isIntFormat(imageFormat) && !isUintFormat(imageFormat)))
1041 {
1042 MovePtr<tcu::TestCaseGroup> mipmapLinearTests(new tcu::TestCaseGroup(testCtx, "linear", "Uses VK_TEX_MIPMAP_MODE_LINEAR"));
1043 mipmapLinearTests->addChild(createSamplerLodTests(testCtx, pipelineConstructionType, imageViewType, imageFormat, VK_SAMPLER_MIPMAP_MODE_LINEAR, separateStencilUsage).release());
1044 samplerMipmapTests->addChild(mipmapLinearTests.release());
1045 }
1046
1047 return samplerMipmapTests;
1048 }
1049
getAddressModesCaseName(VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border, tcu::IVec4 customIntValue, bool formatless, bool sampleStencil)1050 std::string getAddressModesCaseName (VkSamplerAddressMode u, VkSamplerAddressMode v, VkSamplerAddressMode w, BorderColor border, tcu::IVec4 customIntValue, bool formatless, bool sampleStencil)
1051 {
1052 static const char* borderColorNames[BORDER_COLOR_COUNT] =
1053 {
1054 "opaque_black",
1055 "opaque_white",
1056 "transparent_black",
1057 "custom"
1058 };
1059
1060 std::ostringstream caseName;
1061
1062 if (u == v && v == w)
1063 {
1064 const std::string fullName = getSamplerAddressModeName(u);
1065 DE_ASSERT(de::beginsWith(fullName, "VK_SAMPLER_ADDRESS_"));
1066
1067 caseName << "all_";
1068 caseName << de::toLower(fullName.substr(19));
1069
1070 if (u == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
1071 {
1072 caseName << "_" << borderColorNames[border];
1073 }
1074 }
1075 else
1076 {
1077 const std::string fullNameU = getSamplerAddressModeName(u);
1078 const std::string fullNameV = getSamplerAddressModeName(v);
1079 const std::string fullNameW = getSamplerAddressModeName(w);
1080
1081 DE_ASSERT(de::beginsWith(fullNameU, "VK_SAMPLER_ADDRESS_"));
1082 DE_ASSERT(de::beginsWith(fullNameV, "VK_SAMPLER_ADDRESS_"));
1083 DE_ASSERT(de::beginsWith(fullNameW, "VK_SAMPLER_ADDRESS_"));
1084
1085 caseName << "uvw"
1086 << "_" << de::toLower(fullNameU.substr(19))
1087 << "_" << de::toLower(fullNameV.substr(19))
1088 << "_" << de::toLower(fullNameW.substr(19));
1089 }
1090
1091 if (border == BORDER_COLOR_CUSTOM)
1092 {
1093 caseName << "_";
1094 for (int i = 0; i < 4; i++)
1095 caseName << customIntValue[i];
1096
1097 if (formatless)
1098 caseName << "_formatless";
1099
1100 }
1101
1102 if (sampleStencil)
1103 caseName << "_stencil";
1104
1105 return caseName.str();
1106 }
1107
createSamplerAddressModesTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)1108 MovePtr<tcu::TestCaseGroup> createSamplerAddressModesTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, SamplerViewType imageViewType, VkFormat imageFormat, bool separateStencilUsage)
1109 {
1110 struct TestCaseConfig
1111 {
1112 TestCaseConfig (VkSamplerAddressMode _u,
1113 VkSamplerAddressMode _v,
1114 VkSamplerAddressMode _w,
1115 BorderColor _border,
1116 bool _customColorFormatless = false,
1117 tcu::Vec4 _customColorValueFloat = tcu::Vec4(),
1118 tcu::IVec4 _customColorValueInt = tcu::IVec4())
1119 : u(_u), v(_v), w(_w), border(_border), customColorFormatless(_customColorFormatless)
1120 , customColorValueFloat(_customColorValueFloat), customColorValueInt(_customColorValueInt)
1121 {
1122
1123 }
1124
1125 VkSamplerAddressMode u;
1126 VkSamplerAddressMode v;
1127 VkSamplerAddressMode w;
1128 BorderColor border;
1129 bool customColorFormatless;
1130 tcu::Vec4 customColorValueFloat;
1131 tcu::IVec4 customColorValueInt;
1132 };
1133
1134 const TestCaseConfig testCaseConfigs[] =
1135 {
1136 // All address modes equal
1137 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_TRANSPARENT_BLACK },
1138 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
1139 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_TRANSPARENT_BLACK },
1140 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_TRANSPARENT_BLACK },
1141
1142 // All address modes equal using border color
1143 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_TRANSPARENT_BLACK },
1144 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_BLACK },
1145 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
1146
1147 // Pairwise combinations of address modes not covered by previous tests
1148 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE},
1149 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1150 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1151 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1152 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1153 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
1154 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1155 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1156 { VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1157 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1158 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1159 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
1160 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1161 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1162 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
1163 { VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1164 { VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1165 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_OPAQUE_WHITE },
1166 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1167 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1168 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, BORDER_COLOR_OPAQUE_WHITE },
1169 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, BORDER_COLOR_OPAQUE_WHITE },
1170
1171 // Custom border color tests
1172 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1173 false, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::IVec4(0, 0, 0, 0) },
1174 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1175 false, tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::IVec4(0, 0, 1, 1) },
1176 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1177 false, tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::IVec4(1, 0, 0, 0) },
1178 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1179 false, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::IVec4(1, 0, 0, 1) },
1180 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1181 false, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::IVec4(1, 0, 1, 1) },
1182 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1183 false, tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::IVec4(1, 1, 0, 1) },
1184
1185 // Custom border color formatless
1186 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1187 true, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::IVec4(1, 0, 1, 1) },
1188 { VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, BORDER_COLOR_CUSTOM,
1189 true, tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), tcu::IVec4(1, 1, 0, 1) },
1190 };
1191
1192 MovePtr<tcu::TestCaseGroup> samplerAddressModesTests (new tcu::TestCaseGroup(testCtx, "address_modes", "Tests for address modes"));
1193
1194 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testCaseConfigs); configNdx++)
1195 {
1196 const TestCaseConfig& config = testCaseConfigs[configNdx];
1197
1198 if (!imageViewType.isNormalized() &&
1199 ((config.u != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && config.u != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
1200 (config.v != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE && config.v != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)))
1201 continue;
1202
1203 // VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_B5G6R5_UNORM_PACK16 and VK_FORMAT_B5G5R5A1_UNORM_PACK16 are forbidden
1204 // for non-formatless custom border color.
1205 if ((imageFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16 ||
1206 imageFormat == VK_FORMAT_B5G6R5_UNORM_PACK16 ||
1207 imageFormat == VK_FORMAT_B5G5R5A1_UNORM_PACK16) && config.border == BORDER_COLOR_CUSTOM && config.customColorFormatless)
1208 continue;
1209
1210 for (int i = 0; i < 2; ++i)
1211 {
1212 const bool isDSFormat = isDepthStencilFormat(imageFormat);
1213 const bool sampleStencil = (i > 0);
1214
1215 if (separateStencilUsage && sampleStencil)
1216 continue;
1217
1218 if (!isDSFormat && sampleStencil)
1219 continue;
1220
1221 if (isDSFormat)
1222 {
1223 const auto tcuFormat = mapVkFormat(imageFormat);
1224
1225 if (!sampleStencil && !tcu::hasDepthComponent(tcuFormat.order))
1226 continue;
1227 if (sampleStencil && !tcu::hasStencilComponent(tcuFormat.order))
1228 continue;
1229 }
1230
1231 samplerAddressModesTests->addChild(new SamplerAddressModesTest(testCtx,
1232 getAddressModesCaseName(config.u, config.v, config.w, config.border, config.customColorValueInt, config.customColorFormatless, sampleStencil).c_str(),
1233 "",
1234 pipelineConstructionType,
1235 imageViewType,
1236 imageFormat,
1237 config.u, config.v, config.w,
1238 getFormatBorderColor(config.border, imageFormat, sampleStencil),
1239 getFormatCustomBorderColor(config.customColorValueFloat, config.customColorValueInt, imageFormat, sampleStencil),
1240 config.customColorFormatless,
1241 separateStencilUsage,
1242 sampleStencil));
1243 }
1244 }
1245
1246 return samplerAddressModesTests;
1247 }
1248
1249 // Exact sampling case:
1250 // 1) Create a texture and a framebuffer image of the same size.
1251 // 2) Draw a full screen quad with the texture and VK_FILTER_NEAREST.
1252 // 3) Verify the rendered image matches the texture exactly.
1253 class ExactSamplingCase : public vkt::TestCase
1254 {
1255 public:
1256 struct Params
1257 {
1258 PipelineConstructionType pipelineConstructionType;
1259 vk::VkFormat format;
1260 bool unnormalizedCoordinates;
1261 bool solidColor;
1262 tcu::Maybe<float> offsetSign; // -1.0 or 1.0
1263 };
1264
1265 struct PushConstants
1266 {
1267 float texWidth;
1268 float texHeight;
1269 };
1270
1271 struct VertexData
1272 {
1273 tcu::Vec2 vtxCoords;
1274 tcu::Vec2 texCoords;
1275
1276 static vk::VkVertexInputBindingDescription getBindingDescription (void);
1277 static std::vector<vk::VkVertexInputAttributeDescription> getAttributeDescriptions (void);
1278 };
1279
1280 ExactSamplingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params);
~ExactSamplingCase(void)1281 virtual ~ExactSamplingCase (void) {}
1282
1283 virtual void initPrograms (vk::SourceCollections& programCollection) const;
1284 virtual TestInstance* createInstance (Context& context) const;
1285 virtual void checkSupport (Context& context) const;
1286
1287 private:
1288 Params m_params;
1289 };
1290
1291 class ExactSamplingInstance : public vkt::TestInstance
1292 {
1293 public:
1294 using Params = ExactSamplingCase::Params;
1295
1296 ExactSamplingInstance (Context& context, const Params& params);
~ExactSamplingInstance(void)1297 virtual ~ExactSamplingInstance (void) {}
1298
1299 virtual tcu::TestStatus iterate (void);
1300
1301 vk::VkExtent3D getTextureExtent (void) const;
1302
1303 private:
1304 Params m_params;
1305 };
1306
getBindingDescription(void)1307 vk::VkVertexInputBindingDescription ExactSamplingCase::VertexData::getBindingDescription (void)
1308 {
1309 static const vk::VkVertexInputBindingDescription desc =
1310 {
1311 0u, // deUint32 binding;
1312 static_cast<deUint32>(sizeof(ExactSamplingCase::VertexData)), // deUint32 stride;
1313 vk::VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
1314 };
1315
1316 return desc;
1317 }
1318
getAttributeDescriptions(void)1319 std::vector<vk::VkVertexInputAttributeDescription> ExactSamplingCase::VertexData::getAttributeDescriptions (void)
1320 {
1321 static const std::vector<vk::VkVertexInputAttributeDescription> desc =
1322 {
1323 {
1324 0u, // deUint32 location;
1325 0u, // deUint32 binding;
1326 vk::VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1327 static_cast<deUint32>(offsetof(ExactSamplingCase::VertexData, vtxCoords)), // deUint32 offset;
1328 },
1329 {
1330 1u, // deUint32 location;
1331 0u, // deUint32 binding;
1332 vk::VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1333 static_cast<deUint32>(offsetof(ExactSamplingCase::VertexData, texCoords)), // deUint32 offset;
1334 },
1335 };
1336
1337 return desc;
1338 }
1339
1340
ExactSamplingCase(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)1341 ExactSamplingCase::ExactSamplingCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)
1342 : vkt::TestCase{testCtx, name, description}, m_params(params)
1343 {
1344 }
1345
initPrograms(vk::SourceCollections& programCollection) const1346 void ExactSamplingCase::initPrograms (vk::SourceCollections& programCollection) const
1347 {
1348 std::ostringstream vertexShader;
1349
1350 std::string texCoordX = "inTexCoord.x";
1351 std::string texCoordY = "inTexCoord.y";
1352
1353 if (m_params.unnormalizedCoordinates)
1354 {
1355 texCoordX += " * pushc.texWidth";
1356 texCoordY += " * pushc.texHeight";
1357 }
1358
1359 vertexShader
1360 << "#version 450\n"
1361 << "\n"
1362 << "layout(push_constant, std430) uniform PushConstants\n"
1363 << "{\n"
1364 << " float texWidth;\n"
1365 << " float texHeight;\n"
1366 << "} pushc;\n"
1367 << "\n"
1368 << "layout(location = 0) in vec2 inPosition;\n"
1369 << "layout(location = 1) in vec2 inTexCoord;\n"
1370 << "\n"
1371 << "layout(location = 0) out vec2 fragTexCoord;\n"
1372 << "\n"
1373 << "void main() {\n"
1374 << " gl_Position = vec4(inPosition, 0.0, 1.0);\n"
1375 << " fragTexCoord = vec2(" << texCoordX << ", " << texCoordY << ");\n"
1376 << "}\n"
1377 ;
1378
1379 programCollection.glslSources.add("vert") << glu::VertexSource{vertexShader.str()};
1380
1381 std::ostringstream fragmentShader;
1382
1383 std::string typePrefix;
1384 if (vk::isIntFormat(m_params.format))
1385 typePrefix = "i";
1386 else if (vk::isUintFormat(m_params.format))
1387 typePrefix = "u";
1388
1389 const std::string samplerType = typePrefix + "sampler2D";
1390 const std::string colorType = typePrefix + "vec4";
1391
1392 fragmentShader
1393 << "#version 450\n"
1394 << "\n"
1395 << "layout(set = 0, binding = 0) uniform " << samplerType << " texSampler;\n"
1396 << "\n"
1397 << "layout(location = 0) in vec2 fragTexCoord;\n"
1398 << "\n"
1399 << "layout(location = 0) out " << colorType << " outColor;\n"
1400 << "\n"
1401 << "void main() {\n";
1402
1403 if (m_params.unnormalizedCoordinates)
1404 {
1405 fragmentShader << " outColor = textureLod(texSampler, fragTexCoord, 0.0f);";
1406 }
1407 else
1408 {
1409 fragmentShader << " outColor = texture(texSampler, fragTexCoord);\n";
1410 }
1411
1412 fragmentShader << "}\n";
1413
1414 programCollection.glslSources.add("frag") << glu::FragmentSource{fragmentShader.str()};
1415 }
1416
createInstance(Context& context) const1417 TestInstance* ExactSamplingCase::createInstance (Context& context) const
1418 {
1419 return new ExactSamplingInstance{context, m_params};
1420 }
1421
checkSupport(Context& context) const1422 void ExactSamplingCase::checkSupport (Context& context) const
1423 {
1424 const auto& vki = context.getInstanceInterface();
1425 const auto physicalDevice = context.getPhysicalDevice();
1426 const auto props = vk::getPhysicalDeviceFormatProperties(vki, physicalDevice, m_params.format);
1427 const vk::VkFormatFeatureFlags requiredFeatures =
1428 (vk::VK_FORMAT_FEATURE_TRANSFER_DST_BIT
1429 |vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
1430 |vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
1431 |vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
1432 |(m_params.solidColor ? vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT : 0)
1433 );
1434
1435 checkPipelineLibraryRequirements(vki, physicalDevice, m_params.pipelineConstructionType);
1436
1437 if ((props.optimalTilingFeatures & requiredFeatures) != requiredFeatures)
1438 TCU_THROW(NotSupportedError, "Selected format does not support the required features");
1439 }
1440
ExactSamplingInstance(Context& context, const Params& params)1441 ExactSamplingInstance::ExactSamplingInstance (Context& context, const Params& params)
1442 : vkt::TestInstance{context}, m_params(params)
1443 {
1444 }
1445
getTextureExtent(void) const1446 vk::VkExtent3D ExactSamplingInstance::getTextureExtent (void) const
1447 {
1448 return vk::makeExtent3D(256u, 256u, 1u);
1449 }
1450
iterate(void)1451 tcu::TestStatus ExactSamplingInstance::iterate (void)
1452 {
1453 const auto& vkd = m_context.getDeviceInterface();
1454 const auto device = m_context.getDevice();
1455 auto& allocator = m_context.getDefaultAllocator();
1456 const auto queue = m_context.getUniversalQueue();
1457 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
1458
1459 const auto tcuFormat = vk::mapVkFormat(m_params.format);
1460 const auto formatInfo = tcu::getTextureFormatInfo(tcuFormat);
1461 const auto texExtent = getTextureExtent();
1462 const auto texUsage = (vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT);
1463 const auto fbUsage = (vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
1464 const auto descType = vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1465 const auto texLayout = vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1466 const bool& unnorm = m_params.unnormalizedCoordinates;
1467
1468 // Some code below depends on this.
1469 DE_ASSERT(texExtent.depth == 1u);
1470
1471 const vk::VkImageCreateInfo texImgCreateInfo =
1472 {
1473 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1474 nullptr, // const void* pNext;
1475 0u, // VkImageCreateFlags flags;
1476 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
1477 m_params.format, // VkFormat format;
1478 texExtent, // VkExtent3D extent;
1479 1u, // deUint32 mipLevels;
1480 1u, // deUint32 arrayLayers;
1481 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1482 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1483 texUsage, // VkImageUsageFlags usage;
1484 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1485 1u, // deUint32 queueFamilyIndexCount;
1486 &queueIndex, // const deUint32* pQueueFamilyIndices;
1487 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1488 };
1489
1490 const vk::VkImageCreateInfo fbImgCreateInfo =
1491 {
1492 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1493 nullptr, // const void* pNext;
1494 0u, // VkImageCreateFlags flags;
1495 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
1496 m_params.format, // VkFormat format;
1497 texExtent, // VkExtent3D extent;
1498 1u, // deUint32 mipLevels;
1499 1u, // deUint32 arrayLayers;
1500 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1501 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1502 fbUsage, // VkImageUsageFlags usage;
1503 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1504 1u, // deUint32 queueFamilyIndexCount;
1505 &queueIndex, // const deUint32* pQueueFamilyIndices;
1506 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1507 };
1508
1509 // Create main and framebuffer images.
1510 const vk::ImageWithMemory texImage {vkd, device, allocator, texImgCreateInfo, vk::MemoryRequirement::Any};
1511 const vk::ImageWithMemory fbImage {vkd, device, allocator, fbImgCreateInfo, vk::MemoryRequirement::Any};
1512
1513 // Corresponding image views.
1514 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1515 const auto texView = vk::makeImageView(vkd, device, texImage.get(), vk::VK_IMAGE_VIEW_TYPE_2D, m_params.format, colorSubresourceRange);
1516 const auto fbView = vk::makeImageView(vkd, device, fbImage.get(), vk::VK_IMAGE_VIEW_TYPE_2D, m_params.format, colorSubresourceRange);
1517
1518 // Buffers to create the texture and verify results.
1519 const vk::VkDeviceSize texBufferSize = static_cast<vk::VkDeviceSize>(static_cast<deUint32>(tcu::getPixelSize(tcuFormat)) * texExtent.width * texExtent.height * texExtent.depth);
1520 const auto texBufferInfo = vk::makeBufferCreateInfo(texBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1521 const auto resultsBufferInfo = vk::makeBufferCreateInfo(texBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1522 const vk::BufferWithMemory texBuffer {vkd, device, allocator, texBufferInfo, vk::MemoryRequirement::HostVisible};
1523 const vk::BufferWithMemory resultsBuffer {vkd, device, allocator, resultsBufferInfo, vk::MemoryRequirement::HostVisible};
1524
1525 // Create texture.
1526 const tcu::IVec2 iImgSize {static_cast<int>(texExtent.width), static_cast<int>(texExtent.height)};
1527 auto& texBufferAlloc = texBuffer.getAllocation();
1528 auto texBufferPtr = reinterpret_cast<char*>(texBufferAlloc.getHostPtr()) + texBufferAlloc.getOffset();
1529 const tcu::PixelBufferAccess texPixels {tcuFormat, iImgSize[0], iImgSize[1], 1, texBufferPtr};
1530
1531 const int W = texPixels.getWidth();
1532 const int H = texPixels.getHeight();
1533 const int D = texPixels.getDepth();
1534
1535 const float divX = static_cast<float>(W - 1);
1536 const float divY = static_cast<float>(H - 1);
1537
1538 tcu::Vec4 texColor;
1539
1540 for (int x = 0; x < W; ++x)
1541 for (int y = 0; y < H; ++y)
1542 for (int z = 0; z < D; ++z)
1543 {
1544 if (m_params.solidColor)
1545 {
1546 // Texture with solid color for filtered sampling.
1547 texColor = tcu::Vec4{0.5f, 0.25f, 0.7529411764705882f, 1.0f};
1548 }
1549 else
1550 {
1551 // Use a color gradient otherwise.
1552 const float colorX = static_cast<float>(x) / divX;
1553 const float colorY = static_cast<float>(y) / divY;
1554 const float colorZ = std::min(colorX, colorY);
1555
1556 texColor = tcu::Vec4{colorX, colorY, colorZ, 1.0f};
1557 }
1558 const tcu::Vec4 finalColor = (texColor - formatInfo.lookupBias) / formatInfo.lookupScale;
1559 texPixels.setPixel(finalColor, x, y, z);
1560 }
1561
1562 vk::flushAlloc(vkd, device, texBufferAlloc);
1563
1564 float minU = 0.0f;
1565 float maxU = 1.0f;
1566 float minV = 0.0f;
1567 float maxV = 1.0f;
1568
1569 // When testing the edges, apply a texture offset of almost half a texel, so the sample location is very close to the texel border.
1570 if (m_params.offsetSign)
1571 {
1572 const float sign = m_params.offsetSign.get(); DE_ASSERT(sign == 1.0f || sign == -1.0f);
1573 const float offsetWidth = 0.499f / static_cast<float>(texExtent.width);
1574 const float offsetHeight = 0.499f / static_cast<float>(texExtent.height);
1575
1576 minU += sign * offsetWidth;
1577 maxU += sign * offsetWidth;
1578 minV += sign * offsetHeight;
1579 maxV += sign * offsetHeight;
1580 }
1581
1582 const std::vector<ExactSamplingCase::VertexData> fullScreenQuad =
1583 {
1584 {{ 1.f, -1.f }, { maxU, minV }, },
1585 {{ -1.f, -1.f }, { minU, minV }, },
1586 {{ -1.f, 1.f }, { minU, maxV }, },
1587 {{ -1.f, 1.f }, { minU, maxV }, },
1588 {{ 1.f, -1.f }, { maxU, minV }, },
1589 {{ 1.f, 1.f }, { maxU, maxV }, },
1590 };
1591
1592 // Vertex buffer.
1593 const vk::VkDeviceSize vertexBufferSize = static_cast<vk::VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
1594 const auto vertexBufferInfo = vk::makeBufferCreateInfo(vertexBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1595 const vk::BufferWithMemory vertexBuffer {vkd, device, allocator, vertexBufferInfo, vk::MemoryRequirement::HostVisible};
1596
1597 // Copy data to vertex buffer.
1598 const auto& vertexAlloc = vertexBuffer.getAllocation();
1599 const auto vertexDataPtr = reinterpret_cast<char*>(vertexAlloc.getHostPtr()) + vertexAlloc.getOffset();
1600 deMemcpy(vertexDataPtr, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
1601 vk::flushAlloc(vkd, device, vertexAlloc);
1602
1603 // Descriptor set layout.
1604 vk::DescriptorSetLayoutBuilder layoutBuilder;
1605 layoutBuilder.addSingleBinding(descType, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
1606 const auto descriptorSetLayout = layoutBuilder.build(vkd, device);
1607
1608 // Descriptor pool.
1609 vk::DescriptorPoolBuilder poolBuilder;
1610 poolBuilder.addType(descType);
1611 const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1612
1613 // Descriptor set.
1614 const auto descriptorSet = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1615
1616 // Texture sampler. When using a solid color, test linear filtering. Linear filtering may incur in a small precission loss, but
1617 // it should be minimal and we should get the same color when converting back to the original format.
1618 const auto minMagFilter = (m_params.solidColor ? vk::VK_FILTER_LINEAR : vk::VK_FILTER_NEAREST);
1619 const auto addressMode = (unnorm ? vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : vk::VK_SAMPLER_ADDRESS_MODE_REPEAT);
1620 const auto unnormalizedCoordinates = (unnorm ? VK_TRUE : VK_FALSE);
1621
1622 const vk::VkSamplerCreateInfo samplerCreateInfo =
1623 {
1624 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1625 nullptr, // const void* pNext;
1626 0u, // VkSamplerCreateFlags flags;
1627 minMagFilter, // VkFilter magFilter;
1628 minMagFilter, // VkFilter minFilter;
1629 vk::VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
1630 addressMode, // VkSamplerAddressMode addressModeU;
1631 addressMode, // VkSamplerAddressMode addressModeV;
1632 addressMode, // VkSamplerAddressMode addressModeW;
1633 0.0f, // float mipLodBias;
1634 VK_FALSE, // VkBool32 anisotropyEnable;
1635 1.0f, // float maxAnisotropy;
1636 VK_FALSE, // VkBool32 compareEnable;
1637 vk::VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1638 0.0f, // float minLod;
1639 0.0f, // float maxLod;
1640 vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
1641 unnormalizedCoordinates, // VkBool32 unnormalizedCoordinates;
1642 };
1643 const auto texSampler = vk::createSampler(vkd, device, &samplerCreateInfo);
1644
1645 // Update descriptor set with the descriptor.
1646 vk::DescriptorSetUpdateBuilder updateBuilder;
1647 const auto descriptorImageInfo = vk::makeDescriptorImageInfo(texSampler.get(), texView.get(), texLayout);
1648 updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), descType, &descriptorImageInfo);
1649 updateBuilder.update(vkd, device);
1650
1651 // Shader modules.
1652 const auto vertexModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
1653 const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
1654
1655 // Render pass.
1656 const vk::VkAttachmentDescription fbAttachment =
1657 {
1658 0u, // VkAttachmentDescriptionFlags flags;
1659 m_params.format, // VkFormat format;
1660 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1661 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1662 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1663 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1664 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1665 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1666 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
1667 };
1668
1669 const vk::VkAttachmentReference colorRef =
1670 {
1671 0u, // deUint32 attachment;
1672 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
1673 };
1674
1675 const vk::VkSubpassDescription subpass =
1676 {
1677 0u, // VkSubpassDescriptionFlags flags;
1678 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1679 0u, // deUint32 inputAttachmentCount;
1680 nullptr, // const VkAttachmentReference* pInputAttachments;
1681 1u, // deUint32 colorAttachmentCount;
1682 &colorRef, // const VkAttachmentReference* pColorAttachments;
1683 0u, // const VkAttachmentReference* pResolveAttachments;
1684 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
1685 0u, // deUint32 preserveAttachmentCount;
1686 nullptr, // const deUint32* pPreserveAttachments;
1687 };
1688
1689 const vk::VkRenderPassCreateInfo renderPassInfo =
1690 {
1691 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1692 nullptr, // const void* pNext;
1693 0u, // VkRenderPassCreateFlags flags;
1694 1u, // deUint32 attachmentCount;
1695 &fbAttachment, // const VkAttachmentDescription* pAttachments;
1696 1u, // deUint32 subpassCount;
1697 &subpass, // const VkSubpassDescription* pSubpasses;
1698 0u, // deUint32 dependencyCount;
1699 nullptr, // const VkSubpassDependency* pDependencies;
1700 };
1701 const auto renderPass = vk::createRenderPass(vkd, device, &renderPassInfo);
1702
1703 // Framebuffer.
1704 std::vector<vk::VkImageView> attachments;
1705 attachments.push_back(fbView.get());
1706 const auto framebuffer = vk::makeFramebuffer(vkd, device, renderPass.get(), 1u, &fbView.get(), texExtent.width, texExtent.height, texExtent.depth);
1707
1708 // Push constant range.
1709 const vk::VkPushConstantRange pcRange =
1710 {
1711 vk::VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlags stageFlags;
1712 0u, // deUint32 offset;
1713 static_cast<deUint32>(sizeof(ExactSamplingCase::PushConstants)), // deUint32 size;
1714 };
1715
1716 // Pipeline layout.
1717 const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo =
1718 {
1719 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1720 nullptr, // const void* pNext;
1721 0u, // VkPipelineLayoutCreateFlags flags;
1722 1u, // deUint32 setLayoutCount;
1723 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1724 1u, // deUint32 pushConstantRangeCount;
1725 &pcRange, // const VkPushConstantRange* pPushConstantRanges;
1726 };
1727 const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
1728
1729 // Graphics pipeline.
1730 const std::vector<vk::VkViewport> viewports { vk::makeViewport(texExtent) };
1731 const vk::VkRect2D renderArea = vk::makeRect2D(texExtent);
1732 const std::vector<vk::VkRect2D> scissors { renderArea };
1733
1734 const auto vtxBindingDescription = ExactSamplingCase::VertexData::getBindingDescription();
1735 const auto vtxAttributeDescriptions = ExactSamplingCase::VertexData::getAttributeDescriptions();
1736
1737 const vk::VkPipelineVertexInputStateCreateInfo vertexInputInfo =
1738 {
1739 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1740 nullptr, // const void* pNext
1741 0u, // VkPipelineVertexInputStateCreateFlags flags
1742 1u, // deUint32 vertexBindingDescriptionCount
1743 &vtxBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1744 static_cast<deUint32>(vtxAttributeDescriptions.size()), // deUint32 vertexAttributeDescriptionCount
1745 vtxAttributeDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1746 };
1747
1748 GraphicsPipelineWrapper pipeline(vkd, device, m_params.pipelineConstructionType);
1749 pipeline.setDefaultDepthStencilState()
1750 .setDefaultRasterizationState()
1751 .setDefaultMultisampleState()
1752 .setDefaultColorBlendState()
1753 .setupVertexInputState(&vertexInputInfo)
1754 .setupPreRasterizationShaderState(viewports,
1755 scissors,
1756 *pipelineLayout,
1757 *renderPass,
1758 0u,
1759 *vertexModule)
1760 .setupFragmentShaderState(*pipelineLayout, *renderPass, 0u, *fragModule)
1761 .setupFragmentOutputState(*renderPass)
1762 .setMonolithicPipelineLayout(*pipelineLayout)
1763 .buildPipeline();
1764
1765 // Command pool and command buffer.
1766 const auto cmdPool = vk::createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueIndex);
1767 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1768 const auto cmdBuffer = cmdBufferPtr.get();
1769
1770 // Draw quad.
1771 const ExactSamplingCase::PushConstants pushConstants =
1772 {
1773 static_cast<float>(texExtent.width),
1774 static_cast<float>(texExtent.height),
1775 };
1776
1777 const tcu::Vec4 clearFbColor (0.0f, 0.0f, 0.0f, 1.0f);
1778 const vk::VkDeviceSize vertexBufferOffset = 0ull;
1779
1780 const auto vertexBufferBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, vertexBuffer.get(), 0ull, vertexBufferSize);
1781 const auto preBufferCopyBarrier = vk::makeBufferMemoryBarrier(vk::VK_ACCESS_HOST_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, texBuffer.get(), 0ull, texBufferSize);
1782 const auto preTexCopyBarrier = vk::makeImageMemoryBarrier(0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texImage.get(), colorSubresourceRange);
1783 const auto postTexCopyBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texLayout, texImage.get(), colorSubresourceRange);
1784 const auto texCopyRange = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1785 const auto texImageCopy = vk::makeBufferImageCopy(texExtent, texCopyRange);
1786
1787 vk::beginCommandBuffer(vkd, cmdBuffer);
1788
1789 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0u, 0u, nullptr, 1u, &vertexBufferBarrier, 0u, nullptr);
1790 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 1u, &preBufferCopyBarrier, 0u, nullptr);
1791 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &preTexCopyBarrier);
1792 vkd.cmdCopyBufferToImage(cmdBuffer, texBuffer.get(), texImage.get(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &texImageCopy);
1793 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &postTexCopyBarrier);
1794
1795 vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea, clearFbColor);
1796 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
1797 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
1798 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
1799 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_VERTEX_BIT, 0u, static_cast<deUint32>(sizeof(pushConstants)), &pushConstants);
1800 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
1801 vk::endRenderPass(vkd, cmdBuffer);
1802
1803 vk::copyImageToBuffer(vkd, cmdBuffer, fbImage.get(), resultsBuffer.get(), iImgSize);
1804
1805 vk::endCommandBuffer(vkd, cmdBuffer);
1806 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1807
1808 // Check results.
1809 const auto& resultsBufferAlloc = resultsBuffer.getAllocation();
1810 vk::invalidateAlloc(vkd, device, resultsBufferAlloc);
1811
1812 const auto resultsBufferPtr = reinterpret_cast<const char*>(resultsBufferAlloc.getHostPtr()) + resultsBufferAlloc.getOffset();
1813 const tcu::ConstPixelBufferAccess resultPixels {tcuFormat, iImgSize[0], iImgSize[1], 1, resultsBufferPtr};
1814
1815 const tcu::TextureFormat diffFormat {tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8};
1816 const auto diffBytes = tcu::getPixelSize(diffFormat) * iImgSize[0] * iImgSize[1];
1817 std::unique_ptr<deUint8[]> diffData {new deUint8[diffBytes]};
1818 const tcu::PixelBufferAccess diffImg {diffFormat, iImgSize[0], iImgSize[1], 1, diffData.get()};
1819
1820 const tcu::Vec4 colorRed {1.0f, 0.0f, 0.0f, 1.0f};
1821 const tcu::Vec4 colorGreen {0.0f, 1.0f, 0.0f, 1.0f};
1822
1823 // Clear diff image.
1824 deMemset(diffData.get(), 0, static_cast<size_t>(diffBytes));
1825
1826 bool pass = true;
1827 for (int x = 0; x < W; ++x)
1828 for (int y = 0; y < H; ++y)
1829 for (int z = 0; z < D; ++z)
1830 {
1831 const auto inPix = texPixels.getPixel(x, y, z);
1832 const auto outPix = resultPixels.getPixel(x, y, z);
1833 if (inPix == outPix)
1834 {
1835 diffImg.setPixel(colorGreen, x, y, z);
1836 }
1837 else
1838 {
1839 pass = false;
1840 diffImg.setPixel(colorRed, x, y, z);
1841 }
1842 }
1843
1844 tcu::TestStatus status = tcu::TestStatus::pass("Pass");
1845 if (!pass)
1846 {
1847 auto& log = m_context.getTestContext().getLog();
1848 log << tcu::TestLog::Image("input", "Input texture", texPixels);
1849 log << tcu::TestLog::Image("output", "Rendered image", resultPixels);
1850 log << tcu::TestLog::Image("diff", "Mismatched pixels in red", diffImg);
1851 status = tcu::TestStatus::fail("Pixel mismatch; please check the rendered image");
1852 }
1853
1854 return status;
1855 }
1856
1857 } // anonymous
1858
createAllFormatsSamplerTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, bool separateStencilUsage = false)1859 tcu::TestCaseGroup* createAllFormatsSamplerTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, bool separateStencilUsage = false)
1860 {
1861 const struct
1862 {
1863 SamplerViewType type;
1864 const char* name;
1865 }
1866 imageViewTypes[] =
1867 {
1868 { VK_IMAGE_VIEW_TYPE_1D, "1d" },
1869 { { VK_IMAGE_VIEW_TYPE_1D, false }, "1d_unnormalized" },
1870 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
1871 { VK_IMAGE_VIEW_TYPE_2D, "2d" },
1872 { { VK_IMAGE_VIEW_TYPE_2D, false }, "2d_unnormalized" },
1873 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
1874 { VK_IMAGE_VIEW_TYPE_3D, "3d" },
1875 { VK_IMAGE_VIEW_TYPE_CUBE, "cube" },
1876 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" }
1877 };
1878
1879 const VkFormat formats[] =
1880 {
1881 // Packed formats
1882 VK_FORMAT_R4G4_UNORM_PACK8,
1883 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1884 VK_FORMAT_R5G6B5_UNORM_PACK16,
1885 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1886 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1887 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1888 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1889 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1890 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1891 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1892 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
1893 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
1894
1895 // Pairwise combinations of 8-bit channel formats, UNORM/SNORM/SINT/UINT/SRGB type x 1-to-4 channels x RGBA/BGRA order
1896 VK_FORMAT_R8_SRGB,
1897 VK_FORMAT_R8G8B8_UINT,
1898 VK_FORMAT_B8G8R8A8_SINT,
1899 VK_FORMAT_R8G8_UNORM,
1900 VK_FORMAT_B8G8R8_SNORM,
1901 VK_FORMAT_R8G8B8A8_SNORM,
1902 VK_FORMAT_R8G8_UINT,
1903 VK_FORMAT_R8_SINT,
1904 VK_FORMAT_R8G8B8A8_SRGB,
1905 VK_FORMAT_R8G8B8A8_UNORM,
1906 VK_FORMAT_B8G8R8A8_UNORM,
1907 VK_FORMAT_B8G8R8_SRGB,
1908 VK_FORMAT_R8G8_SRGB,
1909 VK_FORMAT_R8_UINT,
1910 VK_FORMAT_R8G8B8A8_UINT,
1911 VK_FORMAT_R8G8_SINT,
1912 VK_FORMAT_R8_SNORM,
1913 VK_FORMAT_B8G8R8_SINT,
1914 VK_FORMAT_R8G8_SNORM,
1915 VK_FORMAT_B8G8R8_UNORM,
1916 VK_FORMAT_R8_UNORM,
1917
1918 // Pairwise combinations of 16/32-bit channel formats x SINT/UINT/SFLOAT type x 1-to-4 channels
1919 VK_FORMAT_R32G32_SFLOAT,
1920 VK_FORMAT_R32G32B32_UINT,
1921 VK_FORMAT_R16G16B16A16_SFLOAT,
1922 VK_FORMAT_R16G16_UINT,
1923 VK_FORMAT_R32G32B32A32_SINT,
1924 VK_FORMAT_R16G16B16_SINT,
1925 VK_FORMAT_R16_SFLOAT,
1926 VK_FORMAT_R32_SINT,
1927 VK_FORMAT_R32_UINT,
1928 VK_FORMAT_R16G16B16_SFLOAT,
1929 VK_FORMAT_R16G16_SINT,
1930
1931 // More 16/32-bit formats required for testing VK_EXT_sampler_filter_minmax
1932 VK_FORMAT_R16_SNORM,
1933 VK_FORMAT_R32_SFLOAT,
1934
1935 // Scaled formats
1936 VK_FORMAT_R8G8B8A8_SSCALED,
1937 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1938
1939 // Compressed formats
1940 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1941 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1942 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1943 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1944 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1945 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1946 VK_FORMAT_EAC_R11_UNORM_BLOCK,
1947 VK_FORMAT_EAC_R11_SNORM_BLOCK,
1948 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1949 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1950 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1951 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1952 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1953 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1954 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1955 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1956 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1957 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1958 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1959 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1960
1961 // Depth formats required for testing VK_EXT_sampler_filter_minmax
1962 VK_FORMAT_D16_UNORM,
1963 VK_FORMAT_X8_D24_UNORM_PACK32,
1964 VK_FORMAT_D32_SFLOAT,
1965 VK_FORMAT_D16_UNORM_S8_UINT,
1966 VK_FORMAT_D24_UNORM_S8_UINT,
1967 VK_FORMAT_D32_SFLOAT_S8_UINT,
1968 };
1969
1970 de::MovePtr<tcu::TestCaseGroup> viewTypeTests (new tcu::TestCaseGroup(testCtx, "view_type", ""));
1971
1972 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
1973 {
1974 const SamplerViewType viewType = imageViewTypes[viewTypeNdx].type;
1975 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
1976 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
1977
1978 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1979 {
1980 const VkFormat format = formats[formatNdx];
1981 const bool isCompressed = isCompressedFormat(format);
1982 const bool isDepthStencil = !isCompressed
1983 && tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order);
1984 if (isCompressed)
1985 {
1986 // Do not use compressed formats with 1D and 1D array textures.
1987 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
1988 break;
1989 }
1990
1991 if (separateStencilUsage && !isDepthStencil)
1992 continue;
1993
1994 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx,
1995 getFormatCaseName(format).c_str(),
1996 (std::string("Samples a texture of format ") + getFormatName(format)).c_str()));
1997
1998 if (!isCompressed && viewType.isNormalized())
1999 {
2000 // Do not include minFilter tests with compressed formats.
2001 // Randomly generated compressed textures are too noisy and will derive in false positives.
2002 de::MovePtr<tcu::TestCaseGroup> minFilterTests = createSamplerMinFilterTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2003 de::MovePtr<tcu::TestCaseGroup> minReduceFilterTests = createSamplerMinReduceFilterTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2004 formatGroup->addChild(minFilterTests.release());
2005 formatGroup->addChild(minReduceFilterTests.release());
2006 }
2007
2008 de::MovePtr<tcu::TestCaseGroup> magFilterTests = createSamplerMagFilterTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2009 formatGroup->addChild(magFilterTests.release());
2010
2011 if (viewType.isNormalized())
2012 {
2013 de::MovePtr<tcu::TestCaseGroup> magReduceFilterTests = createSamplerMagReduceFilterTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2014 de::MovePtr<tcu::TestCaseGroup> mipmapTests = createSamplerMipmapTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2015
2016 formatGroup->addChild(magReduceFilterTests.release());
2017 formatGroup->addChild(mipmapTests.release());
2018 }
2019
2020 if (viewType != VK_IMAGE_VIEW_TYPE_CUBE && viewType != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
2021 {
2022 de::MovePtr<tcu::TestCaseGroup> addressModesTests = createSamplerAddressModesTests(testCtx, pipelineConstructionType, viewType, format, separateStencilUsage);
2023 formatGroup->addChild(addressModesTests.release());
2024 }
2025
2026 formatTests->addChild(formatGroup.release());
2027 }
2028
2029 viewTypeGroup->addChild(formatTests.release());
2030 viewTypeTests->addChild(viewTypeGroup.release());
2031 }
2032
2033 return viewTypeTests.release();
2034 }
2035
createExactSamplingTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)2036 tcu::TestCaseGroup* createExactSamplingTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
2037 {
2038 de::MovePtr<tcu::TestCaseGroup> exactSamplingTests(new tcu::TestCaseGroup(testCtx, "exact_sampling", "Exact sampling tests"));
2039
2040 static const std::vector<vk::VkFormat> formats =
2041 {
2042 vk::VK_FORMAT_R8_SRGB,
2043 vk::VK_FORMAT_R8G8B8_UINT,
2044 vk::VK_FORMAT_B8G8R8A8_SINT,
2045 vk::VK_FORMAT_R8G8_UNORM,
2046 vk::VK_FORMAT_B8G8R8_SNORM,
2047 vk::VK_FORMAT_R8G8B8A8_SNORM,
2048 vk::VK_FORMAT_R8G8_UINT,
2049 vk::VK_FORMAT_R8_SINT,
2050 vk::VK_FORMAT_R8G8B8A8_SRGB,
2051 vk::VK_FORMAT_R8G8B8A8_UNORM,
2052 vk::VK_FORMAT_B8G8R8A8_UNORM,
2053 vk::VK_FORMAT_B8G8R8_SRGB,
2054 vk::VK_FORMAT_R8G8_SRGB,
2055 vk::VK_FORMAT_R8_UINT,
2056 vk::VK_FORMAT_R8G8B8A8_UINT,
2057 vk::VK_FORMAT_R8G8_SINT,
2058 vk::VK_FORMAT_R8_SNORM,
2059 vk::VK_FORMAT_B8G8R8_SINT,
2060 vk::VK_FORMAT_R8G8_SNORM,
2061 vk::VK_FORMAT_B8G8R8_UNORM,
2062 vk::VK_FORMAT_R8_UNORM,
2063
2064 vk::VK_FORMAT_R32G32_SFLOAT,
2065 vk::VK_FORMAT_R32G32B32_UINT,
2066 vk::VK_FORMAT_R16G16B16A16_SFLOAT,
2067 vk::VK_FORMAT_R16G16_UINT,
2068 vk::VK_FORMAT_R32G32B32A32_SINT,
2069 vk::VK_FORMAT_R16G16B16_SINT,
2070 vk::VK_FORMAT_R16_SFLOAT,
2071 vk::VK_FORMAT_R32_SINT,
2072 vk::VK_FORMAT_R32_UINT,
2073 vk::VK_FORMAT_R16G16B16_SFLOAT,
2074 vk::VK_FORMAT_R16G16_SINT,
2075
2076 vk::VK_FORMAT_R16_SNORM,
2077 vk::VK_FORMAT_R32_SFLOAT,
2078 };
2079
2080 static const struct
2081 {
2082 const bool unnormalized;
2083 const std::string name;
2084 const std::string desc;
2085 } unnormalizedCoordinates[] =
2086 {
2087 { false, "normalized_coords", "Normalized coordinates" },
2088 { true, "unnormalized_coords", "Unnormalized coordinates" },
2089 };
2090
2091 static const struct
2092 {
2093 const tcu::Maybe<float> offset;
2094 const std::string name;
2095 const std::string desc;
2096 } testEdges[] =
2097 {
2098 { tcu::Nothing, "centered", "Sampling points centered in texel" },
2099 { tcu::just<float>(-1.0f), "edge_left", "Sampling points near left edge" },
2100 { tcu::just<float>(+1.0f), "edge_right", "Sampling points near right edge" },
2101 };
2102
2103 static const std::vector<std::pair<bool, std::string>> solidColor =
2104 {
2105 { false, "gradient" },
2106 { true, "solid_color" },
2107 };
2108
2109 for (const auto format : formats)
2110 {
2111 const std::string formatName = getFormatCaseName(format);
2112 const std::string description = std::string("Exact sampling tests with image format ") + getFormatName(format);
2113
2114 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName.c_str(), description.c_str()));
2115
2116 for (const auto& solid : solidColor)
2117 {
2118 de::MovePtr<tcu::TestCaseGroup> solidColorGroup(new tcu::TestCaseGroup(testCtx, solid.second.c_str(), ""));
2119
2120 for (int unIdx = 0; unIdx < DE_LENGTH_OF_ARRAY(unnormalizedCoordinates); ++unIdx)
2121 {
2122 const auto& unnorm = unnormalizedCoordinates[unIdx];
2123 de::MovePtr<tcu::TestCaseGroup> coordGroup (new tcu::TestCaseGroup(testCtx, unnorm.name.c_str(), unnorm.desc.c_str()));
2124
2125 for (int edgeIdx = 0; edgeIdx < DE_LENGTH_OF_ARRAY(testEdges); ++edgeIdx)
2126 {
2127 const auto& edges = testEdges[edgeIdx];
2128 const ExactSamplingCase::Params params = { pipelineConstructionType, format, unnorm.unnormalized, solid.first, edges.offset };
2129 coordGroup->addChild(new ExactSamplingCase{testCtx, edges.name, edges.desc, params});
2130 }
2131
2132 solidColorGroup->addChild(coordGroup.release());
2133 }
2134
2135 formatGroup->addChild(solidColorGroup.release());
2136 }
2137
2138 exactSamplingTests->addChild(formatGroup.release());
2139 }
2140
2141 return exactSamplingTests.release();
2142 }
2143
createSamplerTests(tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)2144 tcu::TestCaseGroup* createSamplerTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
2145 {
2146 de::MovePtr<tcu::TestCaseGroup> samplerTests(new tcu::TestCaseGroup(testCtx, "sampler", "Sampler tests"));
2147 {
2148 samplerTests->addChild(createAllFormatsSamplerTests(testCtx, pipelineConstructionType));
2149 samplerTests->addChild(createExactSamplingTests(testCtx, pipelineConstructionType));
2150 }
2151
2152 // tests for VK_EXT_separate_stencil_usage
2153 de::MovePtr<tcu::TestCaseGroup> separateStencilUsageSamplerTests (new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "testing VK_EXT_separate_stencil_uasge"));
2154 {
2155 separateStencilUsageSamplerTests->addChild(createAllFormatsSamplerTests(testCtx, pipelineConstructionType, true));
2156 samplerTests->addChild(separateStencilUsageSamplerTests.release());
2157 }
2158
2159 #ifndef CTS_USES_VULKANSC
2160 // Border color swizzle tests.
2161 samplerTests->addChild(createSamplerBorderSwizzleTests(testCtx, pipelineConstructionType));
2162 #endif // CTS_USES_VULKANSC
2163
2164 return samplerTests.release();
2165 }
2166
2167 } // pipeline
2168 } // vkt
2169