Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / image / vktImageAstcDecodeModeTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file  vktImageAstcDecodeModeTests.cpp
21  * \brief Astc decode mode tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktImageAstcDecodeModeTests.hpp"
25 #include "vktImageLoadStoreUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vkBarrierUtil.hpp"
29 #include "vkBuilderUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkBufferWithMemory.hpp"
34
35 #include "tcuAstcUtil.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuTexture.hpp"
38 #include "tcuCompressedTexture.hpp"
39 #include "tcuImageCompare.hpp"
40
41 #include "deRandom.hpp"
42 #include <vector>
43
44 using namespace vk;
45 namespace vkt
46 {
47 namespace image
48 {
49 namespace
50 {
51 using std::string;
52 using std::vector;
53 using tcu::TestContext;
54 using tcu::TestStatus;
55 using tcu::UVec3;
56 using tcu::IVec3;
57 using tcu::CompressedTexFormat;
58 using tcu::CompressedTexture;
59 using de::MovePtr;
60 using de::SharedPtr;
61 using de::Random;
62
63 struct TestParameters
64 {
65         ImageType                       imageType;
66         UVec3                           imageSize;
67
68         VkFormat                        testedFormat;
69         deBool                          testedIsUnorm;
70         VkFormat                        testedDecodeMode;
71         VkImageUsageFlags       testedImageUsage;
72
73         VkFormat                        resultFormat;
74         VkImageUsageFlags       resultImageUsage;
75 };
76
77 class BasicComputeTestInstance : public TestInstance
78 {
79 public:
80                                         BasicComputeTestInstance        (Context&                                       context,
81                                                                                                  const TestParameters&          parameters);
82
83         TestStatus              iterate                                         (void);
84
85 protected:
86
87         const TestParameters    m_parameters;
88 };
89
90 BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
91         : TestInstance  (context)
92         , m_parameters  (parameters)
93 {
94 }
95
96 TestStatus BasicComputeTestInstance::iterate (void)
97 {
98         Allocator&                                              allocator                       = m_context.getDefaultAllocator();
99         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
100         const VkDevice                                  device                          = m_context.getDevice();
101         const VkQueue                                   queue                           = m_context.getUniversalQueue();
102         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
103         const VkImageType                               imageType                       = mapImageType(m_parameters.imageType);
104         const VkExtent3D                                extentCompressed        = makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize));
105         const VkExtent3D                                extentUnCompressed      = makeExtent3D(m_parameters.imageSize);
106         const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
107         const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
108         const Unique<VkShaderModule>    shaderModule            (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
109
110         const VkImageCreateInfo compressedImageInfo =
111         {
112                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType;
113                 DE_NULL,                                                                                                // const void*                          pNext;
114                 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
115                 VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,                // VkImageCreateFlags           flags;
116                 imageType,                                                                                              // VkImageType                          imageType;
117                 m_parameters.testedFormat,                                                              // VkFormat                                     format;
118                 extentCompressed,                                                                               // VkExtent3D                           extent;
119                 1u,                                                                                                             // deUint32                                     mipLevels;
120                 1u,                                                                                                             // deUint32                                     arrayLayers;
121                 VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits        samples;
122                 VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling;
123                 VK_IMAGE_USAGE_SAMPLED_BIT |
124                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,                                                // VkImageUsageFlags            usage;
125                 VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                        sharingMode;
126                 0u,                                                                                                             // deUint32                                     queueFamilyIndexCount;
127                 DE_NULL,                                                                                                // const deUint32*                      pQueueFamilyIndices;
128                 VK_IMAGE_LAYOUT_UNDEFINED,                                                              // VkImageLayout                        initialLayout;
129         };
130
131         const VkImageCreateInfo resultImageInfo =
132         {
133                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType;
134                 DE_NULL,                                                                                                // const void*                          pNext;
135                 0u,                                                                                                             // VkImageCreateFlags           flags;
136                 imageType,                                                                                              // VkImageType                          imageType;
137                 m_parameters.resultFormat,                                                              // VkFormat                                     format;
138                 extentUnCompressed,                                                                             // VkExtent3D                           extent;
139                 1u,                                                                                                             // deUint32                                     mipLevels;
140                 1u,                                                                                                             // deUint32                                     arrayLayers;
141                 VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits        samples;
142                 VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling;
143                 VK_IMAGE_USAGE_SAMPLED_BIT |
144                 VK_IMAGE_USAGE_STORAGE_BIT |
145                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
146                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,                                                // VkImageUsageFlags            usage;
147                 VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                        sharingMode;
148                 0u,                                                                                                             // deUint32                                     queueFamilyIndexCount;
149                 DE_NULL,                                                                                                // const deUint32*                      pQueueFamilyIndices;
150                 VK_IMAGE_LAYOUT_UNDEFINED,                                                              // VkImageLayout                        initialLayout;
151         };
152
153         // create images
154         Image                                                   testedImage                             (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
155         Image                                                   referenceImage                  (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
156         Image                                                   resultImage                             (vk, device, allocator, resultImageInfo, MemoryRequirement::Any);
157
158         // create image views
159         const VkImageViewType                   imageViewType                   (mapImageViewType(m_parameters.imageType));
160         VkImageSubresourceRange                 subresourceRange                = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
161
162         VkImageViewASTCDecodeModeEXT decodeMode =
163         {
164                 VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
165                 DE_NULL,
166                 m_parameters.testedDecodeMode
167         };
168
169         const VkImageViewCreateInfo imageViewParams =
170         {
171                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
172                 &decodeMode,                                                                    // const void*                          pNext;
173                 0u,                                                                                             // VkImageViewCreateFlags       flags;
174                 testedImage.get(),                                                              // VkImage                                      image;
175                 imageViewType,                                                                  // VkImageViewType                      viewType;
176                 m_parameters.testedFormat,                                              // VkFormat                                     format;
177                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
178                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
179         };
180
181         Move<VkImageView>                               testedView                              = createImageView(vk, device, &imageViewParams);
182         Move<VkImageView>                               referenceView                   = makeImageView(vk, device, referenceImage.get(), imageViewType, m_parameters.testedFormat, subresourceRange);
183         Move<VkImageView>                               resultView                              = makeImageView(vk, device, resultImage.get(), imageViewType, m_parameters.resultFormat,
184                                                                                                                                 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, resultImageInfo.extent.depth, 0u, resultImageInfo.arrayLayers));
185
186         Move<VkDescriptorSetLayout>             descriptorSetLayout             = DescriptorSetLayoutBuilder()
187                                                                                                                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
188                                                                                                                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
189                                                                                                                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
190                                                                                                                                 .build(vk, device);
191         Move<VkDescriptorPool>                  descriptorPool                  = DescriptorPoolBuilder()
192                                                                                                                                 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
193                                                                                                                                 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
194                                                                                                                                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, resultImageInfo.arrayLayers)
195                                                                                                                                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, resultImageInfo.arrayLayers);
196
197         Move<VkDescriptorSet>                   descriptorSet                   = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
198         const Unique<VkPipelineLayout>  pipelineLayout                  (makePipelineLayout(vk, device, *descriptorSetLayout));
199         const Unique<VkPipeline>                pipeline                                (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
200
201         const VkDeviceSize                              bufferSizeCompresed             = getCompressedImageSizeInBytes(m_parameters.testedFormat, m_parameters.imageSize);
202         const VkDeviceSize                              bufferSizeUncompressed  = getImageSizeBytes(IVec3((int)extentUnCompressed.width, (int)extentUnCompressed.height, (int)extentUnCompressed.depth), m_parameters.resultFormat);
203         VkBufferCreateInfo                              compressedBufferCI              = makeBufferCreateInfo(bufferSizeCompresed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
204         VkBufferCreateInfo                              uncompressedBufferCI    = makeBufferCreateInfo(bufferSizeUncompressed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
205         BufferWithMemory                                inBuffer                                (vk, device, allocator, compressedBufferCI, MemoryRequirement::HostVisible);
206         BufferWithMemory                                resultBuffer                    (vk, device, allocator, uncompressedBufferCI, MemoryRequirement::HostVisible);
207         Move<VkSampler>                                 sampler;
208
209         // generate data for compressed image and copy it to in buffer
210         {
211                 vector<deUint8> generatedData;
212                 generatedData.resize(static_cast<size_t>(bufferSizeCompresed));
213
214                 auto blocks = getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize);
215                 tcu::astc::generateRandomValidBlocks(generatedData.data(),
216                                                                                 blocks.x() * blocks.y() * blocks.z(),
217                                                                                 mapVkCompressedFormat(m_parameters.testedFormat),
218                                                                                 tcu::TexDecompressionParams::ASTCMODE_LDR,
219                                                                                 1);
220
221                 const Allocation& alloc = inBuffer.getAllocation();
222                 deMemcpy(alloc.getHostPtr(), generatedData.data(), generatedData.size());
223                 flushAlloc(vk, device, alloc);
224         }
225
226         {
227                 const VkSamplerCreateInfo createInfo    =
228                 {
229                         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                  //VkStructureType               sType;
230                         DE_NULL,                                                                                //const void*                   pNext;
231                         0u,                                                                                             //VkSamplerCreateFlags  flags;
232                         VK_FILTER_NEAREST,                                                              //VkFilter                              magFilter;
233                         VK_FILTER_NEAREST,                                                              //VkFilter                              minFilter;
234                         VK_SAMPLER_MIPMAP_MODE_NEAREST,                                 //VkSamplerMipmapMode   mipmapMode;
235                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  //VkSamplerAddressMode  addressModeU;
236                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  //VkSamplerAddressMode  addressModeV;
237                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  //VkSamplerAddressMode  addressModeW;
238                         0.0f,                                                                                   //float                                 mipLodBias;
239                         VK_FALSE,                                                                               //VkBool32                              anisotropyEnable;
240                         1.0f,                                                                                   //float                                 maxAnisotropy;
241                         VK_FALSE,                                                                               //VkBool32                              compareEnable;
242                         VK_COMPARE_OP_EQUAL,                                                    //VkCompareOp                   compareOp;
243                         0.0f,                                                                                   //float                                 minLod;
244                         1.0f,                                                                                   //float                                 maxLod;
245                         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,                //VkBorderColor                 borderColor;
246                         VK_FALSE,                                                                               //VkBool32                              unnormalizedCoordinates;
247                 };
248                 sampler = createSampler(vk, device, &createInfo);
249         }
250
251         VkDescriptorImageInfo descriptorImageInfos[] =
252         {
253                 makeDescriptorImageInfo(*sampler,       *testedView,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
254                 makeDescriptorImageInfo(*sampler,       *referenceView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
255                 makeDescriptorImageInfo(DE_NULL,        *resultView,    VK_IMAGE_LAYOUT_GENERAL),
256         };
257         DescriptorSetUpdateBuilder()
258                 .writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[0])
259                 .writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfos[1])
260                 .writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[2])
261                 .update(vk, device);
262
263         beginCommandBuffer(vk, *cmdBuffer);
264         {
265                 // copy input buffer to tested and reference images
266                 {
267                         Image* inImages[] = { &testedImage, &referenceImage };
268                         for (Image* image : inImages)
269                         {
270                                 const VkImageMemoryBarrier preCopyImageBarrier = makeImageMemoryBarrier(
271                                         0u, VK_ACCESS_TRANSFER_WRITE_BIT,
272                                         VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
273                                         image->get(), subresourceRange);
274
275                                 const VkBufferMemoryBarrier flushHostCopyBarrier = makeBufferMemoryBarrier(
276                                         VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
277                                         inBuffer.get(), 0ull, bufferSizeCompresed);
278
279                                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
280                                         (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 1u, &flushHostCopyBarrier, 1u, &preCopyImageBarrier);
281
282                                 const VkBufferImageCopy copyRegion =
283                                 {
284                                         0ull,                                                                                                                                                   //VkDeviceSize                          bufferOffset;
285                                         0u,                                                                                                                                                             //deUint32                                      bufferRowLength;
286                                         0u,                                                                                                                                                             //deUint32                                      bufferImageHeight;
287                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),                              //VkImageSubresourceLayers      imageSubresource;
288                                         makeOffset3D(0, 0, 0),                                                                                                                  //VkOffset3D                            imageOffset;
289                                         extentCompressed,                                                                                                                               //VkExtent3D                            imageExtent;
290                                 };
291
292                                 vk.cmdCopyBufferToImage(*cmdBuffer, inBuffer.get(), image->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
293                         }
294                 }
295
296                 // bind pipeline and descriptors
297                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
298                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
299
300                 {
301                         const VkImageMemoryBarrier preShaderImageBarriers[] =
302                         {
303                                 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
304                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
305                                         testedImage.get(), subresourceRange),
306
307                                 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
308                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
309                                         referenceImage.get(), subresourceRange),
310
311                                 makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT,
312                                         VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
313                                         resultImage.get(), subresourceRange)
314                         };
315
316                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
317                                 (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
318                                 DE_LENGTH_OF_ARRAY(preShaderImageBarriers), preShaderImageBarriers);
319                 }
320
321                 vk.cmdDispatch(*cmdBuffer, extentUnCompressed.width, extentUnCompressed.height, extentUnCompressed.depth);
322
323                 {
324                         const VkImageMemoryBarrier postShaderImageBarriers[] =
325                         {
326                                 makeImageMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
327                                         VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
328                                         resultImage.get(), subresourceRange)
329                         };
330
331                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
332                                 (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, 0u, (const VkBufferMemoryBarrier*)DE_NULL,
333                                 DE_LENGTH_OF_ARRAY(postShaderImageBarriers), postShaderImageBarriers);
334                 }
335
336                 const VkBufferImageCopy copyRegion =
337                 {
338                         0ull,                                                                                                                           //      VkDeviceSize                            bufferOffset;
339                         0u,                                                                                                                                     //      deUint32                                        bufferRowLength;
340                         0u,                                                                                                                                     //      deUint32                                        bufferImageHeight;
341                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),      //      VkImageSubresourceLayers        imageSubresource;
342                         makeOffset3D(0, 0, 0),                                                                                          //      VkOffset3D                                      imageOffset;
343                         resultImageInfo.extent,                                                                                         //      VkExtent3D                                      imageExtent;
344                 };
345                 vk.cmdCopyImageToBuffer(*cmdBuffer, resultImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, resultBuffer.get(), 1u, &copyRegion);
346
347                 {
348                         const VkBufferMemoryBarrier postCopyBufferBarrier[] =
349                         {
350                                 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
351                                         resultBuffer.get(), 0ull, bufferSizeUncompressed),
352                         };
353
354                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
355                                 (VkDependencyFlags)0, 0u, (const VkMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBufferBarrier), postCopyBufferBarrier,
356                                 0u, (const VkImageMemoryBarrier*)DE_NULL);
357                 }
358         }
359         endCommandBuffer(vk, *cmdBuffer);
360         submitCommandsAndWait(vk, device, queue, *cmdBuffer);
361
362         const Allocation& resultAlloc = resultBuffer.getAllocation();
363         invalidateAlloc(vk, device, resultAlloc);
364
365         // verification is done in shader - here we just check if one of pixels has wrong value
366         const size_t    numBytes                = static_cast<size_t>(bufferSizeUncompressed);
367         deUint8*                result          = static_cast<deUint8*>(resultAlloc.getHostPtr());
368         for (size_t i = 0 ; i < numBytes ; i += 4)
369         {
370                 // expected result should be around 128 (if reference is same as tested mode then we return 0.5)
371                 if ((result[i] < 100) || (result[i] > 150))
372                         return TestStatus::fail("Fail");
373         }
374
375         return TestStatus::pass("Pass");
376 }
377
378 class AstcDecodeModeCase : public TestCase
379 {
380 public:
381                                         AstcDecodeModeCase      (TestContext&                   testCtx,
382                                                                                  const std::string&             name,
383                                                                                  const std::string&             desc,
384                                                                                  const TestParameters&  parameters);
385         virtual void    checkSupport            (Context&                               context) const;
386         void                    initPrograms            (SourceCollections&             programCollection) const;
387         TestInstance*   createInstance          (Context&                               context) const;
388
389 protected:
390
391         const TestParameters m_parameters;
392 };
393
394 AstcDecodeModeCase::AstcDecodeModeCase (TestContext&                    testCtx,
395                                                                                 const std::string&              name,
396                                                                                 const std::string&              desc,
397                                                                                 const TestParameters&   parameters)
398         : TestCase              (testCtx, name, desc)
399         , m_parameters  (parameters)
400 {
401 }
402
403 void AstcDecodeModeCase::checkSupport (Context& context) const
404 {
405         const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
406         const InstanceInterface&        vk                              = context.getInstanceInterface();
407
408         context.requireDeviceFunctionality("VK_EXT_astc_decode_mode");
409         if (!getPhysicalDeviceFeatures(vk, physicalDevice).textureCompressionASTC_LDR)
410                 TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
411
412         VkImageFormatProperties imageFormatProperties;
413         if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.testedFormat,
414                                                                                                   mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
415                                                                                                   m_parameters.testedImageUsage, 0u, &imageFormatProperties))
416                 TCU_THROW(NotSupportedError, "Operation not supported with this image format");
417
418         if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.resultFormat,
419                                                                                                   mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
420                                                                                                   m_parameters.resultImageUsage, 0u, &imageFormatProperties))
421                 TCU_THROW(NotSupportedError, "Operation not supported with this image format");
422
423         if ((m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
424                 !context.getASTCDecodeFeaturesEXT().decodeModeSharedExponent)
425                 TCU_THROW(NotSupportedError, "decodeModeSharedExponent not supported");
426
427         VkFormatProperties properties;
428         context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_parameters.resultFormat, &properties);
429         if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
430                 TCU_THROW(NotSupportedError, "Format storage feature not supported");
431 }
432
433 void AstcDecodeModeCase::initPrograms (vk::SourceCollections& programCollection) const
434 {
435         DE_ASSERT(m_parameters.imageSize.x() > 0);
436         DE_ASSERT(m_parameters.imageSize.y() > 0);
437
438         const string                            formatQualifierStr      = getShaderImageFormatQualifier(mapVkFormat(m_parameters.resultFormat));
439         const string                            imageTypeStr            = getShaderImageType(mapVkFormat(m_parameters.resultFormat), m_parameters.imageType);
440
441         std::ostringstream      src;
442         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
443                 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n"
444                 << "layout (binding = 0) uniform sampler2D compressed_tested;\n"
445                 << "layout (binding = 1) uniform sampler2D compressed_reference;\n"
446                 << "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " result;\n"
447                 << "void main (void)\n"
448                 << "{\n"
449                 << "    const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
450                 << "    const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
451                 << "    const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n"
452                 << "    vec4 tested = texture(compressed_tested, cord);\n"
453                 << "    vec4 reference = texture(compressed_reference, cord);\n";
454
455         // special case for e5b9g9r9 decode mode that was set on unorm astc formats
456         // here negative values are clamped to zero and alpha is set to 1
457         if (m_parameters.testedIsUnorm && (m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
458                 src << "    reference = max(vec4(0,0,0,1), reference);\n"
459                            "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
460         else
461                 src << "    float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
462
463         src << "    imageStore(result, pos, vec4(result_color));\n"
464                 << "}\n";
465
466         programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
467 }
468
469 TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
470 {
471         return new BasicComputeTestInstance(context, m_parameters);
472 }
473
474 } // anonymous ns
475
476 tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx)
477 {
478         struct FormatData
479         {
480                 VkFormat                format;
481                 std::string             name;
482                 deBool                  isUnorm;
483         };
484         const FormatData astcFormats[] =
485         {
486                 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK,               "4x4_unorm",    DE_TRUE },
487                 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK,                "4x4_srgb",             DE_FALSE },
488                 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK,               "5x4_unorm",    DE_TRUE },
489                 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK,                "5x4_srgb",             DE_FALSE },
490                 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK,               "5x5_unorm",    DE_TRUE },
491                 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK,                "5x5_srgb",             DE_FALSE },
492                 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK,               "6x5_unorm",    DE_TRUE },
493                 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK,                "6x5_srgb",             DE_FALSE },
494                 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK,               "6x6_unorm",    DE_TRUE },
495                 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK,                "6x6_srgb",             DE_FALSE },
496                 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK,               "8x5_unorm",    DE_TRUE },
497                 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK,                "8x5_srgb",             DE_FALSE },
498                 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK,               "8x6_unorm",    DE_TRUE },
499                 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK,                "8x6_srgb",             DE_FALSE },
500                 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK,               "8x8_unorm",    DE_TRUE },
501                 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK,                "8x8_srgb",             DE_FALSE },
502                 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK,              "10x5_unorm",   DE_TRUE },
503                 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK,               "10x5_srgb",    DE_FALSE },
504                 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK,              "10x6_unorm",   DE_TRUE },
505                 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK,               "10x6_srgb",    DE_FALSE },
506                 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK,              "10x8_unorm",   DE_TRUE },
507                 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK,               "10x8_srgb",    DE_FALSE },
508                 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK,             "10x10_unorm",  DE_TRUE },
509                 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK,              "10x10_srgb",   DE_FALSE },
510                 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK,             "12x10_unorm",  DE_TRUE },
511                 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK,              "12x10_srgb",   DE_FALSE },
512                 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK,             "12x12_unorm",  DE_TRUE },
513                 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK,              "12x12_srgb",   DE_FALSE },
514         };
515
516         struct DecodeModeData
517         {
518                 VkFormat                mode;
519                 std::string             name;
520         };
521         const DecodeModeData decodeModes[] =
522         {
523                 { VK_FORMAT_R16G16B16A16_SFLOAT,        "r16g16b16a16_sfloat" },
524                 { VK_FORMAT_R8G8B8A8_UNORM,                     "r8g8b8a8_unorm" },
525                 { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,     "e5b9g9r9_ufloat_pack32" }
526         };
527
528         MovePtr<tcu::TestCaseGroup> astcDecodeModeTests(new tcu::TestCaseGroup(testCtx, "astc_decode_mode", "Intermediate decoding precision cases"));
529         for (const FormatData& format : astcFormats)
530         {
531                 for (const DecodeModeData& mode : decodeModes)
532                 {
533                         const TestParameters parameters =
534                         {
535                                 IMAGE_TYPE_2D,
536                                 UVec3(64u, 64u, 1u),
537                                 format.format,
538                                 format.isUnorm,
539                                 mode.mode,
540                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
541                                 VK_FORMAT_R8G8B8A8_UNORM,
542                                 VK_IMAGE_USAGE_STORAGE_BIT
543                         };
544
545                         std::string name = format.name + "_to_" + mode.name;
546                         astcDecodeModeTests->addChild(new AstcDecodeModeCase(testCtx, name, "", parameters));
547                 }
548         }
549
550         return astcDecodeModeTests.release();
551 }
552
553 } // image
554 } // vkt