xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/image/vktImageMismatchedFormatsTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
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 Testing writing and reading for mismatched formats
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktImageLoadStoreTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktImageTestsUtil.hpp"
28 #include "vktImageLoadStoreUtil.hpp"
29 #include "vktImageTexture.hpp"
30 
31 #include "vkDefs.hpp"
32 #include "vkRef.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkBarrierUtil.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
43 #include "vkImageWithMemory.hpp"
44 
45 #include "deMath.h"
46 #include "deUniquePtr.hpp"
47 #include "deSharedPtr.hpp"
48 #include "deStringUtil.hpp"
49 
50 #include "tcuImageCompare.hpp"
51 #include "tcuTexture.hpp"
52 #include "tcuTextureUtil.hpp"
53 #include "tcuFloat.hpp"
54 #include "tcuStringTemplate.hpp"
55 
56 #include <string>
57 #include <vector>
58 #include <map>
59 
60 using namespace vk;
61 
62 namespace vkt
63 {
64 namespace image
65 {
66 namespace
67 {
68 
69 struct FormatInfo
70 {
71     const char *GLSLFormat;
72     int VectorWidth;
73     int BytesPerPixel;
74     tcu::TextureChannelClass ChannelClass;
75 };
76 
getFormatInfo(VkFormat format)77 FormatInfo getFormatInfo(VkFormat format)
78 {
79     FormatInfo result;
80 
81     const tcu::TextureFormat texFormat = mapVkFormat(format);
82 
83     result.VectorWidth   = getNumUsedChannels(texFormat.order);
84     result.BytesPerPixel = getPixelSize(texFormat);
85     result.ChannelClass  = tcu::getTextureChannelClass(texFormat.type);
86 
87     return result;
88 }
89 
ChannelClassToImageType(tcu::TextureChannelClass channelClass)90 std::string ChannelClassToImageType(tcu::TextureChannelClass channelClass)
91 {
92     switch (channelClass)
93     {
94     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
95         return "uimage2D";
96     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
97         return "iimage2D";
98     default:
99         return "image2D";
100     }
101 }
102 
ChannelClassToVecType(tcu::TextureChannelClass channelClass)103 std::string ChannelClassToVecType(tcu::TextureChannelClass channelClass)
104 {
105     switch (channelClass)
106     {
107     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
108         return "uvec4";
109     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
110         return "ivec4";
111     default:
112         return "vec4";
113     }
114 }
115 
ChannelClassToDefaultVecValue(tcu::TextureChannelClass channelClass)116 std::string ChannelClassToDefaultVecValue(tcu::TextureChannelClass channelClass)
117 {
118     switch (channelClass)
119     {
120     case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
121         return "uvec4(1, 10, 100, 1000)";
122     case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
123         return "ivec4(-1, 2, -1000, 2000)";
124     default:
125         return "vec4(0.25, 0.5, 0.0, 1.0)";
126     }
127 }
128 
129 const std::map<std::string, FormatInfo> SpirvFormats{
130     {"Rgba32f", {nullptr, 4, 16, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
131     {"Rg32f", {nullptr, 2, 8, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
132     {"R32f", {nullptr, 1, 4, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
133     {"Rgba16f", {nullptr, 4, 8, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
134     {"Rg16f", {nullptr, 2, 4, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
135     {"R16f", {nullptr, 1, 2, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
136     {"Rgba16", {nullptr, 4, 8, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
137     {"Rg16", {nullptr, 2, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
138     {"R16", {nullptr, 1, 2, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
139     {"Rgba16Snorm", {"rgba16_snorm", 4, 8, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
140     {"Rg16Snorm", {"rg16_snorm", 2, 4, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
141     {"R16Snorm", {"r16_snorm", 1, 2, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
142     {"Rgb10A2", {"rgb10_a2", 4, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
143     {"R11fG11fB10f", {"r11f_g11f_b10f", 3, 4, tcu::TEXTURECHANNELCLASS_FLOATING_POINT}},
144     {"Rgba8", {nullptr, 4, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
145     {"Rg8", {nullptr, 2, 2, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
146     {"R8", {nullptr, 1, 1, tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT}},
147     {"Rgba8Snorm", {"rgba8_snorm", 4, 4, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
148     {"Rg8Snorm", {"rg8_snorm", 2, 2, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
149     {"R8Snorm", {"r8_snorm", 1, 1, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT}},
150     {"Rgba32i", {nullptr, 4, 16, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
151     {"Rg32i", {nullptr, 2, 2, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
152     {"R32i", {nullptr, 1, 1, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
153     {"Rgba16i", {nullptr, 4, 8, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
154     {"Rg16i", {nullptr, 2, 4, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
155     {"R16i", {nullptr, 1, 2, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
156     {"Rgba8i", {nullptr, 4, 4, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
157     {"Rg8i", {nullptr, 2, 2, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
158     {"R8i", {nullptr, 1, 1, tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER}},
159     {"Rgba32ui", {nullptr, 4, 16, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
160     {"Rg32ui", {nullptr, 2, 8, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
161     {"R32ui", {nullptr, 1, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
162     {"Rgba16ui", {nullptr, 4, 8, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
163     {"Rg16ui", {nullptr, 2, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
164     {"R16ui", {nullptr, 1, 2, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
165     {"Rgb10a2ui", {"rgb10_a2ui", 4, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
166     {"Rgba8ui", {nullptr, 4, 4, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
167     {"Rg8ui", {nullptr, 2, 2, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}},
168     {"R8ui", {nullptr, 1, 1, tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER}}};
169 
getFormatInfo(const std::string & spirvFormat)170 FormatInfo getFormatInfo(const std::string &spirvFormat)
171 {
172     auto it = SpirvFormats.find(spirvFormat);
173     if (it != SpirvFormats.end())
174         return it->second;
175     else
176         return {"", 0, 0, tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT};
177 }
178 
matching(VkFormat format,const std::string & spirvFormat)179 bool matching(VkFormat format, const std::string &spirvFormat)
180 {
181     try
182     {
183         FormatInfo baseFormat   = getFormatInfo(format);
184         FormatInfo shaderFormat = getFormatInfo(spirvFormat);
185 
186         return (baseFormat.VectorWidth == shaderFormat.VectorWidth &&
187                 baseFormat.BytesPerPixel == shaderFormat.BytesPerPixel &&
188                 baseFormat.ChannelClass == shaderFormat.ChannelClass);
189     }
190     catch (const tcu::InternalError &)
191     {
192         return false;
193     }
194 }
195 
196 enum class TestType
197 {
198     READ = 0,
199     SPARSE_READ,
200     WRITE
201 };
202 
fillImageCreateInfo(VkImageCreateInfo & imageCreateInfo,TestType testType,VkFormat format)203 void fillImageCreateInfo(VkImageCreateInfo &imageCreateInfo, TestType testType, VkFormat format)
204 {
205     const VkImageCreateFlags imageFlags =
206         ((testType == TestType::SPARSE_READ) ?
207              (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) :
208              0u);
209     const VkImageCreateInfo createInfo = {
210         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
211         nullptr,                             // const void* pNext;
212         imageFlags,                          // VkImageCreateFlags flags;
213         VK_IMAGE_TYPE_2D,                    // VkImageType imageType;
214         format,                              // VkFormat format;
215         makeExtent3D(8, 8, 1),               // VkExtent3D extent;
216         1u,                                  // uint32_t mipLevels;
217         1u,                                  // uint32_t arrayLayers;
218         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
219         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
220         VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
221             VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
222         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
223         0u,                                  // uint32_t queueFamilyIndexCount;
224         nullptr,                             // const uint32_t* pQueueFamilyIndices;
225         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
226     };
227 
228     imageCreateInfo = createInfo;
229 }
230 
231 class MismatchedFormatTest : public TestCase
232 {
233 public:
234     MismatchedFormatTest(tcu::TestContext &testCtx, const std::string &name, const TestType type, const VkFormat format,
235                          const std::string &spirvFormat);
236 
237     virtual void checkSupport(Context &context) const;
238     void initPrograms(SourceCollections &programCollection) const;
239     TestInstance *createInstance(Context &context) const;
240 
241 private:
242     const TestType m_type;
243     const VkFormat m_format;
244     const std::string m_spirvFormat;
245 };
246 
MismatchedFormatTest(tcu::TestContext & testCtx,const std::string & name,const TestType type,const VkFormat format,const std::string & spirvFormat)247 MismatchedFormatTest::MismatchedFormatTest(tcu::TestContext &testCtx, const std::string &name, const TestType type,
248                                            const VkFormat format, const std::string &spirvFormat)
249     : TestCase(testCtx, name)
250     , m_type(type)
251     , m_format(format)
252     , m_spirvFormat(spirvFormat)
253 {
254 }
255 
checkSupport(Context & context) const256 void MismatchedFormatTest::checkSupport(Context &context) const
257 {
258     const auto &vki           = context.getInstanceInterface();
259     const auto physicalDevice = context.getPhysicalDevice();
260 
261 #ifndef CTS_USES_VULKANSC
262     if (m_type == TestType::SPARSE_READ)
263     {
264         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
265 
266         if (!getPhysicalDeviceFeatures(vki, physicalDevice).sparseResidencyBuffer)
267             TCU_THROW(NotSupportedError, "Sparse partially resident buffers not supported");
268 
269         // Check sparse operations support before creating the image.
270         VkImageCreateInfo imageCreateInfo;
271         fillImageCreateInfo(imageCreateInfo, m_type, m_format);
272 
273         if (!checkSparseImageFormatSupport(physicalDevice, vki, imageCreateInfo))
274         {
275             TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
276         }
277 
278         if (!getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice())
279                  .shaderResourceResidency)
280         {
281             TCU_THROW(NotSupportedError, "Shader resource residency not supported");
282         }
283     }
284 #endif // CTS_USES_VULKANSC
285 
286     VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, m_format);
287 
288     if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
289     {
290         TCU_THROW(NotSupportedError, "Creating storage image with this format is not supported");
291     }
292 }
293 
initPrograms(SourceCollections & programCollection) const294 void MismatchedFormatTest::initPrograms(SourceCollections &programCollection) const
295 {
296     std::string source;
297 
298     if (m_type == TestType::READ)
299     {
300         source = R"(
301             #version 460 core
302 
303             layout (${FORMAT}, binding=0) uniform ${IMAGE} inputImage;
304 
305             void main()
306             {
307                 ${VECT} value = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.xy));
308             }
309         )";
310     }
311     else if (m_type == TestType::WRITE)
312     {
313         source = R"(
314             #version 460 core
315 
316             layout (${FORMAT}, binding=0) uniform ${IMAGE} inputImage;
317 
318             void main()
319             {
320                 imageStore(inputImage, ivec2(gl_GlobalInvocationID.xy), ${VALUE});
321             }
322         )";
323     }
324     else if (m_type == TestType::SPARSE_READ)
325     {
326         source = R"(
327             #version 460 core
328             #extension GL_ARB_sparse_texture2 : require
329 
330             layout (${FORMAT}, binding=0) uniform ${IMAGE} inputImage;
331 
332             void main()
333             {
334                 ${VECT} result;
335                 int r = sparseImageLoadARB(inputImage, ivec2(gl_GlobalInvocationID.xy), result);
336             }
337         )";
338     }
339 
340     const FormatInfo spirvFormatInfo = getFormatInfo(m_spirvFormat);
341 
342     const std::string glslFormat = spirvFormatInfo.GLSLFormat ? spirvFormatInfo.GLSLFormat : de::toLower(m_spirvFormat);
343 
344     std::map<std::string, std::string> specializations;
345 
346     specializations["FORMAT"] = glslFormat;
347     specializations["VECT"]   = ChannelClassToVecType(spirvFormatInfo.ChannelClass);
348     specializations["IMAGE"]  = ChannelClassToImageType(spirvFormatInfo.ChannelClass);
349     specializations["VALUE"]  = ChannelClassToDefaultVecValue(spirvFormatInfo.ChannelClass);
350 
351     programCollection.glslSources.add("comp")
352         << glu::ComputeSource(tcu::StringTemplate{source}.specialize(specializations));
353 }
354 
355 class MismatchedFormatTestInstance : public TestInstance
356 {
357 public:
358     MismatchedFormatTestInstance(Context &context, const TestType type, const VkFormat format,
359                                  const std::string &spirvFormat);
360 
361     tcu::TestStatus iterate(void);
362 
363 protected:
364     const TestType m_type;
365     const VkFormat m_format;
366     const std::string m_spirvFormat;
367 };
368 
MismatchedFormatTestInstance(Context & context,const TestType type,const VkFormat format,const std::string & spirvFormat)369 MismatchedFormatTestInstance::MismatchedFormatTestInstance(Context &context, const TestType type, const VkFormat format,
370                                                            const std::string &spirvFormat)
371     : TestInstance(context)
372     , m_type(type)
373     , m_format(format)
374     , m_spirvFormat(spirvFormat)
375 {
376 }
377 
iterate(void)378 tcu::TestStatus MismatchedFormatTestInstance::iterate(void)
379 {
380     const DeviceInterface &vk       = m_context.getDeviceInterface();
381     const VkDevice device           = m_context.getDevice();
382     const VkQueue queue             = m_context.getUniversalQueue();
383     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
384     auto &allocator                 = m_context.getDefaultAllocator();
385 #ifndef CTS_USES_VULKANSC
386     const auto physicalDevice = m_context.getPhysicalDevice();
387     const auto &instance      = m_context.getInstanceInterface();
388 #endif // CTS_USES_VULKANSC
389 
390     Move<VkShaderModule> shaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0);
391 
392     Move<VkDescriptorSetLayout> descriptorSetLayout =
393         DescriptorSetLayoutBuilder()
394             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
395             .build(vk, device);
396     Move<VkDescriptorPool> descriptorPool =
397         DescriptorPoolBuilder()
398             .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
399             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
400 
401     Move<VkDescriptorSet> descriptorSet   = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
402     Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
403 
404     Move<VkPipeline> pipeline = makeComputePipeline(vk, device, *pipelineLayout, *shaderModule);
405 
406     VkImageCreateInfo imageCreateInfo;
407     fillImageCreateInfo(imageCreateInfo, m_type, m_format);
408 
409     vk::Move<vk::VkImage> storageImage = createImage(vk, device, &imageCreateInfo);
410     const auto tcuFormat               = mapVkFormat(m_format);
411 
412     de::MovePtr<vk::Allocation> storageAllocation;
413     vk::Move<vk::VkSemaphore> bindSemaphore;
414     std::vector<de::SharedPtr<Allocation>> allocations;
415 
416     if (m_type == TestType::SPARSE_READ)
417     {
418         bindSemaphore = createSemaphore(vk, device);
419 #ifndef CTS_USES_VULKANSC
420         allocateAndBindSparseImage(vk, device, physicalDevice, instance, imageCreateInfo, *bindSemaphore,
421                                    m_context.getSparseQueue(), allocator, allocations, tcuFormat, *storageImage);
422 #endif // CTS_USES_VULKANSC
423     }
424     else
425     {
426         storageAllocation =
427             allocator.allocate(getImageMemoryRequirements(vk, device, *storageImage), MemoryRequirement::Any);
428         VK_CHECK(
429             vk.bindImageMemory(device, *storageImage, storageAllocation->getMemory(), storageAllocation->getOffset()));
430     }
431 
432     const auto subresourceRange = makeImageSubresourceRange(getImageAspectFlags(tcuFormat), 0u, 1u, 0u, 1u);
433     Move<VkImageView> storageImageView =
434         makeImageView(vk, device, *storageImage, VK_IMAGE_VIEW_TYPE_2D, m_format, subresourceRange);
435     VkDescriptorImageInfo storageImageInfo =
436         makeDescriptorImageInfo(DE_NULL, *storageImageView, VK_IMAGE_LAYOUT_GENERAL);
437 
438     DescriptorSetUpdateBuilder builder;
439     builder
440         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
441                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &storageImageInfo)
442         .update(vk, device);
443 
444     Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
445     Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
446 
447     const auto layoutBarrier =
448         makeImageMemoryBarrier(0u, (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT), VK_IMAGE_LAYOUT_UNDEFINED,
449                                VK_IMAGE_LAYOUT_GENERAL, *storageImage, subresourceRange);
450 
451     beginCommandBuffer(vk, *cmdBuffer);
452     vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u,
453                           nullptr, 0u, nullptr, 1u, &layoutBarrier);
454     vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
455     vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(),
456                              0u, DE_NULL);
457     vk.cmdDispatch(*cmdBuffer, 8, 8, 1);
458     endCommandBuffer(vk, *cmdBuffer);
459 
460     if (m_type == TestType::SPARSE_READ)
461     {
462         const VkPipelineStageFlags stageBits[] = {VK_PIPELINE_STAGE_TRANSFER_BIT};
463         submitCommandsAndWait(vk, device, queue, *cmdBuffer, false, 1u, 1u, &bindSemaphore.get(), stageBits);
464     }
465     else
466         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
467 
468     return tcu::TestStatus::pass("Passed");
469 }
470 
createInstance(Context & context) const471 TestInstance *MismatchedFormatTest::createInstance(Context &context) const
472 {
473     return new MismatchedFormatTestInstance(context, m_type, m_format, m_spirvFormat);
474 }
475 
476 } // namespace
477 
createImageMismatchedFormatsTests(tcu::TestContext & testCtx)478 tcu::TestCaseGroup *createImageMismatchedFormatsTests(tcu::TestContext &testCtx)
479 {
480     // Test image load/store operations on mismatched formats
481     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "mismatched_formats"));
482     // perform OpImageRead
483     de::MovePtr<tcu::TestCaseGroup> testGroupOpRead(new tcu::TestCaseGroup(testCtx, "image_read"));
484     de::MovePtr<tcu::TestCaseGroup> testGroupOpWrite(new tcu::TestCaseGroup(testCtx, "image_write"));
485 #ifndef CTS_USES_VULKANSC
486     de::MovePtr<tcu::TestCaseGroup> testGroupOpSparseRead(new tcu::TestCaseGroup(testCtx, "sparse_image_read"));
487 #endif // CTS_USES_VULKANSC
488 
489     for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8; format < VK_CORE_FORMAT_LAST;
490          format          = static_cast<VkFormat>(format + 1))
491     {
492         if (isCompressedFormat(format))
493             continue;
494 
495         for (auto &pair : SpirvFormats)
496         {
497             const std::string &spirvFormat = pair.first;
498 
499             if (matching(format, spirvFormat))
500             {
501                 const std::string enumName = getFormatName(format);
502                 const std::string testName = de::toLower(enumName.substr(10) + "_with_" + spirvFormat);
503 
504                 testGroupOpRead->addChild(
505                     new MismatchedFormatTest(testCtx, testName, TestType::READ, format, spirvFormat));
506 
507                 testGroupOpWrite->addChild(
508                     new MismatchedFormatTest(testCtx, testName, TestType::WRITE, format, spirvFormat));
509 #ifndef CTS_USES_VULKANSC
510                 testGroupOpSparseRead->addChild(
511                     new MismatchedFormatTest(testCtx, testName, TestType::SPARSE_READ, format, spirvFormat));
512 #endif // CTS_USES_VULKANSC
513             }
514         }
515     }
516 
517     testGroup->addChild(testGroupOpRead.release());
518     testGroup->addChild(testGroupOpWrite.release());
519 #ifndef CTS_USES_VULKANSC
520     testGroup->addChild(testGroupOpSparseRead.release());
521 #endif // CTS_USES_VULKANSC
522 
523     return testGroup.release();
524 }
525 
526 } // namespace image
527 } // namespace vkt
528