• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 LunarG, Inc.
6  * Copyright (c) 2023 Nintendo
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Shader Object Link Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectRenderingTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vktShaderObjectCreateUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "deRandom.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuVectorUtil.hpp"
39 #include <cmath>
40 
41 namespace vkt
42 {
43 namespace ShaderObject
44 {
45 
46 namespace
47 {
48 
49 enum ExtraAttachments {
50 	NONE = 0,
51 	BEFORE,
52 	BETWEEN,
53 	AFTER,
54 };
55 
56 enum DummyRenderPass
57 {
58 	DUMMY_NONE = 0,
59 	DUMMY_DYNAMIC,
60 	DUMMY_STATIC,
61 };
62 
63 struct TestParams {
64 	deUint32 colorAttachmentCount;
65 	deUint32 extraAttachmentCount;
66 	ExtraAttachments extraAttachments;
67 	deUint32 extraFragmentOutputCount;
68 	ExtraAttachments extraOutputs;
69 	bool useDepthAttachment;
70 	vk::VkFormat colorFormat;
71 	vk::VkFormat depthFormat;
72 	bool bindShadersBeforeBeginRendering;
73 	DummyRenderPass dummyRenderPass;
74 	bool writeGlFragDepth;
75 	bool randomColorFormats;
76 };
77 
78 const vk::VkFormat colorFormats[] =
79 {
80 	vk::VK_FORMAT_R4G4_UNORM_PACK8,
81 	vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
82 	vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
83 	vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
84 	vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
85 	vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
86 	vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
87 	vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
88 	vk::VK_FORMAT_R8_UNORM,
89 	vk::VK_FORMAT_R8_SNORM,
90 	vk::VK_FORMAT_R8_USCALED,
91 	vk::VK_FORMAT_R8_SSCALED,
92 	vk::VK_FORMAT_R8_UINT,
93 	vk::VK_FORMAT_R8_SINT,
94 	vk::VK_FORMAT_R8_SRGB,
95 	vk::VK_FORMAT_R8G8_UNORM,
96 	vk::VK_FORMAT_R8G8_SNORM,
97 	vk::VK_FORMAT_R8G8_USCALED,
98 	vk::VK_FORMAT_R8G8_SSCALED,
99 	vk::VK_FORMAT_R8G8_UINT,
100 	vk::VK_FORMAT_R8G8_SINT,
101 	vk::VK_FORMAT_R8G8_SRGB,
102 	vk::VK_FORMAT_R8G8B8_UNORM,
103 	vk::VK_FORMAT_R8G8B8_SNORM,
104 	vk::VK_FORMAT_R8G8B8_USCALED,
105 	vk::VK_FORMAT_R8G8B8_SSCALED,
106 	vk::VK_FORMAT_R8G8B8_UINT,
107 	vk::VK_FORMAT_R8G8B8_SINT,
108 	vk::VK_FORMAT_R8G8B8_SRGB,
109 	vk::VK_FORMAT_B8G8R8_UNORM,
110 	vk::VK_FORMAT_B8G8R8_SNORM,
111 	vk::VK_FORMAT_B8G8R8_USCALED,
112 	vk::VK_FORMAT_B8G8R8_SSCALED,
113 	vk::VK_FORMAT_B8G8R8_UINT,
114 	vk::VK_FORMAT_B8G8R8_SINT,
115 	vk::VK_FORMAT_B8G8R8_SRGB,
116 	vk::VK_FORMAT_R8G8B8A8_UNORM,
117 	vk::VK_FORMAT_R8G8B8A8_SNORM,
118 	vk::VK_FORMAT_R8G8B8A8_USCALED,
119 	vk::VK_FORMAT_R8G8B8A8_SSCALED,
120 	vk::VK_FORMAT_R8G8B8A8_UINT,
121 	vk::VK_FORMAT_R8G8B8A8_SINT,
122 	vk::VK_FORMAT_R8G8B8A8_SRGB,
123 	vk::VK_FORMAT_B8G8R8A8_UNORM,
124 	vk::VK_FORMAT_B8G8R8A8_SNORM,
125 	vk::VK_FORMAT_B8G8R8A8_USCALED,
126 	vk::VK_FORMAT_B8G8R8A8_SSCALED,
127 	vk::VK_FORMAT_B8G8R8A8_UINT,
128 	vk::VK_FORMAT_B8G8R8A8_SINT,
129 	vk::VK_FORMAT_B8G8R8A8_SRGB,
130 	vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
131 	vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32,
132 	vk::VK_FORMAT_A8B8G8R8_USCALED_PACK32,
133 	vk::VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
134 	vk::VK_FORMAT_A8B8G8R8_UINT_PACK32,
135 	vk::VK_FORMAT_A8B8G8R8_SINT_PACK32,
136 	vk::VK_FORMAT_A8B8G8R8_SRGB_PACK32,
137 	vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
138 	vk::VK_FORMAT_A2R10G10B10_SNORM_PACK32,
139 	vk::VK_FORMAT_A2R10G10B10_USCALED_PACK32,
140 	vk::VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
141 	vk::VK_FORMAT_A2R10G10B10_UINT_PACK32,
142 	vk::VK_FORMAT_A2R10G10B10_SINT_PACK32,
143 	vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
144 	vk::VK_FORMAT_A2B10G10R10_SNORM_PACK32,
145 	vk::VK_FORMAT_A2B10G10R10_USCALED_PACK32,
146 	vk::VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
147 	vk::VK_FORMAT_A2B10G10R10_UINT_PACK32,
148 	vk::VK_FORMAT_A2B10G10R10_SINT_PACK32,
149 	vk::VK_FORMAT_R16_UNORM,
150 	vk::VK_FORMAT_R16_SNORM,
151 	vk::VK_FORMAT_R16_USCALED,
152 	vk::VK_FORMAT_R16_SSCALED,
153 	vk::VK_FORMAT_R16_UINT,
154 	vk::VK_FORMAT_R16_SINT,
155 	vk::VK_FORMAT_R16_SFLOAT,
156 	vk::VK_FORMAT_R16G16_UNORM,
157 	vk::VK_FORMAT_R16G16_SNORM,
158 	vk::VK_FORMAT_R16G16_USCALED,
159 	vk::VK_FORMAT_R16G16_SSCALED,
160 	vk::VK_FORMAT_R16G16_UINT,
161 	vk::VK_FORMAT_R16G16_SINT,
162 	vk::VK_FORMAT_R16G16_SFLOAT,
163 	vk::VK_FORMAT_R16G16B16_UNORM,
164 	vk::VK_FORMAT_R16G16B16_SNORM,
165 	vk::VK_FORMAT_R16G16B16_USCALED,
166 	vk::VK_FORMAT_R16G16B16_SSCALED,
167 	vk::VK_FORMAT_R16G16B16_UINT,
168 	vk::VK_FORMAT_R16G16B16_SINT,
169 	vk::VK_FORMAT_R16G16B16_SFLOAT,
170 	vk::VK_FORMAT_R16G16B16A16_UNORM,
171 	vk::VK_FORMAT_R16G16B16A16_SNORM,
172 	vk::VK_FORMAT_R16G16B16A16_USCALED,
173 	vk::VK_FORMAT_R16G16B16A16_SSCALED,
174 	vk::VK_FORMAT_R16G16B16A16_UINT,
175 	vk::VK_FORMAT_R16G16B16A16_SINT,
176 	vk::VK_FORMAT_R16G16B16A16_SFLOAT,
177 	vk::VK_FORMAT_R32_UINT,
178 	vk::VK_FORMAT_R32_SINT,
179 	vk::VK_FORMAT_R32_SFLOAT,
180 	vk::VK_FORMAT_R32G32_UINT,
181 	vk::VK_FORMAT_R32G32_SINT,
182 	vk::VK_FORMAT_R32G32_SFLOAT,
183 	vk::VK_FORMAT_R32G32B32_UINT,
184 	vk::VK_FORMAT_R32G32B32_SINT,
185 	vk::VK_FORMAT_R32G32B32_SFLOAT,
186 	vk::VK_FORMAT_R32G32B32A32_UINT,
187 	vk::VK_FORMAT_R32G32B32A32_SINT,
188 	vk::VK_FORMAT_R32G32B32A32_SFLOAT,
189 };
190 
191 const vk::VkFormat randomColorFormats[] =
192 {
193 	vk::VK_FORMAT_R8_UNORM,
194 	vk::VK_FORMAT_R8_SNORM,
195 	vk::VK_FORMAT_R8G8_UNORM,
196 	vk::VK_FORMAT_R8G8_SNORM,
197 	vk::VK_FORMAT_R8G8B8A8_UNORM,
198 	vk::VK_FORMAT_R8G8B8A8_SNORM,
199 	vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
200 	vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32,
201 	vk::VK_FORMAT_R16_UNORM,
202 	vk::VK_FORMAT_R16_SNORM,
203 	vk::VK_FORMAT_R16G16_UNORM,
204 	vk::VK_FORMAT_R16G16_SNORM,
205 	vk::VK_FORMAT_R16G16_SFLOAT,
206 	vk::VK_FORMAT_R16G16B16_UNORM,
207 	vk::VK_FORMAT_R16G16B16_SNORM,
208 	vk::VK_FORMAT_R16G16B16_SFLOAT,
209 	vk::VK_FORMAT_R16G16B16A16_UNORM,
210 	vk::VK_FORMAT_R16G16B16A16_SNORM,
211 	vk::VK_FORMAT_R16G16B16A16_SFLOAT,
212 	vk::VK_FORMAT_R32_SFLOAT,
213 	vk::VK_FORMAT_R32G32_SFLOAT,
214 	vk::VK_FORMAT_R32G32B32_SFLOAT,
215 	vk::VK_FORMAT_R32G32B32A32_SFLOAT,
216 };
217 
readDepthAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,deUint32 queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)218 de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface&	vk,
219 													vk::VkDevice				device,
220 													vk::VkQueue					queue,
221 													deUint32					queueFamilyIndex,
222 													vk::Allocator&				allocator,
223 													vk::VkImage					image,
224 													vk::VkFormat				format,
225 													const tcu::UVec2&			renderSize,
226 													vk::VkImageLayout			currentLayout)
227 {
228 	vk::Move<vk::VkBuffer>					buffer;
229 	de::MovePtr<vk::Allocation>				bufferAlloc;
230 	vk::Move<vk::VkCommandPool>				cmdPool;
231 	vk::Move<vk::VkCommandBuffer>			cmdBuffer;
232 
233 	tcu::TextureFormat				retFormat		(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
234 	tcu::TextureFormat				bufferFormat	(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
235 	const vk::VkImageAspectFlags	barrierAspect	= vk::VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT : (vk::VkImageAspectFlagBits)0);
236 
237 	switch (format)
238 	{
239 	case vk::VK_FORMAT_D16_UNORM:
240 	case vk::VK_FORMAT_D16_UNORM_S8_UINT:
241 		bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
242 		break;
243 	case vk::VK_FORMAT_D24_UNORM_S8_UINT:
244 	case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
245 		retFormat.type = tcu::TextureFormat::UNORM_INT24;
246 		// vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
247 		bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
248 		break;
249 	case vk::VK_FORMAT_D32_SFLOAT:
250 	case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
251 		bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
252 		break;
253 	default:
254 		TCU_FAIL("unrecognized format");
255 	}
256 
257 	const vk::VkDeviceSize				pixelDataSize	= renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
258 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
259 
260 	// Create destination buffer
261 	{
262 		const vk::VkBufferCreateInfo bufferParams =
263 		{
264 			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
265 			DE_NULL,									// const void*			pNext;
266 			0u,											// VkBufferCreateFlags	flags;
267 			pixelDataSize,								// VkDeviceSize			size;
268 			vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
269 			vk::VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
270 			0u,											// deUint32				queueFamilyIndexCount;
271 			DE_NULL										// const deUint32*		pQueueFamilyIndices;
272 		};
273 
274 		buffer		= createBuffer(vk, device, &bufferParams);
275 		bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
276 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
277 	}
278 
279 	// Create command pool and buffer
280 	cmdPool		= createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
281 	cmdBuffer	= allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
282 
283 	beginCommandBuffer(vk, *cmdBuffer);
284 	copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_DEPTH_BIT);
285 	endCommandBuffer(vk, *cmdBuffer);
286 
287 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
288 
289 	// Read buffer data
290 	invalidateAlloc(vk, device, *bufferAlloc);
291 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
292 
293 	return resultLevel;
294 }
295 
296 class ShaderObjectRenderingInstance : public vkt::TestInstance
297 {
298 public:
ShaderObjectRenderingInstance(Context & context,const TestParams & params)299 							ShaderObjectRenderingInstance	(Context& context, const TestParams& params)
300 															: vkt::TestInstance	(context)
301 															, m_params			(params)
302 															{}
~ShaderObjectRenderingInstance(void)303 	virtual					~ShaderObjectRenderingInstance	(void) {}
304 
305 	tcu::TestStatus			iterate							(void) override;
306 private:
307 	void					beginRendering					(vk::VkCommandBuffer cmdBuffer);
308 	void					createDummyImage				(void);
309 	void					createDummyRenderPass			(void);
310 	void					setColorFormats					(const vk::InstanceDriver& vki);
311 	void					generateExpectedImage			(const tcu::PixelBufferAccess& outputImage, const deUint32 width, const deUint32 height, deUint32 attachmentIndex);
312 
313 	TestParams								m_params;
314 
315 	const vk::VkRect2D						m_renderArea = vk::makeRect2D(0, 0, 32, 32);
316 	std::vector<vk::VkFormat>				m_colorFormats;
317 	std::vector<vk::Move<vk::VkImageView>>	m_colorImageViews;
318 	vk::Move<vk::VkImageView>				m_depthImageView;
319 
320 	de::MovePtr<vk::ImageWithMemory>		m_dummyImage;
321 	vk::Move<vk::VkImageView>				m_dummyImageView;
322 	vk::Move<vk::VkRenderPass>				m_dummyRenderPass;
323 	vk::Move<vk::VkFramebuffer>				m_dummyFramebuffer;
324 };
325 
createDummyImage(void)326 void ShaderObjectRenderingInstance::createDummyImage (void)
327 {
328 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
329 	const vk::VkDevice					device						= m_context.getDevice();
330 	auto&								alloc						= m_context.getDefaultAllocator();
331 	const auto							colorSubresourceRange		= makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
332 
333 	vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT : vk::VK_FORMAT_R8G8B8A8_UNORM;
334 
335 	const vk::VkImageCreateInfo	createInfo =
336 	{
337 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
338 		DE_NULL,									// const void*				pNext
339 		0u,											// VkImageCreateFlags		flags
340 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
341 		format,										// VkFormat					format
342 		{ 32, 32, 1 },								// VkExtent3D				extent
343 		1u,											// uint32_t					mipLevels
344 		1u,											// uint32_t					arrayLayers
345 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
346 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
347 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
348 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
349 		0,											// uint32_t					queueFamilyIndexCount
350 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
351 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
352 	};
353 
354 	m_dummyImage = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
355 	m_dummyImageView = vk::makeImageView(vk, device, **m_dummyImage, vk::VK_IMAGE_VIEW_TYPE_2D, format, colorSubresourceRange);
356 }
357 
createDummyRenderPass(void)358 void ShaderObjectRenderingInstance::createDummyRenderPass (void)
359 {
360 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
361 	const vk::VkDevice					device						= m_context.getDevice();
362 	vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT : vk::VK_FORMAT_R8G8B8A8_UNORM;
363 	m_dummyRenderPass = vk::makeRenderPass(vk, device, format);
364 	m_dummyFramebuffer = vk::makeFramebuffer(vk, device, *m_dummyRenderPass, 1u, &*m_dummyImageView, m_renderArea.extent.width, m_renderArea.extent.height);
365 }
366 
getClearValue(const tcu::TextureFormat tcuFormat)367 vk::VkClearValue getClearValue(const tcu::TextureFormat tcuFormat)
368 {
369 	const tcu::TextureChannelClass	channelClass = tcu::getTextureChannelClass(tcuFormat.type);
370 
371 	if (channelClass != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER && channelClass != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
372 		return vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
373 
374 	const tcu::IVec4	bits = tcu::min(tcu::getTextureFormatBitDepth(tcuFormat), tcu::IVec4(32));
375 	const int			signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
376 
377 	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
378 		return vk::makeClearValueColorU32(0u, 0u, 0u, deUint32((deUint64(1) << (bits[3] - signBit)) - 1));
379 
380 	return vk::makeClearValueColorI32(0u, 0u, 0u, deInt32((deUint64(1) << (bits[3] - signBit)) - 1));
381 }
382 
beginRendering(vk::VkCommandBuffer cmdBuffer)383 void ShaderObjectRenderingInstance::beginRendering (vk::VkCommandBuffer cmdBuffer)
384 {
385 	const vk::DeviceInterface&			vk					= m_context.getDeviceInterface();
386 	const vk::VkClearValue				floatClearValue		= vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
387 	const vk::VkClearValue				clearDepthValue		= vk::makeClearValueDepthStencil(1.0f, 0u);
388 
389 	vk::VkRenderingAttachmentInfo colorAttachment
390 	{
391 		vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
392 		DE_NULL,												// const void*							pNext;
393 		VK_NULL_HANDLE,											// VkImageView							imageView;
394 		vk::VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout						imageLayout;
395 		vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
396 		DE_NULL,												// VkImageView							resolveImageView;
397 		vk::VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout						resolveImageLayout;
398 		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp					loadOp;
399 		vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
400 		floatClearValue											// VkClearValue							clearValue;
401 	};
402 
403 	deUint32 outputCount = m_params.colorAttachmentCount + m_params.extraFragmentOutputCount + m_params.extraAttachmentCount;
404 	std::vector<vk::VkRenderingAttachmentInfo> colorAttachments(outputCount);
405 	deUint32 i = 0;
406 	if (m_params.extraOutputs == BEFORE || (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 0))
407 	{
408 		colorAttachment.imageView = VK_NULL_HANDLE;
409 		for (deUint32 j = 0; j < m_params.extraFragmentOutputCount; ++j)
410 			colorAttachments[i++] = colorAttachment;
411 	}
412 	for (deUint32 j = 0; j < m_params.colorAttachmentCount + m_params.extraAttachmentCount; ++j)
413 	{
414 		if (m_params.extraOutputs == BETWEEN && i == (m_params.colorAttachmentCount + m_params.extraAttachmentCount) / 2 + 1)
415 		{
416 			colorAttachment.imageView = VK_NULL_HANDLE;
417 			for (deUint32 k = 0; k < m_params.extraFragmentOutputCount; ++k)
418 				colorAttachments[i++] = colorAttachment;
419 		}
420 		colorAttachment.imageView = *m_colorImageViews[j];
421 		colorAttachment.clearValue = getClearValue(vk::mapVkFormat(m_colorFormats[j]));
422 
423 		colorAttachments[i++] = colorAttachment;
424 	}
425 	if (m_params.extraOutputs == AFTER || (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 1))
426 	{
427 		colorAttachment.imageView = VK_NULL_HANDLE;
428 		for (deUint32 j = 0; j < m_params.extraFragmentOutputCount; ++j)
429 			colorAttachments[i++] = colorAttachment;
430 	}
431 
432 	vk::VkRenderingAttachmentInfo depthAttachment
433 	{
434 		vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
435 		DE_NULL,												// const void*							pNext;
436 		*m_depthImageView,										// VkImageView							imageView;
437 		vk::VK_IMAGE_LAYOUT_GENERAL,							// VkImageLayout						imageLayout;
438 		vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
439 		DE_NULL,												// VkImageView							resolveImageView;
440 		vk::VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout						resolveImageLayout;
441 		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp					loadOp;
442 		vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
443 		clearDepthValue											// VkClearValue							clearValue;
444 	};
445 
446 	vk::VkRenderingInfoKHR renderingInfo
447 	{
448 		vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
449 		DE_NULL,
450 		(vk::VkRenderingFlags)0u,									// VkRenderingFlagsKHR					flags;
451 		m_renderArea,												// VkRect2D								renderArea;
452 		1u,															// deUint32								layerCount;
453 		0x0,														// deUint32								viewMask;
454 		(deUint32)colorAttachments.size(),							// deUint32								colorAttachmentCount;
455 		colorAttachments.data(),									// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
456 		m_params.useDepthAttachment ? &depthAttachment : DE_NULL,	// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
457 		DE_NULL,													// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
458 	};
459 
460 	vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
461 }
462 
setColorFormats(const vk::InstanceDriver & vki)463 void ShaderObjectRenderingInstance::setColorFormats (const vk::InstanceDriver& vki)
464 {
465 	const auto							physicalDevice = m_context.getPhysicalDevice();
466 
467 	m_colorFormats.resize(m_params.colorAttachmentCount + m_params.extraAttachmentCount);
468 	if (m_params.randomColorFormats)
469 	{
470 		if (m_colorFormats.size() > 0)
471 		{
472 			m_colorFormats[0] = m_params.colorFormat;
473 		}
474 		de::Random random(102030);
475 		for (deUint32 i = 1; i < (deUint32)m_colorFormats.size(); ++i)
476 		{
477 			if (i <= m_params.extraAttachmentCount && m_params.extraAttachments == BEFORE)
478 				m_colorFormats[i] = m_params.colorFormat;
479 			else
480 			{
481 				while (true)
482 				{
483 					// Find random color format, and make sure it is supported
484 					vk::VkFormat format = randomColorFormats[random.getUint32() % DE_LENGTH_OF_ARRAY(randomColorFormats)];
485 					vk::VkImageFormatProperties	colorImageFormatProperties;
486 					const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &colorImageFormatProperties);
487 					if (colorResult == vk::VK_SUCCESS)
488 					{
489 						m_colorFormats[i] = format;
490 						break;
491 					}
492 				}
493 			}
494 		}
495 	}
496 	else
497 	{
498 		for (auto& colorFormat : m_colorFormats)
499 			colorFormat = m_params.colorFormat;
500 	}
501 }
502 
generateExpectedImage(const tcu::PixelBufferAccess & outputImage,const deUint32 width,const deUint32 height,deUint32 attachmentIndex)503 void ShaderObjectRenderingInstance::generateExpectedImage (const tcu::PixelBufferAccess& outputImage, const deUint32 width, const deUint32 height, deUint32 attachmentIndex)
504 {
505 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(outputImage.getFormat().type);
506 	const vk::VkClearValue			clearValue		= getClearValue(outputImage.getFormat());
507 
508 	const deUint32					xOffset			= 8;
509 	const deUint32					yOffset			= 8;
510 
511 	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
512 		tcu::clear(outputImage, tcu::UVec4(clearValue.color.uint32));
513 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
514 		tcu::clear(outputImage, tcu::IVec4(clearValue.color.int32));
515 	else
516 		tcu::clear(outputImage, tcu::Vec4(clearValue.color.float32));
517 
518 	if ((m_params.extraAttachments == BEFORE && attachmentIndex < m_params.extraAttachmentCount) || (m_params.extraAttachments == BETWEEN && attachmentIndex > m_params.colorAttachmentCount / 2u && attachmentIndex <= m_params.colorAttachmentCount / 2u + m_params.extraAttachmentCount) || (m_params.extraAttachments == AFTER && attachmentIndex >= m_params.colorAttachmentCount))
519 		return;
520 
521 	tcu::Vec4 setColor		= tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
522 	tcu::IVec4 setColorInt	= tcu::IVec4(0, 0, 0, 0);
523 	tcu::UVec4 setColorUint = tcu::UVec4(0u, 0u, 0u, 0u);
524 
525 	for (deInt32 i = 0; i < tcu::getNumUsedChannels(outputImage.getFormat().order); ++i)
526 	{
527 		setColor[i] = 1.0f;
528 		setColorInt[i] = 255;
529 		setColorUint[i] = 255u;
530 	}
531 
532 	for (deUint32 j = 0; j < height; ++j)
533 	{
534 		for (deUint32 i = 0; i < width; ++i)
535 		{
536 			if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
537 			{
538 				if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
539 					outputImage.setPixel(setColorUint, i, j, 0);
540 				else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
541 					outputImage.setPixel(setColorInt, i, j, 0);
542 				else
543 					outputImage.setPixel(setColor, i, j, 0);
544 			}
545 		}
546 	}
547 }
548 
iterate(void)549 tcu::TestStatus ShaderObjectRenderingInstance::iterate (void)
550 {
551 	const vk::VkInstance				instance					= m_context.getInstance();
552 	const vk::InstanceDriver			instanceDriver				(m_context.getPlatformInterface(), instance);
553 	const vk::DeviceInterface&			vk							= m_context.getDeviceInterface();
554 	const vk::VkDevice					device						= m_context.getDevice();
555 	const vk::VkQueue					queue						= m_context.getUniversalQueue();
556 	const deUint32						queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
557 	auto&								alloc						= m_context.getDefaultAllocator();
558 	tcu::TestLog&						log							= m_context.getTestContext().getLog();
559 	const auto							deviceExtensions			= vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
560 	const bool							tessellationSupported		= m_context.getDeviceFeatures().tessellationShader;
561 	const bool							geometrySupported			= m_context.getDeviceFeatures().geometryShader;
562 	const bool							taskSupported				= m_context.getMeshShaderFeatures().taskShader;
563 	const bool							meshSupported				= m_context.getMeshShaderFeatures().meshShader;
564 
565 	const auto							colorSubresourceRange		= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
566 	auto								depthSubresourceRange		= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
567 	if (m_params.useDepthAttachment && tcu::hasStencilComponent(mapVkFormat(m_params.depthFormat).order))
568 		depthSubresourceRange.aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
569 	const auto							colorSubresourceLayers		= vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
570 	vk::VkExtent3D						extent						= { m_renderArea.extent.width, m_renderArea.extent.height, 1};
571 
572 	setColorFormats(instanceDriver);
573 
574 	vk::VkImageCreateInfo	createInfo =
575 	{
576 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
577 		DE_NULL,									// const void*				pNext
578 		0u,											// VkImageCreateFlags		flags
579 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
580 		vk::VK_FORMAT_UNDEFINED,					// VkFormat					format
581 		{ 32, 32, 1 },								// VkExtent3D				extent
582 		1u,											// uint32_t					mipLevels
583 		1u,											// uint32_t					arrayLayers
584 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
585 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
586 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
587 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
588 		0,											// uint32_t					queueFamilyIndexCount
589 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
590 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
591 	};
592 
593 	const vk::VkImageCreateInfo	depthCreateInfo =
594 	{
595 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
596 		DE_NULL,									// const void*				pNext
597 		0u,											// VkImageCreateFlags		flags
598 		vk::VK_IMAGE_TYPE_2D,						// VkImageType				imageType
599 		m_params.depthFormat,						// VkFormat					format
600 		{ 32, 32, 1 },								// VkExtent3D				extent
601 		1u,											// uint32_t					mipLevels
602 		1u,											// uint32_t					arrayLayers
603 		vk::VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
604 		vk::VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
605 		vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
606 		vk::VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
607 		0,											// uint32_t					queueFamilyIndexCount
608 		DE_NULL,									// const uint32_t*			pQueueFamilyIndices
609 		vk::VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
610 	};
611 
612 	deUint32 colorAttachmentCount = m_params.colorAttachmentCount + m_params.extraAttachmentCount;
613 	std::vector<de::MovePtr<vk::ImageWithMemory>>	colorImages	(colorAttachmentCount);
614 	m_colorImageViews.resize(colorAttachmentCount);
615 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
616 	{
617 		createInfo.format = m_colorFormats[i];
618 		colorImages[i] = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
619 		m_colorImageViews[i] = vk::makeImageView(vk, device, **colorImages[i], vk::VK_IMAGE_VIEW_TYPE_2D, createInfo.format, colorSubresourceRange);
620 	}
621 
622 	de::MovePtr<vk::ImageWithMemory>	depthImage;
623 	if (m_params.useDepthAttachment)
624 	{
625 		depthImage = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
626 		m_depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D, m_params.depthFormat, depthSubresourceRange);
627 	}
628 
629 	std::vector<de::MovePtr<vk::BufferWithMemory>>	colorOutputBuffers;
630 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
631 	{
632 		const vk::VkDeviceSize				colorOutputBufferSize = m_renderArea.extent.width * m_renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(m_colorFormats[i]));
633 		colorOutputBuffers.push_back(de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
634 			vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible)));
635 	}
636 
637 	const auto&							binaries				= m_context.getBinaryCollection();
638 	const auto							vertShader				= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vertDepth"), tessellationSupported, geometrySupported));
639 	const auto							fragShader				= vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("fragMulti"), tessellationSupported, geometrySupported));
640 
641 	const vk::Move<vk::VkCommandPool>	cmdPool					(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
642 	const vk::Move<vk::VkCommandBuffer>	cmdBuffer				(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
643 
644 	vk::beginCommandBuffer(vk, *cmdBuffer);
645 
646 	if (m_params.dummyRenderPass == DUMMY_DYNAMIC)
647 	{
648 		createDummyImage();
649 		const vk::VkClearValue				clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
650 		vk::beginRendering(vk, *cmdBuffer, *m_dummyImageView, m_renderArea, clearValue);
651 	}
652 	else if (m_params.dummyRenderPass == DUMMY_STATIC)
653 	{
654 		createDummyImage();
655 		createDummyRenderPass();
656 		const vk::VkClearValue				clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
657 		vk::beginRenderPass(vk, *cmdBuffer, *m_dummyRenderPass, *m_dummyFramebuffer, m_renderArea, clearValue);
658 	}
659 
660 	if (m_params.bindShadersBeforeBeginRendering)
661 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
662 
663 	if (m_params.dummyRenderPass == DUMMY_DYNAMIC)
664 	{
665 		vk::endRendering(vk, *cmdBuffer);
666 	}
667 	else if (m_params.dummyRenderPass == DUMMY_STATIC)
668 	{
669 		vk::endRenderPass(vk, *cmdBuffer);
670 	}
671 
672 	for (const auto& colorImage : colorImages)
673 	{
674 		vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange);
675 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier);
676 	}
677 
678 	if (m_params.useDepthAttachment)
679 	{
680 		vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
681 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preDepthImageBarrier);
682 	}
683 
684 	beginRendering(*cmdBuffer);
685 	vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
686 	vk::VkBool32 colorBlendEnable = VK_FALSE;
687 	vk::VkColorBlendEquationEXT		colorBlendEquation = {
688 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	srcColorBlendFactor;
689 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	dstColorBlendFactor;
690 		vk::VK_BLEND_OP_ADD,			// VkBlendOp		colorBlendOp;
691 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	srcAlphaBlendFactor;
692 		vk::VK_BLEND_FACTOR_ONE,		// VkBlendFactor	dstAlphaBlendFactor;
693 		vk::VK_BLEND_OP_ADD,			// VkBlendOp		alphaBlendOp;
694 	};
695 	vk::VkColorComponentFlags		colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
696 		vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
697 	deUint32 count = colorAttachmentCount + m_params.extraFragmentOutputCount;
698 	if (count == 0) ++count;
699 	std::vector<vk::VkBool32>					colorBlendEnables	(count, colorBlendEnable);
700 	std::vector<vk::VkColorBlendEquationEXT>	colorBlendEquations	(count, colorBlendEquation);
701 	std::vector<vk::VkColorComponentFlags>		colorWriteMasks		(count, colorWriteMask);
702 	vk.cmdSetColorBlendEnableEXT(*cmdBuffer, 0u, count, colorBlendEnables.data());
703 	vk.cmdSetColorBlendEquationEXT(*cmdBuffer, 0u, count, colorBlendEquations.data());
704 	vk.cmdSetColorWriteMaskEXT(*cmdBuffer, 0u, count, colorWriteMasks.data());
705 	std::vector<vk::VkBool32> colorWriteEnables	(count, VK_TRUE);
706 	vk.cmdSetColorWriteEnableEXT(*cmdBuffer, count, colorWriteEnables.data());
707 	vk.cmdSetDepthWriteEnable(*cmdBuffer, VK_TRUE);
708 	vk.cmdSetDepthTestEnable(*cmdBuffer, VK_TRUE);
709 	vk.cmdSetDepthCompareOp(*cmdBuffer, vk::VK_COMPARE_OP_LESS);
710 	vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
711 	if (!m_params.bindShadersBeforeBeginRendering)
712 		vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported);
713 	vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
714 	vk::endRendering(vk, *cmdBuffer);
715 
716 	for (const auto& colorImage : colorImages)
717 	{
718 		vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange);
719 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier);
720 	}
721 
722 	if (m_params.useDepthAttachment)
723 	{
724 		vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
725 		vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postDepthImageBarrier);
726 	}
727 
728 	const vk::VkBufferImageCopy	colorCopyRegion = vk::makeBufferImageCopy(extent, colorSubresourceLayers);
729 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
730 		vk.cmdCopyImageToBuffer(*cmdBuffer, **colorImages[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u, &colorCopyRegion);
731 
732 	vk::endCommandBuffer(vk, *cmdBuffer);
733 
734 	vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
735 
736 	std::vector<tcu::ConstPixelBufferAccess> colorResultBuffers;
737 	for (deUint32 i = 0; i < colorAttachmentCount; ++i)
738 		colorResultBuffers.push_back(tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_colorFormats[i]), m_renderArea.extent.width, m_renderArea.extent.height, 1, (const void*)colorOutputBuffers[i]->getAllocation().getHostPtr()));
739 
740 	const deUint32			width	= m_renderArea.extent.width;
741 	const deUint32			height	= m_renderArea.extent.height;
742 	const deUint32			xOffset = 8;
743 	const deUint32			yOffset = 8;
744 
745 	for (deUint32 k = 0; k < (deUint32)colorImages.size(); ++k)
746 	{
747 		tcu::TextureLevel					textureLevel	(mapVkFormat(m_colorFormats[k]), width, height);
748 		const tcu::PixelBufferAccess		expectedImage	= textureLevel.getAccess();
749 		generateExpectedImage(expectedImage, width, height, k);
750 
751 		if (vk::isFloatFormat(m_colorFormats[k]))
752 		{
753 			if (!tcu::floatThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k], tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
754 				return tcu::TestStatus::fail("Fail");
755 		}
756 		else
757 		{
758 			if (!tcu::intThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k], tcu::UVec4(2), tcu::COMPARE_LOG_RESULT))
759 				return tcu::TestStatus::fail("Fail");
760 		}
761 	}
762 
763 	if (m_params.useDepthAttachment)
764 	{
765 		const auto depthBuffer = readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, m_params.depthFormat, tcu::UVec2(m_renderArea.extent.width, m_renderArea.extent.height), vk::VK_IMAGE_LAYOUT_GENERAL);
766 		const auto depthAccess = depthBuffer->getAccess();
767 
768 		const float depthEpsilon = 0.02f;
769 		for (deUint32 j = 0; j < height; ++j)
770 		{
771 			for (deUint32 i = 0; i < width; ++i)
772 			{
773 				const float depth = depthAccess.getPixDepth(i, j);
774 				if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
775 				{
776 					if (deFloatAbs(depth - 0.5f) > depthEpsilon)
777 					{
778 						log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be 0.5, but was (" << depth << ")" << tcu::TestLog::EndMessage;
779 						return tcu::TestStatus::fail("Fail");
780 					}
781 				}
782 				else
783 				{
784 					if (deFloatAbs(depth - 1.0f) > depthEpsilon)
785 					{
786 						log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be 0.0, but was (" << depth << ")" << tcu::TestLog::EndMessage;
787 						return tcu::TestStatus::fail("Fail");
788 					}
789 				}
790 			}
791 		}
792 	}
793 
794 	return tcu::TestStatus::pass("Pass");
795 }
796 
797 class ShaderObjectRenderingCase : public vkt::TestCase
798 {
799 public:
ShaderObjectRenderingCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)800 							ShaderObjectRenderingCase	(tcu::TestContext& testCtx, const std::string& name, const TestParams& params)
801 														: vkt::TestCase		(testCtx, name)
802 														, m_params			(params)
803 														{}
~ShaderObjectRenderingCase(void)804 	virtual					~ShaderObjectRenderingCase	(void) {}
805 
806 	void					checkSupport			(vkt::Context& context) const override;
807 	virtual void			initPrograms			(vk::SourceCollections& programCollection) const override;
createInstance(Context & context) const808 	TestInstance*			createInstance			(Context& context) const override { return new ShaderObjectRenderingInstance(context, m_params); }
809 private:
810 	TestParams m_params;
811 };
812 
checkSupport(Context & context) const813 void ShaderObjectRenderingCase::checkSupport (Context& context) const
814 {
815 	const auto&		vki				= context.getInstanceInterface();
816 	const auto		physicalDevice	= context.getPhysicalDevice();
817 	const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
818 
819 	context.requireDeviceFunctionality("VK_EXT_shader_object");
820 
821 	if (m_params.colorAttachmentCount + m_params.extraAttachmentCount + m_params.extraFragmentOutputCount > properties.limits.maxColorAttachments)
822 		TCU_THROW(NotSupportedError, "Tests uses more color attachments than VkPhysicalDeviceLimits::maxColorAttachments");
823 
824 	vk::VkImageFormatProperties	colorImageFormatProperties;
825 	const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_params.colorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &colorImageFormatProperties);
826 	if (colorResult != vk::VK_SUCCESS)
827 		TCU_THROW(NotSupportedError, "Format unsupported for tiling");
828 	vk::VkImageFormatProperties	depthImageFormatProperties;
829 	if (m_params.useDepthAttachment)
830 	{
831 		const auto depthResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_params.depthFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &depthImageFormatProperties);
832 		if (depthResult != vk::VK_SUCCESS)
833 			TCU_THROW(NotSupportedError, "Format unsupported for tiling");
834 	}
835 }
836 
initPrograms(vk::SourceCollections & programCollection) const837 void ShaderObjectRenderingCase::initPrograms (vk::SourceCollections& programCollection) const
838 {
839 	std::stringstream vertDepth;
840 	std::stringstream fragMulti;
841 
842 	vertDepth
843 		<< "#version 450\n"
844 		<< "void main() {\n"
845 		<< "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
846 		<< "    gl_Position = vec4(pos - 0.5f, 0.5f, 1.0f);\n"
847 		<< "}\n";
848 
849 	fragMulti
850 		<< "#version 450\n";
851 	deUint32 outputCount = m_params.colorAttachmentCount + m_params.extraFragmentOutputCount;
852 	for (deUint32 i = 0; i < outputCount; ++i)
853 	{
854 		deUint32 j = i;
855 		if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2))
856 			j += m_params.extraAttachmentCount;
857 		bool firstWrittenAttachment = (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0);
858 		if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
859 			fragMulti << "layout (location = " << j << ") out uvec4 outColor" << j << ";\n";
860 		else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
861 			fragMulti << "layout (location = " << j << ") out ivec4 outColor" << j << ";\n";
862 		else
863 			fragMulti << "layout (location = " << j << ") out vec4 outColor" << j << ";\n";
864 	}
865 	fragMulti
866 		<< "void main() {\n";
867 	for (deUint32 i = 0; i < outputCount; ++i)
868 	{
869 		deUint32 j = i;
870 		if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2))
871 			j += m_params.extraAttachmentCount;
872 		bool firstWrittenAttachment = (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0);
873 		if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
874 			fragMulti << "    outColor" << j << " = uvec4(255);\n";
875 		else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats))
876 			fragMulti << "    outColor" << j << " = ivec4(255);\n";
877 		else
878 			fragMulti << "    outColor" << j << " = vec4(1.0f);\n";
879 	}
880 	if (m_params.writeGlFragDepth)
881 		fragMulti
882 			<< "    gl_FragDepth = 0.5f;\n";
883 	fragMulti
884 		<< "}\n";
885 
886 	programCollection.glslSources.add("vertDepth") << glu::VertexSource(vertDepth.str());
887 	programCollection.glslSources.add("fragMulti") << glu::FragmentSource(fragMulti.str());
888 }
889 
890 }
891 
getFormatCaseName(vk::VkFormat format)892 std::string getFormatCaseName(vk::VkFormat format)
893 {
894 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
895 }
896 
createShaderObjectRenderingTests(tcu::TestContext & testCtx)897 tcu::TestCaseGroup* createShaderObjectRenderingTests (tcu::TestContext& testCtx)
898 {
899 	de::MovePtr<tcu::TestCaseGroup> renderingGroup(new tcu::TestCaseGroup(testCtx, "rendering"));
900 
901 	const struct
902 	{
903 		deUint32 colorAttachmentCount;
904 		const char* name;
905 	} colorAttachmentCountTests[] =
906 	{
907 		{ 0u,	"color_attachment_count_0",	},
908 		{ 1u,	"color_attachment_count_1",	},
909 		{ 4u,	"color_attachment_count_4",	},
910 		{ 8u,	"color_attachment_count_8",	},
911 	};
912 
913 	const struct
914 	{
915 		deUint32 extraAttachmentCount;
916 		ExtraAttachments extraAttachment;
917 		const char* name;
918 	} extraAttachmentTests[] =
919 	{
920 		{ 0u,	NONE,		"none",							},
921 		{ 1u,	BEFORE,		"extra_attachment_before_1",	},
922 		{ 1u,	BETWEEN,	"extra_attachment_between_1",	},
923 		{ 1u,	AFTER,		"extra_attachment_after_1",		},
924 		{ 2u,	BEFORE,		"extra_attachment_before_2",	},
925 		{ 2u,	BETWEEN,	"extra_attachment_between_2",	},
926 		{ 2u,	AFTER,		"extra_attachment_after_2",		},
927 	};
928 
929 	const struct
930 	{
931 		deUint32 extraFragmentOutputCount;
932 		ExtraAttachments extraAttachment;
933 		const char* name;
934 	} extraOutputTests[] =
935 	{
936 		{ 0u,	NONE,		"none",						},
937 		{ 1u,	BEFORE,		"extra_output_before_1",	},
938 		{ 1u,	BETWEEN,	"extra_output_between_1",	},
939 		{ 1u,	AFTER,		"extra_output_after_1",		},
940 		{ 2u,	BEFORE,		"extra_output_before_2",	},
941 		{ 2u,	BETWEEN,	"extra_output_between_2",	},
942 		{ 2u,	AFTER,		"extra_output_after_2",		},
943 	};
944 
945 	const vk::VkFormat		depthStencilFormats[] =
946 	{
947 		vk::VK_FORMAT_D16_UNORM,
948 		vk::VK_FORMAT_X8_D24_UNORM_PACK32,
949 		vk::VK_FORMAT_D32_SFLOAT,
950 		vk::VK_FORMAT_D16_UNORM_S8_UINT,
951 		vk::VK_FORMAT_D24_UNORM_S8_UINT,
952 		vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
953 	};
954 
955 	const struct
956 	{
957 		DummyRenderPass	dummyRenderPass;
958 		const char* name;
959 	} dummyRenderPassTests[] =
960 	{
961 		{ DUMMY_NONE,		"none",		},
962 		{ DUMMY_DYNAMIC,	"dynamic",	},
963 		{ DUMMY_STATIC,		"static",	},
964 	};
965 
966 	for (const auto& colorAttachmentCountTest : colorAttachmentCountTests)
967 	{
968 		de::MovePtr<tcu::TestCaseGroup> colorAttachmentGroup(new tcu::TestCaseGroup(testCtx, colorAttachmentCountTest.name));
969 		for (const auto& extraAttachment : extraAttachmentTests)
970 		{
971 			de::MovePtr<tcu::TestCaseGroup> extraAttachmentGroup(new tcu::TestCaseGroup(testCtx, extraAttachment.name));
972 			for (const auto& extraOutput : extraOutputTests)
973 			{
974 				if (extraAttachment.extraAttachment != NONE && extraOutput.extraFragmentOutputCount != NONE)
975 					continue;
976 
977 				de::MovePtr<tcu::TestCaseGroup> extraOutputGroup(new tcu::TestCaseGroup(testCtx, extraOutput.name));
978 
979 				for (const auto& dummyRenderPass : dummyRenderPassTests)
980 				{
981 					de::MovePtr<tcu::TestCaseGroup> dummyRenderPassGroup(new tcu::TestCaseGroup(testCtx, dummyRenderPass.name));
982 					for (deUint32 m = 0; m < 2; ++m)
983 					{
984 						bool useRandomColorFormats = m == 0;
985 						if (useRandomColorFormats && colorAttachmentCountTest.colorAttachmentCount < 2)
986 							continue;
987 						std::string randomColorFormatsName = useRandomColorFormats ? "random_color_formats" : "same_color_formats";
988 						de::MovePtr<tcu::TestCaseGroup> randomColorFormatsGroup(new tcu::TestCaseGroup(testCtx, randomColorFormatsName.c_str()));
989 						for (deUint32 k = 0; k < 2; ++k)
990 						{
991 							bool bindShadersBeforeBeginRendering = k == 0;
992 							std::string bindName = bindShadersBeforeBeginRendering ? "before" : "after";
993 							de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, bindName.c_str()));
994 							for (deUint32 l = 0; l < 2; ++l)
995 							{
996 								bool writeGlFragDepth = l == 0;
997 								std::string writeGlFragName = writeGlFragDepth ? "gl_frag_write" : "none";
998 								de::MovePtr<tcu::TestCaseGroup> fragWriteGroup(new tcu::TestCaseGroup(testCtx, writeGlFragName.c_str()));
999 								for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(colorFormats); ++i)
1000 								{
1001 									if (extraAttachment.extraAttachmentCount > colorAttachmentCountTest.colorAttachmentCount)
1002 										continue;
1003 
1004 									if (!bindShadersBeforeBeginRendering && dummyRenderPass.dummyRenderPass != DUMMY_NONE)
1005 										continue;
1006 
1007 									const auto colorFormat = colorFormats[i];
1008 
1009 									TestParams params;
1010 									params.colorAttachmentCount = colorAttachmentCountTest.colorAttachmentCount;
1011 									params.extraAttachmentCount = extraAttachment.extraAttachmentCount;
1012 									params.extraAttachments = extraAttachment.extraAttachment;
1013 									params.extraFragmentOutputCount = extraOutput.extraFragmentOutputCount;
1014 									params.extraOutputs = extraOutput.extraAttachment;
1015 									params.useDepthAttachment = false;
1016 									params.colorFormat = colorFormat;
1017 									params.depthFormat = vk::VK_FORMAT_UNDEFINED;
1018 									params.bindShadersBeforeBeginRendering = bindShadersBeforeBeginRendering;
1019 									params.dummyRenderPass = dummyRenderPass.dummyRenderPass;
1020 									params.writeGlFragDepth = writeGlFragDepth;
1021 									params.randomColorFormats = useRandomColorFormats;
1022 
1023 									std::string name = getFormatCaseName(colorFormat);
1024 									fragWriteGroup->addChild(new ShaderObjectRenderingCase(testCtx, name, params));
1025 
1026 									if (writeGlFragDepth)
1027 										continue;
1028 
1029 									for (deUint32 j = 0; j < DE_LENGTH_OF_ARRAY(depthStencilFormats); ++j)
1030 									{
1031 										const auto depthFormat = depthStencilFormats[j];
1032 										params.useDepthAttachment = true;
1033 										params.depthFormat = depthFormat;
1034 
1035 										std::string depthTestName = name + "_" + getFormatCaseName(depthFormat);
1036 										fragWriteGroup->addChild(new ShaderObjectRenderingCase(testCtx, depthTestName, params));
1037 									}
1038 								}
1039 								bindGroup->addChild(fragWriteGroup.release());
1040 							}
1041 							randomColorFormatsGroup->addChild(bindGroup.release());
1042 						}
1043 						dummyRenderPassGroup->addChild(randomColorFormatsGroup.release());
1044 					}
1045 					extraOutputGroup->addChild(dummyRenderPassGroup.release());
1046 				}
1047 				extraAttachmentGroup->addChild(extraOutputGroup.release());
1048 			}
1049 			colorAttachmentGroup->addChild(extraAttachmentGroup.release());
1050 		}
1051 		renderingGroup->addChild(colorAttachmentGroup.release());
1052 	}
1053 
1054 	return renderingGroup.release();
1055 }
1056 
1057 } // ShaderObject
1058 } // vkt
1059