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