• 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 
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, &copyRegion);
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, &copyRegion);
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