1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 * Copyright (c) 2023 LunarG, Inc.
8 * Copyright (c) 2023 Nintendo
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Image Tests
25 *//*--------------------------------------------------------------------*/
26
27 #include "vktPipelineImageTests.hpp"
28 #include "vktPipelineImageSamplingInstance.hpp"
29 #include "vktPipelineImageUtil.hpp"
30 #include "vktPipelineVertexUtil.hpp"
31 #include "vktTestCase.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "deStringUtil.hpp"
36
37 #include <sstream>
38 #include <vector>
39
40 namespace vkt
41 {
42 namespace pipeline
43 {
44
45 using namespace vk;
46 using de::MovePtr;
47
48 namespace
49 {
50
51 class ImageTest : public vkt::TestCase
52 {
53 public:
54 ImageTest(tcu::TestContext &testContext, const char *name, AllocationKind allocationKind,
55 PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType,
56 VkImageViewType imageViewType, VkFormat imageFormat, const tcu::IVec3 &imageSize, int imageCount,
57 int arraySize, bool pipelineProtectedFlag);
58
59 ImageSamplingInstanceParams getImageSamplingInstanceParams(AllocationKind allocationKind,
60 VkDescriptorType samplingType,
61 VkImageViewType imageViewType, VkFormat imageFormat,
62 const tcu::IVec3 &imageSize, int imageCount,
63 int arraySize) const;
64
65 virtual void initPrograms(SourceCollections &sourceCollections) const;
66 virtual void checkSupport(Context &context) const;
67 virtual TestInstance *createInstance(Context &context) const;
68 static std::string getGlslSamplerType(const tcu::TextureFormat &format, VkImageViewType type);
69 static std::string getGlslTextureType(const tcu::TextureFormat &format, VkImageViewType type);
70 static std::string getGlslSamplerDecl(int imageCount);
71 static std::string getGlslTextureDecl(int imageCount);
72 static std::string getGlslFragColorDecl(int imageCount);
73 static std::string getGlslSampler(const tcu::TextureFormat &format, VkImageViewType type,
74 VkDescriptorType samplingType, int imageCount);
75
76 private:
77 AllocationKind m_allocationKind;
78 PipelineConstructionType m_pipelineConstructionType;
79 VkDescriptorType m_samplingType;
80 VkImageViewType m_imageViewType;
81 VkFormat m_imageFormat;
82 tcu::IVec3 m_imageSize;
83 int m_imageCount;
84 int m_arraySize;
85 bool m_pipelineProtectedFlag;
86 };
87
ImageTest(tcu::TestContext & testContext,const char * name,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,const tcu::IVec3 & imageSize,int imageCount,int arraySize,bool pipelineProtectedFlag)88 ImageTest::ImageTest(tcu::TestContext &testContext, const char *name, AllocationKind allocationKind,
89 PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType,
90 VkImageViewType imageViewType, VkFormat imageFormat, const tcu::IVec3 &imageSize, int imageCount,
91 int arraySize, bool pipelineProtectedFlag)
92
93 : vkt::TestCase(testContext, name)
94 , m_allocationKind(allocationKind)
95 , m_pipelineConstructionType(pipelineConstructionType)
96 , m_samplingType(samplingType)
97 , m_imageViewType(imageViewType)
98 , m_imageFormat(imageFormat)
99 , m_imageSize(imageSize)
100 , m_imageCount(imageCount)
101 , m_arraySize(arraySize)
102 , m_pipelineProtectedFlag(pipelineProtectedFlag)
103 {
104 }
105
checkSupport(Context & context) const106 void ImageTest::checkSupport(Context &context) const
107 {
108 // Using a loop to index into an array of images requires shaderSampledImageArrayDynamicIndexing
109 if (m_imageCount > 1)
110 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING);
111
112 #ifndef CTS_USES_VULKANSC
113 if (m_imageFormat == VK_FORMAT_A8_UNORM_KHR || m_imageFormat == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
114 context.requireDeviceFunctionality("VK_KHR_maintenance5");
115 #endif // CTS_USES_VULKANSC
116
117 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
118 m_pipelineConstructionType);
119 checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType,
120 m_imageViewType, m_imageFormat,
121 m_imageSize, m_imageCount, m_arraySize));
122
123 if (m_pipelineProtectedFlag)
124 {
125 #ifndef CTS_USES_VULKANSC
126 context.requireDeviceFunctionality("VK_EXT_pipeline_protected_access");
127
128 if (!context.getPipelineProtectedAccessFeaturesEXT().pipelineProtectedAccess)
129 {
130 throw tcu::NotSupportedError("pipelineProtectedAccess feature is not supported");
131 }
132 #else // CTS_USES_VULKANSC
133 throw tcu::NotSupportedError("pipeline protected access is not supported");
134 #endif // CTS_USES_VULKANSC
135 }
136 }
137
getImageSamplingInstanceParams(AllocationKind allocationKind,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,const tcu::IVec3 & imageSize,int imageCount,int arraySize) const138 ImageSamplingInstanceParams ImageTest::getImageSamplingInstanceParams(AllocationKind allocationKind,
139 VkDescriptorType samplingType,
140 VkImageViewType imageViewType,
141 VkFormat imageFormat, const tcu::IVec3 &imageSize,
142 int imageCount, int arraySize) const
143 {
144 tcu::UVec2 renderSize;
145
146 if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_2D)
147 {
148 renderSize = tcu::UVec2((uint32_t)imageSize.x(), (uint32_t)imageSize.y());
149 }
150 else
151 {
152 // Draw a 3x2 grid of texture layers
153 renderSize = tcu::UVec2((uint32_t)imageSize.x() * 3, (uint32_t)imageSize.y() * 2);
154 }
155
156 const bool separateStencilUsage = false;
157 const std::vector<Vertex4Tex4> vertices = createTestQuadMosaic(imageViewType);
158 const VkComponentMapping componentMapping = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B,
159 VK_COMPONENT_SWIZZLE_A};
160 const VkImageSubresourceRange subresourceRange = {
161 VK_IMAGE_ASPECT_COLOR_BIT,
162 0u,
163 (uint32_t)deLog2Floor32(deMax32(imageSize.x(), deMax32(imageSize.y(), imageSize.z()))) + 1,
164 0u,
165 (uint32_t)arraySize,
166 };
167
168 const VkSamplerCreateInfo samplerParams = {
169 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
170 DE_NULL, // const void* pNext;
171 0u, // VkSamplerCreateFlags flags;
172 VK_FILTER_NEAREST, // VkFilter magFilter;
173 VK_FILTER_NEAREST, // VkFilter minFilter;
174 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
175 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
176 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
177 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
178 0.0f, // float mipLodBias;
179 VK_FALSE, // VkBool32 anisotropyEnable;
180 1.0f, // float maxAnisotropy;
181 false, // VkBool32 compareEnable;
182 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
183 0.0f, // float minLod;
184 (float)(subresourceRange.levelCount - 1), // float maxLod;
185 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, imageFormat,
186 false), // VkBorderColor borderColor;
187 false // VkBool32 unnormalizedCoordinates;
188 };
189
190 #ifdef CTS_USES_VULKANSC
191 const vk::VkPipelineCreateFlags pipelineFlags = (vk::VkPipelineCreateFlagBits)0u;
192 (void)m_pipelineProtectedFlag;
193 #else // CTS_USES_VULKANSC
194 const vk::VkPipelineCreateFlags pipelineFlags =
195 m_pipelineProtectedFlag ? vk::VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT : (vk::VkPipelineCreateFlagBits)0u;
196 #endif // CTS_USES_VULKANSC
197
198 return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat, imageSize,
199 arraySize, componentMapping, subresourceRange, samplerParams, 0.0f, vertices,
200 separateStencilUsage, samplingType, imageCount, allocationKind,
201 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, pipelineFlags);
202 }
203
initPrograms(SourceCollections & sourceCollections) const204 void ImageTest::initPrograms(SourceCollections &sourceCollections) const
205 {
206 std::ostringstream vertexSrc;
207 std::ostringstream fragmentSrc;
208 const char *texCoordSwizzle = DE_NULL;
209 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ?
210 tcu::getUncompressedFormat(mapVkCompressedFormat(m_imageFormat)) :
211 mapVkFormat(m_imageFormat);
212
213 tcu::Vec4 lookupScale;
214 tcu::Vec4 lookupBias;
215
216 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
217
218 switch (m_imageViewType)
219 {
220 case VK_IMAGE_VIEW_TYPE_1D:
221 texCoordSwizzle = "x";
222 break;
223 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
224 case VK_IMAGE_VIEW_TYPE_2D:
225 texCoordSwizzle = "xy";
226 break;
227 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
228 case VK_IMAGE_VIEW_TYPE_3D:
229 case VK_IMAGE_VIEW_TYPE_CUBE:
230 texCoordSwizzle = "xyz";
231 break;
232 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
233 texCoordSwizzle = "xyzw";
234 break;
235 default:
236 DE_ASSERT(false);
237 break;
238 }
239
240 vertexSrc << "#version 440\n"
241 << "layout(location = 0) in vec4 position;\n"
242 << "layout(location = 1) in vec4 texCoords;\n"
243 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
244 << "out gl_PerVertex {\n"
245 << " vec4 gl_Position;\n"
246 << "};\n"
247 << "void main (void)\n"
248 << "{\n"
249 << " gl_Position = position;\n"
250 << " vtxTexCoords = texCoords;\n"
251 << "}\n";
252
253 fragmentSrc << "#version 440\n";
254 switch (m_samplingType)
255 {
256 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
257 fragmentSrc << "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
258 << "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType)
259 << " " << getGlslTextureDecl(m_imageCount) << ";\n";
260 break;
261 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
262 default:
263 fragmentSrc << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType)
264 << " " << getGlslSamplerDecl(m_imageCount) << ";\n";
265 }
266 fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
267 << "layout(location = 0) out highp vec4 " << getGlslFragColorDecl(m_imageCount) << ";\n"
268 << "void main (void)\n"
269 << "{\n";
270 if (m_imageCount > 1)
271 fragmentSrc << " for (uint i = 0; i < " << m_imageCount << "; ++i)\n"
272 << " fragColors[i] = (texture("
273 << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords."
274 << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias
275 << "; \n";
276 else
277 fragmentSrc << " fragColor = (texture("
278 << getGlslSampler(format, m_imageViewType, m_samplingType, m_imageCount) << ", vtxTexCoords."
279 << texCoordSwizzle << std::scientific << ") * vec4" << lookupScale << ") + vec4" << lookupBias
280 << "; \n";
281 fragmentSrc << "}\n";
282
283 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
284 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
285 }
286
createInstance(Context & context) const287 TestInstance *ImageTest::createInstance(Context &context) const
288 {
289 return new ImageSamplingInstance(context, getImageSamplingInstanceParams(m_allocationKind, m_samplingType,
290 m_imageViewType, m_imageFormat,
291 m_imageSize, m_imageCount, m_arraySize));
292 }
293
getGlslSamplerType(const tcu::TextureFormat & format,VkImageViewType type)294 std::string ImageTest::getGlslSamplerType(const tcu::TextureFormat &format, VkImageViewType type)
295 {
296 std::ostringstream samplerType;
297
298 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
299 samplerType << "u";
300 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
301 samplerType << "i";
302
303 switch (type)
304 {
305 case VK_IMAGE_VIEW_TYPE_1D:
306 samplerType << "sampler1D";
307 break;
308
309 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
310 samplerType << "sampler1DArray";
311 break;
312
313 case VK_IMAGE_VIEW_TYPE_2D:
314 samplerType << "sampler2D";
315 break;
316
317 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
318 samplerType << "sampler2DArray";
319 break;
320
321 case VK_IMAGE_VIEW_TYPE_3D:
322 samplerType << "sampler3D";
323 break;
324
325 case VK_IMAGE_VIEW_TYPE_CUBE:
326 samplerType << "samplerCube";
327 break;
328
329 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
330 samplerType << "samplerCubeArray";
331 break;
332
333 default:
334 DE_FATAL("Unknown image view type");
335 break;
336 }
337
338 return samplerType.str();
339 }
340
getGlslTextureType(const tcu::TextureFormat & format,VkImageViewType type)341 std::string ImageTest::getGlslTextureType(const tcu::TextureFormat &format, VkImageViewType type)
342 {
343 std::ostringstream textureType;
344
345 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
346 textureType << "u";
347 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
348 textureType << "i";
349
350 switch (type)
351 {
352 case VK_IMAGE_VIEW_TYPE_1D:
353 textureType << "texture1D";
354 break;
355
356 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
357 textureType << "texture1DArray";
358 break;
359
360 case VK_IMAGE_VIEW_TYPE_2D:
361 textureType << "texture2D";
362 break;
363
364 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
365 textureType << "texture2DArray";
366 break;
367
368 case VK_IMAGE_VIEW_TYPE_3D:
369 textureType << "texture3D";
370 break;
371
372 case VK_IMAGE_VIEW_TYPE_CUBE:
373 textureType << "textureCube";
374 break;
375
376 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
377 textureType << "textureCubeArray";
378 break;
379
380 default:
381 DE_FATAL("Unknown image view type");
382 }
383
384 return textureType.str();
385 }
386
getGlslSamplerDecl(int imageCount)387 std::string ImageTest::getGlslSamplerDecl(int imageCount)
388 {
389 std::ostringstream samplerArray;
390 samplerArray << "texSamplers[" << imageCount << "]";
391
392 return imageCount > 1 ? samplerArray.str() : "texSampler";
393 }
394
getGlslTextureDecl(int imageCount)395 std::string ImageTest::getGlslTextureDecl(int imageCount)
396 {
397 std::ostringstream textureArray;
398 textureArray << "texImages[" << imageCount << "]";
399
400 return imageCount > 1 ? textureArray.str() : "texImage";
401 }
402
getGlslFragColorDecl(int imageCount)403 std::string ImageTest::getGlslFragColorDecl(int imageCount)
404 {
405 std::ostringstream samplerArray;
406 samplerArray << "fragColors[" << imageCount << "]";
407
408 return imageCount > 1 ? samplerArray.str() : "fragColor";
409 }
410
getGlslSampler(const tcu::TextureFormat & format,VkImageViewType type,VkDescriptorType samplingType,int imageCount)411 std::string ImageTest::getGlslSampler(const tcu::TextureFormat &format, VkImageViewType type,
412 VkDescriptorType samplingType, int imageCount)
413 {
414 std::string texSampler = imageCount > 1 ? "texSamplers[i]" : "texSampler";
415 std::string texImage = imageCount > 1 ? "texImages[i]" : "texImage";
416
417 switch (samplingType)
418 {
419 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
420 return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
421 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
422 default:
423 return texSampler;
424 }
425 }
426
getFormatCaseName(const VkFormat format)427 std::string getFormatCaseName(const VkFormat format)
428 {
429 const std::string fullName = getFormatName(format);
430
431 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
432
433 return de::toLower(fullName.substr(10));
434 }
435
getSizeName(VkImageViewType viewType,const tcu::IVec3 & size,int arraySize,bool pipelineProtectedFlag)436 std::string getSizeName(VkImageViewType viewType, const tcu::IVec3 &size, int arraySize, bool pipelineProtectedFlag)
437 {
438 std::ostringstream caseName;
439
440 if (pipelineProtectedFlag)
441 {
442 caseName << "pipeline_protected_flag_";
443 }
444
445 switch (viewType)
446 {
447 case VK_IMAGE_VIEW_TYPE_1D:
448 case VK_IMAGE_VIEW_TYPE_2D:
449 case VK_IMAGE_VIEW_TYPE_CUBE:
450 caseName << size.x() << "x" << size.y();
451 break;
452
453 case VK_IMAGE_VIEW_TYPE_3D:
454 caseName << size.x() << "x" << size.y() << "x" << size.z();
455 break;
456
457 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
458 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
459 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
460 caseName << size.x() << "x" << size.y() << "_array_of_" << arraySize;
461 break;
462
463 default:
464 DE_ASSERT(false);
465 break;
466 }
467
468 return caseName.str();
469 }
470
createImageSizeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat,int imageCount)471 de::MovePtr<tcu::TestCaseGroup> createImageSizeTests(tcu::TestContext &testCtx, AllocationKind allocationKind,
472 PipelineConstructionType pipelineConstructionType,
473 VkDescriptorType samplingType, VkImageViewType imageViewType,
474 VkFormat imageFormat, int imageCount)
475 {
476 using tcu::IVec3;
477
478 std::vector<IVec3> imageSizes;
479 std::vector<int> arraySizes;
480 de::MovePtr<tcu::TestCaseGroup> imageSizeTests(new tcu::TestCaseGroup(testCtx, "size"));
481
482 const bool pipelineProtectedAccess[] = {
483 false,
484 #ifndef CTS_USES_VULKANSC
485 true,
486 #endif
487 };
488 const bool pipelineProtectedFlag[] = {
489 false,
490 #ifndef CTS_USES_VULKANSC
491 true,
492 #endif
493 };
494
495 // Select image imageSizes
496 switch (imageViewType)
497 {
498 case VK_IMAGE_VIEW_TYPE_1D:
499 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
500 // POT
501 if (imageCount == 1)
502 {
503 imageSizes.push_back(IVec3(1, 1, 1));
504 imageSizes.push_back(IVec3(2, 1, 1));
505 imageSizes.push_back(IVec3(32, 1, 1));
506 imageSizes.push_back(IVec3(128, 1, 1));
507 }
508 imageSizes.push_back(IVec3(512, 1, 1));
509
510 // NPOT
511 if (imageCount == 1)
512 {
513 imageSizes.push_back(IVec3(3, 1, 1));
514 imageSizes.push_back(IVec3(13, 1, 1));
515 imageSizes.push_back(IVec3(127, 1, 1));
516 }
517 imageSizes.push_back(IVec3(443, 1, 1));
518 break;
519
520 case VK_IMAGE_VIEW_TYPE_2D:
521 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
522 if (imageCount == 1)
523 {
524 // POT
525 imageSizes.push_back(IVec3(1, 1, 1));
526 imageSizes.push_back(IVec3(2, 2, 1));
527 imageSizes.push_back(IVec3(32, 32, 1));
528
529 // NPOT
530 imageSizes.push_back(IVec3(3, 3, 1));
531 imageSizes.push_back(IVec3(13, 13, 1));
532 }
533
534 // POT rectangular
535 if (imageCount == 1)
536 imageSizes.push_back(IVec3(8, 16, 1));
537 imageSizes.push_back(IVec3(32, 16, 1));
538
539 // NPOT rectangular
540 imageSizes.push_back(IVec3(13, 23, 1));
541 if (imageCount == 1)
542 imageSizes.push_back(IVec3(23, 8, 1));
543 break;
544
545 case VK_IMAGE_VIEW_TYPE_3D:
546 // POT cube
547 if (imageCount == 1)
548 {
549 imageSizes.push_back(IVec3(1, 1, 1));
550 imageSizes.push_back(IVec3(2, 2, 2));
551 }
552 imageSizes.push_back(IVec3(16, 16, 16));
553
554 // NPOT cube
555 if (imageCount == 1)
556 {
557 imageSizes.push_back(IVec3(3, 3, 3));
558 imageSizes.push_back(IVec3(5, 5, 5));
559 }
560 imageSizes.push_back(IVec3(11, 11, 11));
561
562 // POT non-cube
563 if (imageCount == 1)
564 imageSizes.push_back(IVec3(32, 16, 8));
565 imageSizes.push_back(IVec3(8, 16, 32));
566
567 // NPOT non-cube
568 imageSizes.push_back(IVec3(17, 11, 5));
569 if (imageCount == 1)
570 imageSizes.push_back(IVec3(5, 11, 17));
571 break;
572
573 case VK_IMAGE_VIEW_TYPE_CUBE:
574 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
575 // POT
576 imageSizes.push_back(IVec3(32, 32, 1));
577
578 // NPOT
579 imageSizes.push_back(IVec3(13, 13, 1));
580 break;
581
582 default:
583 DE_ASSERT(false);
584 break;
585 }
586
587 // Select array sizes
588 switch (imageViewType)
589 {
590 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
591 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
592 if (imageCount == 1)
593 arraySizes.push_back(3);
594 arraySizes.push_back(6);
595 break;
596
597 case VK_IMAGE_VIEW_TYPE_CUBE:
598 arraySizes.push_back(6);
599 break;
600
601 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
602 if (imageCount == 1)
603 arraySizes.push_back(6);
604 arraySizes.push_back(6 * 6);
605 break;
606
607 default:
608 arraySizes.push_back(1);
609 break;
610 }
611
612 for (size_t flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(pipelineProtectedAccess); ++flagNdx)
613 {
614
615 /* VK_EXT_pipeline_protected_access doesn't apply to shader objects */
616 if (pipelineProtectedFlag[flagNdx] && isConstructionTypeShaderObject(pipelineConstructionType))
617 continue;
618
619 for (size_t sizeNdx = 0; sizeNdx < imageSizes.size(); sizeNdx++)
620 {
621 for (size_t arraySizeNdx = 0; arraySizeNdx < arraySizes.size(); arraySizeNdx++)
622 {
623 imageSizeTests->addChild(new ImageTest(
624 testCtx,
625 getSizeName(imageViewType, imageSizes[sizeNdx], arraySizes[arraySizeNdx],
626 pipelineProtectedFlag[flagNdx])
627 .c_str(),
628 allocationKind, pipelineConstructionType, samplingType, imageViewType, imageFormat,
629 imageSizes[sizeNdx], imageCount, arraySizes[arraySizeNdx], pipelineProtectedFlag[flagNdx]));
630 }
631 }
632 }
633
634 return imageSizeTests;
635 }
636
createImageCountTests(tcu::TestCaseGroup * parentGroup,tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType,VkFormat imageFormat)637 void createImageCountTests(tcu::TestCaseGroup *parentGroup, tcu::TestContext &testCtx, AllocationKind allocationKind,
638 PipelineConstructionType pipelineConstructionType, VkDescriptorType samplingType,
639 VkImageViewType imageViewType, VkFormat imageFormat)
640 {
641 const int coreImageCounts[] = {1, 4, 8};
642 const int dedicatedAllocationImageCounts[] = {1};
643 const int *imageCounts =
644 (allocationKind == ALLOCATION_KIND_DEDICATED) ? dedicatedAllocationImageCounts : coreImageCounts;
645 const size_t imageCountsLength = (allocationKind == ALLOCATION_KIND_DEDICATED) ?
646 DE_LENGTH_OF_ARRAY(dedicatedAllocationImageCounts) :
647 DE_LENGTH_OF_ARRAY(coreImageCounts);
648
649 for (size_t countNdx = 0; countNdx < imageCountsLength; countNdx++)
650 {
651 std::ostringstream caseName;
652 caseName << "count_" << imageCounts[countNdx];
653 de::MovePtr<tcu::TestCaseGroup> countGroup(new tcu::TestCaseGroup(testCtx, caseName.str().c_str()));
654 de::MovePtr<tcu::TestCaseGroup> sizeTests =
655 createImageSizeTests(testCtx, allocationKind, pipelineConstructionType, samplingType, imageViewType,
656 imageFormat, imageCounts[countNdx]);
657
658 countGroup->addChild(sizeTests.release());
659 parentGroup->addChild(countGroup.release());
660 }
661 }
662
createImageFormatTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType,VkImageViewType imageViewType)663 de::MovePtr<tcu::TestCaseGroup> createImageFormatTests(tcu::TestContext &testCtx, AllocationKind allocationKind,
664 PipelineConstructionType pipelineConstructionType,
665 VkDescriptorType samplingType, VkImageViewType imageViewType)
666 {
667 // All supported dEQP formats that are not intended for depth or stencil.
668 const VkFormat coreFormats[] = {
669 VK_FORMAT_R4G4_UNORM_PACK8,
670 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
671 VK_FORMAT_R5G6B5_UNORM_PACK16,
672 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
673 VK_FORMAT_R8_UNORM,
674 VK_FORMAT_R8_SNORM,
675 VK_FORMAT_R8_USCALED,
676 VK_FORMAT_R8_SSCALED,
677 VK_FORMAT_R8_UINT,
678 VK_FORMAT_R8_SINT,
679 VK_FORMAT_R8_SRGB,
680 VK_FORMAT_R8G8_UNORM,
681 VK_FORMAT_R8G8_SNORM,
682 VK_FORMAT_R8G8_USCALED,
683 VK_FORMAT_R8G8_SSCALED,
684 VK_FORMAT_R8G8_UINT,
685 VK_FORMAT_R8G8_SINT,
686 VK_FORMAT_R8G8_SRGB,
687 VK_FORMAT_R8G8B8_UNORM,
688 VK_FORMAT_R8G8B8_SNORM,
689 VK_FORMAT_R8G8B8_USCALED,
690 VK_FORMAT_R8G8B8_SSCALED,
691 VK_FORMAT_R8G8B8_UINT,
692 VK_FORMAT_R8G8B8_SINT,
693 VK_FORMAT_R8G8B8_SRGB,
694 VK_FORMAT_R8G8B8A8_UNORM,
695 VK_FORMAT_R8G8B8A8_SNORM,
696 VK_FORMAT_R8G8B8A8_USCALED,
697 VK_FORMAT_R8G8B8A8_SSCALED,
698 VK_FORMAT_R8G8B8A8_UINT,
699 VK_FORMAT_R8G8B8A8_SINT,
700 VK_FORMAT_R8G8B8A8_SRGB,
701 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
702 VK_FORMAT_A2R10G10B10_UINT_PACK32,
703 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
704 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
705 VK_FORMAT_A2B10G10R10_UINT_PACK32,
706 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
707 #ifndef CTS_USES_VULKANSC
708 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
709 #endif // CTS_USES_VULKANSC
710 VK_FORMAT_R16_UNORM,
711 VK_FORMAT_R16_SNORM,
712 VK_FORMAT_R16_USCALED,
713 VK_FORMAT_R16_SSCALED,
714 VK_FORMAT_R16_UINT,
715 VK_FORMAT_R16_SINT,
716 VK_FORMAT_R16_SFLOAT,
717 VK_FORMAT_R16G16_UNORM,
718 VK_FORMAT_R16G16_SNORM,
719 VK_FORMAT_R16G16_USCALED,
720 VK_FORMAT_R16G16_SSCALED,
721 VK_FORMAT_R16G16_UINT,
722 VK_FORMAT_R16G16_SINT,
723 VK_FORMAT_R16G16_SFLOAT,
724 VK_FORMAT_R16G16B16_UNORM,
725 VK_FORMAT_R16G16B16_SNORM,
726 VK_FORMAT_R16G16B16_USCALED,
727 VK_FORMAT_R16G16B16_SSCALED,
728 VK_FORMAT_R16G16B16_UINT,
729 VK_FORMAT_R16G16B16_SINT,
730 VK_FORMAT_R16G16B16_SFLOAT,
731 VK_FORMAT_R16G16B16A16_UNORM,
732 VK_FORMAT_R16G16B16A16_SNORM,
733 VK_FORMAT_R16G16B16A16_USCALED,
734 VK_FORMAT_R16G16B16A16_SSCALED,
735 VK_FORMAT_R16G16B16A16_UINT,
736 VK_FORMAT_R16G16B16A16_SINT,
737 VK_FORMAT_R16G16B16A16_SFLOAT,
738 VK_FORMAT_R32_UINT,
739 VK_FORMAT_R32_SINT,
740 VK_FORMAT_R32_SFLOAT,
741 VK_FORMAT_R32G32_UINT,
742 VK_FORMAT_R32G32_SINT,
743 VK_FORMAT_R32G32_SFLOAT,
744 VK_FORMAT_R32G32B32_UINT,
745 VK_FORMAT_R32G32B32_SINT,
746 VK_FORMAT_R32G32B32_SFLOAT,
747 VK_FORMAT_R32G32B32A32_UINT,
748 VK_FORMAT_R32G32B32A32_SINT,
749 VK_FORMAT_R32G32B32A32_SFLOAT,
750 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
751 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
752 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
753 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
754 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
755 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
756 #ifndef CTS_USES_VULKANSC
757 VK_FORMAT_A8_UNORM_KHR,
758 #endif // CTS_USES_VULKANSC
759
760 // Compressed formats
761 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
762 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
763 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
764 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
765 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
766 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
767 VK_FORMAT_EAC_R11_UNORM_BLOCK,
768 VK_FORMAT_EAC_R11_SNORM_BLOCK,
769 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
770 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
771 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
772 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
773 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
774 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
775 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
776 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
777 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
778 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
779 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
780 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
781 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
782 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
783 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
784 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
785 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
786 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
787 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
788 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
789 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
790 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
791 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
792 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
793 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
794 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
795 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
796 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
797 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
798 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
799 };
800 // Formats to test with dedicated allocation
801 const VkFormat dedicatedAllocationFormats[] = {
802 VK_FORMAT_R8G8B8A8_UNORM,
803 VK_FORMAT_R16_SFLOAT,
804 };
805 const VkFormat *formats = (allocationKind == ALLOCATION_KIND_DEDICATED) ? dedicatedAllocationFormats : coreFormats;
806 const size_t formatsLength = (allocationKind == ALLOCATION_KIND_DEDICATED) ?
807 DE_LENGTH_OF_ARRAY(dedicatedAllocationFormats) :
808 DE_LENGTH_OF_ARRAY(coreFormats);
809
810 de::MovePtr<tcu::TestCaseGroup> imageFormatTests(new tcu::TestCaseGroup(testCtx, "format"));
811
812 for (size_t formatNdx = 0; formatNdx < formatsLength; formatNdx++)
813 {
814 const VkFormat format = formats[formatNdx];
815
816 if (isCompressedFormat(format))
817 {
818 // Do not use compressed formats with 1D and 1D array textures.
819 if (imageViewType == VK_IMAGE_VIEW_TYPE_1D || imageViewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
820 break;
821 }
822
823 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getFormatCaseName(format).c_str()));
824 createImageCountTests(formatGroup.get(), testCtx, allocationKind, pipelineConstructionType, samplingType,
825 imageViewType, format);
826
827 imageFormatTests->addChild(formatGroup.release());
828 }
829
830 return imageFormatTests;
831 }
832
createImageViewTypeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType,VkDescriptorType samplingType)833 de::MovePtr<tcu::TestCaseGroup> createImageViewTypeTests(tcu::TestContext &testCtx, AllocationKind allocationKind,
834 PipelineConstructionType pipelineConstructionType,
835 VkDescriptorType samplingType)
836 {
837 const struct
838 {
839 VkImageViewType type;
840 const char *name;
841 } imageViewTypes[] = {{VK_IMAGE_VIEW_TYPE_1D, "1d"},
842 {VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array"},
843 {VK_IMAGE_VIEW_TYPE_2D, "2d"},
844 {VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array"},
845 {VK_IMAGE_VIEW_TYPE_3D, "3d"},
846 {VK_IMAGE_VIEW_TYPE_CUBE, "cube"},
847 {VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array"}};
848
849 de::MovePtr<tcu::TestCaseGroup> imageViewTypeTests(new tcu::TestCaseGroup(testCtx, "view_type"));
850
851 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
852 {
853 const VkImageViewType viewType = imageViewTypes[viewTypeNdx].type;
854 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup(
855 new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name));
856 de::MovePtr<tcu::TestCaseGroup> formatTests =
857 createImageFormatTests(testCtx, allocationKind, pipelineConstructionType, samplingType, viewType);
858
859 viewTypeGroup->addChild(formatTests.release());
860 imageViewTypeTests->addChild(viewTypeGroup.release());
861 }
862
863 return imageViewTypeTests;
864 }
865
createImageSamplingTypeTests(tcu::TestContext & testCtx,AllocationKind allocationKind,PipelineConstructionType pipelineConstructionType)866 de::MovePtr<tcu::TestCaseGroup> createImageSamplingTypeTests(tcu::TestContext &testCtx, AllocationKind allocationKind,
867 PipelineConstructionType pipelineConstructionType)
868 {
869 VkDescriptorType samplingTypes[] = {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE};
870
871 de::MovePtr<tcu::TestCaseGroup> imageSamplingTypeTests(new tcu::TestCaseGroup(testCtx, "sampling_type"));
872
873 for (int smpTypeNdx = 0; smpTypeNdx < DE_LENGTH_OF_ARRAY(samplingTypes); smpTypeNdx++)
874 {
875 const char *smpTypeName =
876 samplingTypes[smpTypeNdx] == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? "combined" : "separate";
877 de::MovePtr<tcu::TestCaseGroup> samplingTypeGroup(new tcu::TestCaseGroup(testCtx, smpTypeName));
878 de::MovePtr<tcu::TestCaseGroup> viewTypeTests =
879 createImageViewTypeTests(testCtx, allocationKind, pipelineConstructionType, samplingTypes[smpTypeNdx]);
880
881 samplingTypeGroup->addChild(viewTypeTests.release());
882 imageSamplingTypeTests->addChild(samplingTypeGroup.release());
883 }
884
885 return imageSamplingTypeTests;
886 }
887
createSuballocationTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)888 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext &testCtx,
889 PipelineConstructionType pipelineConstructionType)
890 {
891 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation"));
892 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests =
893 createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_SUBALLOCATED, pipelineConstructionType);
894
895 suballocationTestsGroup->addChild(samplingTypeTests.release());
896
897 return suballocationTestsGroup;
898 }
899
createDedicatedAllocationTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)900 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext &testCtx,
901 PipelineConstructionType pipelineConstructionType)
902 {
903 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(
904 new tcu::TestCaseGroup(testCtx, "dedicated_allocation"));
905 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests =
906 createImageSamplingTypeTests(testCtx, ALLOCATION_KIND_DEDICATED, pipelineConstructionType);
907
908 dedicatedAllocationTestsGroup->addChild(samplingTypeTests.release());
909
910 return dedicatedAllocationTestsGroup;
911 }
912 } // namespace
913
createImageTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)914 tcu::TestCaseGroup *createImageTests(tcu::TestContext &testCtx, PipelineConstructionType pipelineConstructionType)
915 {
916 de::MovePtr<tcu::TestCaseGroup> imageTests(new tcu::TestCaseGroup(testCtx, "image"));
917 de::MovePtr<tcu::TestCaseGroup> imageSuballocationTests =
918 createSuballocationTests(testCtx, pipelineConstructionType);
919 de::MovePtr<tcu::TestCaseGroup> imageDedicatedAllocationTests =
920 createDedicatedAllocationTests(testCtx, pipelineConstructionType);
921
922 imageTests->addChild(imageSuballocationTests.release());
923 imageTests->addChild(imageDedicatedAllocationTests.release());
924
925 return imageTests.release();
926 }
927
928 } // namespace pipeline
929 } // namespace vkt
930