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