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
34 #include "tcuTextureUtil.hpp"
35 #include "tcuTexture.hpp"
36 #include "tcuCompressedTexture.hpp"
37 #include "tcuImageCompare.hpp"
38
39 #include "deRandom.hpp"
40 #include <vector>
41
42 using namespace vk;
43 namespace vkt
44 {
45 namespace image
46 {
47 namespace
48 {
49 using std::string;
50 using std::vector;
51 using tcu::TestContext;
52 using tcu::TestStatus;
53 using tcu::UVec3;
54 using tcu::IVec3;
55 using tcu::CompressedTexFormat;
56 using tcu::CompressedTexture;
57 using de::MovePtr;
58 using de::SharedPtr;
59 using de::Random;
60
61 struct TestParameters
62 {
63 ImageType imageType;
64 UVec3 imageSize;
65
66 VkFormat testedFormat;
67 deBool testedIsUnorm;
68 VkFormat testedDecodeMode;
69 VkImageUsageFlags testedImageUsage;
70
71 VkFormat resultFormat;
72 VkImageUsageFlags resultImageUsage;
73 };
74
75 class BasicComputeTestInstance : public TestInstance
76 {
77 public:
78 BasicComputeTestInstance (Context& context,
79 const TestParameters& parameters);
80
81 TestStatus iterate (void);
82
83 protected:
84
85 void generateData (deUint8* toFill,
86 const size_t size,
87 const VkFormat format,
88 const deUint32 layer,
89 const deUint32 level);
90
91 protected:
92
93 const TestParameters m_parameters;
94 };
95
BasicComputeTestInstance(Context & context,const TestParameters & parameters)96 BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
97 : TestInstance (context)
98 , m_parameters (parameters)
99 {
100 }
101
iterate(void)102 TestStatus BasicComputeTestInstance::iterate (void)
103 {
104 Allocator& allocator = m_context.getDefaultAllocator();
105 const DeviceInterface& vk = m_context.getDeviceInterface();
106 const VkDevice device = m_context.getDevice();
107 const VkQueue queue = m_context.getUniversalQueue();
108 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
109 const VkImageType imageType = mapImageType(m_parameters.imageType);
110 const VkExtent3D extentCompressed = makeExtent3D(getCompressedImageResolutionInBlocks(m_parameters.testedFormat, m_parameters.imageSize));
111 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
112 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
113 const Unique<VkShaderModule> shaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
114
115 const VkImageCreateInfo compressedImageInfo =
116 {
117 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
118 DE_NULL, // const void* pNext;
119 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
120 VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, // VkImageCreateFlags flags;
121 imageType, // VkImageType imageType;
122 m_parameters.testedFormat, // VkFormat format;
123 extentCompressed, // VkExtent3D extent;
124 1u, // deUint32 mipLevels;
125 1u, // deUint32 arrayLayers;
126 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
127 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
128 VK_IMAGE_USAGE_SAMPLED_BIT |
129 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
130 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
131 0u, // deUint32 queueFamilyIndexCount;
132 DE_NULL, // const deUint32* pQueueFamilyIndices;
133 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
134 };
135
136 const VkImageCreateInfo resultImageInfo =
137 {
138 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
139 DE_NULL, // const void* pNext;
140 0u, // VkImageCreateFlags flags;
141 imageType, // VkImageType imageType;
142 m_parameters.resultFormat, // VkFormat format;
143 extentCompressed, // VkExtent3D extent;
144 1u, // deUint32 mipLevels;
145 1u, // deUint32 arrayLayers;
146 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
147 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
148 VK_IMAGE_USAGE_SAMPLED_BIT |
149 VK_IMAGE_USAGE_STORAGE_BIT |
150 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
151 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
152 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
153 0u, // deUint32 queueFamilyIndexCount;
154 DE_NULL, // const deUint32* pQueueFamilyIndices;
155 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
156 };
157
158 // create images
159 Image testedImage (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
160 Image referenceImage (vk, device, allocator, compressedImageInfo, MemoryRequirement::Any);
161 Image resultImage (vk, device, allocator, resultImageInfo, MemoryRequirement::Any);
162
163 // create image views
164 const VkImageViewType imageViewType (mapImageViewType(m_parameters.imageType));
165 VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
166 VkFormat viewFormat = m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
167
168 VkImageViewASTCDecodeModeEXT decodeMode =
169 {
170 VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT,
171 DE_NULL,
172 m_parameters.testedDecodeMode
173 };
174
175 const VkImageViewCreateInfo imageViewParams =
176 {
177 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
178 &decodeMode, // const void* pNext;
179 0u, // VkImageViewCreateFlags flags;
180 testedImage.get(), // VkImage image;
181 imageViewType, // VkImageViewType viewType;
182 viewFormat, // VkFormat format;
183 makeComponentMappingRGBA(), // VkComponentMapping components;
184 subresourceRange, // VkImageSubresourceRange subresourceRange;
185 };
186
187 Move<VkImageView> testedView = createImageView(vk, device, &imageViewParams);
188 Move<VkImageView> referenceView = makeImageView(vk, device, referenceImage.get(), imageViewType, viewFormat, subresourceRange);
189 Move<VkImageView> resultView = makeImageView(vk, device, resultImage.get(), imageViewType, m_parameters.resultFormat,
190 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, resultImageInfo.extent.depth, 0u, resultImageInfo.arrayLayers));
191
192 Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
193 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
194 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_COMPUTE_BIT)
195 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
196 .build(vk, device);
197 Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
198 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
199 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, compressedImageInfo.arrayLayers)
200 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, resultImageInfo.arrayLayers)
201 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, resultImageInfo.arrayLayers);
202
203 Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
204 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
205 const Unique<VkPipeline> pipeline (makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
206
207 const VkDeviceSize bufferSizeCompresed = getCompressedImageSizeInBytes(m_parameters.testedFormat, m_parameters.imageSize);
208 const VkDeviceSize bufferSizeUncompressed = getImageSizeBytes(IVec3((int)extentCompressed.width, (int)extentCompressed.height, (int)extentCompressed.depth), m_parameters.resultFormat);
209 VkBufferCreateInfo compressedBufferCI = makeBufferCreateInfo(bufferSizeCompresed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
210 VkBufferCreateInfo uncompressedBufferCI = makeBufferCreateInfo(bufferSizeUncompressed, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
211 Buffer inBuffer (vk, device, allocator, compressedBufferCI, MemoryRequirement::HostVisible);
212 Buffer resultBuffer (vk, device, allocator, uncompressedBufferCI, MemoryRequirement::HostVisible);
213 Move<VkSampler> sampler;
214
215 // generate data for compressed image and copy it to in buffer
216 {
217 vector<deUint8> generatedData;
218 generatedData.resize(static_cast<size_t>(bufferSizeCompresed));
219 generateData(generatedData.data(), generatedData.size(), m_parameters.testedFormat, 0u, 0u);
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, ©Region);
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, extentCompressed.width, extentCompressed.height, extentCompressed.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, ©Region);
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
generateData(deUint8 * toFill,const size_t size,const VkFormat format,const deUint32 layer,const deUint32 level)378 void BasicComputeTestInstance::generateData (deUint8* toFill,
379 const size_t size,
380 const VkFormat format,
381 const deUint32 layer,
382 const deUint32 level)
383 {
384 // Random data
385 deUint32* start32 = reinterpret_cast<deUint32*>(toFill);
386 size_t sizeToRnd32 = size / sizeof(deUint32);
387 deUint32 seed = (layer << 24) ^ (level << 16) ^ static_cast<deUint32>(format);
388 Random rnd (seed);
389
390 for (size_t i = 0; i < sizeToRnd32; i++)
391 start32[i] = rnd.getUint32();
392 }
393
394 class AstcDecodeModeCase : public TestCase
395 {
396 public:
397 AstcDecodeModeCase (TestContext& testCtx,
398 const std::string& name,
399 const std::string& desc,
400 const TestParameters& parameters);
401 virtual void checkSupport (Context& context) const;
402 void initPrograms (SourceCollections& programCollection) const;
403 TestInstance* createInstance (Context& context) const;
404
405 protected:
406
407 const TestParameters m_parameters;
408 };
409
AstcDecodeModeCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)410 AstcDecodeModeCase::AstcDecodeModeCase (TestContext& testCtx,
411 const std::string& name,
412 const std::string& desc,
413 const TestParameters& parameters)
414 : TestCase (testCtx, name, desc)
415 , m_parameters (parameters)
416 {
417 }
418
checkSupport(Context & context) const419 void AstcDecodeModeCase::checkSupport (Context& context) const
420 {
421 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
422 const InstanceInterface& vk = context.getInstanceInterface();
423
424 context.requireDeviceFunctionality("VK_EXT_astc_decode_mode");
425 if (!getPhysicalDeviceFeatures(vk, physicalDevice).textureCompressionASTC_LDR)
426 TCU_THROW(NotSupportedError, "textureCompressionASTC_LDR not supported");
427
428 VkImageFormatProperties imageFormatProperties;
429 if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.testedFormat,
430 mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
431 m_parameters.testedImageUsage, 0u, &imageFormatProperties))
432 TCU_THROW(NotSupportedError, "Operation not supported with this image format");
433
434 if (VK_ERROR_FORMAT_NOT_SUPPORTED == vk.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.resultFormat,
435 mapImageType(m_parameters.imageType), VK_IMAGE_TILING_OPTIMAL,
436 m_parameters.resultImageUsage, 0u, &imageFormatProperties))
437 TCU_THROW(NotSupportedError, "Operation not supported with this image format");
438
439 if ((m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
440 !context.getASTCDecodeFeaturesEXT().decodeModeSharedExponent)
441 TCU_THROW(NotSupportedError, "decodeModeSharedExponent not supported");
442
443 VkFormatProperties properties;
444 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_parameters.resultFormat, &properties);
445 if (!(properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
446 TCU_THROW(NotSupportedError, "Format storage feature not supported");
447 }
448
initPrograms(vk::SourceCollections & programCollection) const449 void AstcDecodeModeCase::initPrograms (vk::SourceCollections& programCollection) const
450 {
451 DE_ASSERT(m_parameters.imageSize.x() > 0);
452 DE_ASSERT(m_parameters.imageSize.y() > 0);
453
454 VkFormat compatibileFormat = m_parameters.testedIsUnorm ? VK_FORMAT_R32G32B32A32_UINT : VK_FORMAT_R32G32B32A32_SINT;
455 tcu::TextureFormat testedTextureFormat = mapVkFormat(compatibileFormat);
456 VkImageViewType imageViewType = mapImageViewType(m_parameters.imageType);
457 string samplerType = getGlslSamplerType(testedTextureFormat, imageViewType);
458 const string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_parameters.resultFormat));
459 const string imageTypeStr = getShaderImageType(mapVkFormat(m_parameters.resultFormat), m_parameters.imageType);
460
461 std::ostringstream src;
462 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
463 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n\n"
464 << "layout (binding = 0) uniform " << samplerType << " compressed_tested;\n"
465 << "layout (binding = 1) uniform " << samplerType << " compressed_reference;\n"
466 << "layout (binding = 2, " << formatQualifierStr << ") writeonly uniform " << imageTypeStr << " result;\n"
467 << "void main (void)\n"
468 << "{\n"
469 << " const vec2 pixels_resolution = vec2(gl_NumWorkGroups.xy);\n"
470 << " const vec2 cord = vec2(gl_GlobalInvocationID.xy) / vec2(pixels_resolution);\n"
471 << " const ivec2 pos = ivec2(gl_GlobalInvocationID.xy); \n"
472 << " vec4 tested = texture(compressed_tested, cord);\n"
473 << " vec4 reference = texture(compressed_reference, cord);\n";
474
475 // special case for e5b9g9r9 decode mode that was set on unorm astc formats
476 // here negative values are clamped to zero and alpha is set to 1
477 if (m_parameters.testedIsUnorm && (m_parameters.testedDecodeMode == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32))
478 src << " reference = max(vec4(0,0,0,1), reference);\n"
479 " float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
480 else
481 src << " float result_color = 0.5 * float(distance(tested, reference) < 0.01);\n";
482
483 src << " imageStore(result, pos, vec4(result_color));\n"
484 << "}\n";
485
486 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
487 }
488
createInstance(Context & context) const489 TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
490 {
491 return new BasicComputeTestInstance(context, m_parameters);
492 }
493
494 } // anonymous ns
495
createImageAstcDecodeModeTests(tcu::TestContext & testCtx)496 tcu::TestCaseGroup* createImageAstcDecodeModeTests (tcu::TestContext& testCtx)
497 {
498 struct FormatData
499 {
500 VkFormat format;
501 std::string name;
502 deBool isUnorm;
503 };
504 const FormatData astcFormats[] =
505 {
506 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, "4x4_unorm", DE_TRUE },
507 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, "4x4_srgb", DE_FALSE },
508 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, "5x4_unorm", DE_TRUE },
509 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, "5x4_srgb", DE_FALSE },
510 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, "5x5_unorm", DE_TRUE },
511 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, "5x5_srgb", DE_FALSE },
512 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, "6x5_unorm", DE_TRUE },
513 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, "6x5_srgb", DE_FALSE },
514 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, "6x6_unorm", DE_TRUE },
515 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, "6x6_srgb", DE_FALSE },
516 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, "8x5_unorm", DE_TRUE },
517 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, "8x5_srgb", DE_FALSE },
518 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, "8x6_unorm", DE_TRUE },
519 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, "8x6_srgb", DE_FALSE },
520 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, "8x8_unorm", DE_TRUE },
521 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, "8x8_srgb", DE_FALSE },
522 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, "10x5_unorm", DE_TRUE },
523 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, "10x5_srgb", DE_FALSE },
524 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, "10x6_unorm", DE_TRUE },
525 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, "10x6_srgb", DE_FALSE },
526 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, "10x8_unorm", DE_TRUE },
527 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, "10x8_srgb", DE_FALSE },
528 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, "10x10_unorm", DE_TRUE },
529 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, "10x10_srgb", DE_FALSE },
530 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, "12x10_unorm", DE_TRUE },
531 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, "12x10_srgb", DE_FALSE },
532 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, "12x12_unorm", DE_TRUE },
533 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, "12x12_srgb", DE_FALSE },
534 };
535
536 struct DecodeModeData
537 {
538 VkFormat mode;
539 std::string name;
540 };
541 const DecodeModeData decodeModes[] =
542 {
543 { VK_FORMAT_R16G16B16A16_SFLOAT, "r16g16b16a16_sfloat" },
544 { VK_FORMAT_R8G8B8A8_UNORM, "r8g8b8a8_unorm" },
545 { VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, "e5b9g9r9_ufloat_pack32" }
546 };
547
548 MovePtr<tcu::TestCaseGroup> astcDecodeModeTests(new tcu::TestCaseGroup(testCtx, "astc_decode_mode", "Intermediate decoding precision cases"));
549 for (const FormatData& format : astcFormats)
550 {
551 for (const DecodeModeData& mode : decodeModes)
552 {
553 const TestParameters parameters =
554 {
555 IMAGE_TYPE_2D,
556 UVec3(64u, 64u, 1u),
557 format.format,
558 format.isUnorm,
559 mode.mode,
560 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
561 VK_FORMAT_R8G8B8A8_UNORM,
562 VK_IMAGE_USAGE_STORAGE_BIT
563 };
564
565 std::string name = format.name + "_to_" + mode.name;
566 astcDecodeModeTests->addChild(new AstcDecodeModeCase(testCtx, name, "", parameters));
567 }
568 }
569
570 return astcDecodeModeTests.release();
571 }
572
573 } // image
574 } // vkt
575