• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BasicComputeTestInstance(Context & context,const TestParameters & parameters)90 BasicComputeTestInstance::BasicComputeTestInstance (Context& context, const TestParameters& parameters)
91 	: TestInstance	(context)
92 	, m_parameters	(parameters)
93 {
94 }
95 
iterate(void)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 
AstcDecodeModeCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)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 
checkSupport(Context & context) const403 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 
initPrograms(vk::SourceCollections & programCollection) const433 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 
createInstance(Context & context) const469 TestInstance* AstcDecodeModeCase::createInstance (Context& context) const
470 {
471 	return new BasicComputeTestInstance(context, m_parameters);
472 }
473 
474 } // anonymous ns
475 
createImageAstcDecodeModeTests(tcu::TestContext & testCtx)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
555