• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Google Inc.
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 Utility for generating simple work
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDrawUtil.hpp"
26 #include "rrMultisamplePixelBufferAccess.hpp"
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkBarrierUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "rrRenderer.hpp"
34 #include "rrRenderState.hpp"
35 #include "rrPrimitiveTypes.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "deArrayUtil.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 
42 namespace vkt
43 {
44 namespace drawutil
45 {
46 
47 using namespace de;
48 using namespace tcu;
49 using namespace vk;
50 
mapCompareOp(rr::TestFunc compareFunc)51 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
52 {
53 	switch (compareFunc)
54 	{
55 		case rr::TESTFUNC_NEVER:				return VK_COMPARE_OP_NEVER;
56 		case rr::TESTFUNC_LESS:					return VK_COMPARE_OP_LESS;
57 		case rr::TESTFUNC_EQUAL:				return VK_COMPARE_OP_EQUAL;
58 		case rr::TESTFUNC_LEQUAL:				return VK_COMPARE_OP_LESS_OR_EQUAL;
59 		case rr::TESTFUNC_GREATER:				return VK_COMPARE_OP_GREATER;
60 		case rr::TESTFUNC_NOTEQUAL:				return VK_COMPARE_OP_NOT_EQUAL;
61 		case rr::TESTFUNC_GEQUAL:				return VK_COMPARE_OP_GREATER_OR_EQUAL;
62 		case rr::TESTFUNC_ALWAYS:				return VK_COMPARE_OP_ALWAYS;
63 		default:
64 			DE_ASSERT(false);
65 	}
66 	return VK_COMPARE_OP_LAST;
67 }
68 
mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology & primitiveTopology)69 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
70 {
71 	static const rr::PrimitiveType primitiveTypeTable[] =
72 	{
73 		rr::PRIMITIVETYPE_POINTS,
74 		rr::PRIMITIVETYPE_LINES,
75 		rr::PRIMITIVETYPE_LINE_STRIP,
76 		rr::PRIMITIVETYPE_TRIANGLES,
77 		rr::PRIMITIVETYPE_TRIANGLE_STRIP,
78 		rr::PRIMITIVETYPE_TRIANGLE_FAN,
79 		rr::PRIMITIVETYPE_LINES_ADJACENCY,
80 		rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY,
81 		rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY,
82 		rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY
83 	};
84 
85 	return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
86 }
87 
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)88 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
89 										 const VkBufferUsageFlags	usage)
90 {
91 	const VkBufferCreateInfo bufferCreateInfo =
92 	{
93 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
94 		DE_NULL,								// const void*			pNext;
95 		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
96 		bufferSize,								// VkDeviceSize			size;
97 		usage,									// VkBufferUsageFlags	usage;
98 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
99 		0u,										// deUint32				queueFamilyIndexCount;
100 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
101 	};
102 	return bufferCreateInfo;
103 }
104 
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)105 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
106 {
107 	const VkCommandPoolCreateInfo info =
108 	{
109 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
110 		DE_NULL,											// const void*				pNext;
111 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
112 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
113 	};
114 	return createCommandPool(vk, device, &info);
115 }
116 
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)117 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
118 {
119 	const VkCommandBufferAllocateInfo info =
120 	{
121 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
122 		DE_NULL,											// const void*			pNext;
123 		commandPool,										// VkCommandPool		commandPool;
124 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
125 		1u,													// deUint32				commandBufferCount;
126 	};
127 	return allocateCommandBuffer(vk, device, &info);
128 }
129 
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)130 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
131 										 const VkDevice					device,
132 										 const VkDescriptorPool			descriptorPool,
133 										 const VkDescriptorSetLayout	setLayout)
134 {
135 	const VkDescriptorSetAllocateInfo info =
136 	{
137 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
138 		DE_NULL,											// const void*					pNext;
139 		descriptorPool,										// VkDescriptorPool				descriptorPool;
140 		1u,													// deUint32						descriptorSetCount;
141 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
142 	};
143 	return allocateDescriptorSet(vk, device, &info);
144 }
145 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)146 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
147 										   const VkDevice				device,
148 										   const VkDescriptorSetLayout	descriptorSetLayout)
149 {
150 	const VkPipelineLayoutCreateInfo info =
151 	{
152 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
153 		DE_NULL,											// const void*					pNext;
154 		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
155 		1u,													// deUint32						setLayoutCount;
156 		&descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
157 		0u,													// deUint32						pushConstantRangeCount;
158 		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
159 	};
160 	return createPipelineLayout(vk, device, &info);
161 }
162 
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)163 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&		vk,
164 															 const VkDevice				device)
165 {
166 	const VkPipelineLayoutCreateInfo info =
167 	{
168 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
169 		DE_NULL,											// const void*					pNext;
170 		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
171 		0u,													// deUint32						setLayoutCount;
172 		DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
173 		0u,													// deUint32						pushConstantRangeCount;
174 		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
175 	};
176 	return createPipelineLayout(vk, device, &info);
177 }
178 
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)179 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
180 								 const VkDevice					device,
181 								 const VkImage					image,
182 								 const VkImageViewType			viewType,
183 								 const VkFormat					format,
184 								 const VkImageSubresourceRange	subresourceRange)
185 {
186 	const VkImageViewCreateInfo imageViewParams =
187 	{
188 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
189 		DE_NULL,										// const void*				pNext;
190 		(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
191 		image,											// VkImage					image;
192 		viewType,										// VkImageViewType			viewType;
193 		format,											// VkFormat					format;
194 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
195 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
196 	};
197 	return createImageView(vk, device, &imageViewParams);
198 }
199 
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)200 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers	subresourceLayers,
201 									   const VkExtent3D					extent)
202 {
203 	const VkBufferImageCopy copyParams =
204 	{
205 		0ull,										//	VkDeviceSize				bufferOffset;
206 		0u,											//	deUint32					bufferRowLength;
207 		0u,											//	deUint32					bufferImageHeight;
208 		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
209 		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
210 		extent,										//	VkExtent3D					imageExtent;
211 	};
212 	return copyParams;
213 }
214 
getPrimitiveTopologyShortName(const VkPrimitiveTopology topology)215 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
216 {
217 	std::string name(getPrimitiveTopologyName(topology));
218 	return de::toLower(name.substr(22));
219 }
220 
DrawState(const vk::VkPrimitiveTopology topology_,deUint32 renderWidth_,deUint32 renderHeight_)221 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_)
222 	: topology				(topology_)
223 	, colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
224 	, renderSize			(tcu::UVec2(renderWidth_, renderHeight_))
225 	, depthClampEnable		(false)
226 	, depthTestEnable		(false)
227 	, depthWriteEnable		(false)
228 	, compareOp				(rr::TESTFUNC_LESS)
229 	, depthBoundsTestEnable	(false)
230 	, blendEnable			(false)
231 	, lineWidth				(1.0)
232 	, numPatchControlPoints	(0)
233 	, numSamples			(VK_SAMPLE_COUNT_1_BIT)
234 	, sampleShadingEnable	(false)
235 {
236 	DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
237 }
238 
~ReferenceDrawContext(void)239 ReferenceDrawContext::~ReferenceDrawContext (void)
240 {
241 }
242 
draw(void)243 void ReferenceDrawContext::draw (void)
244 {
245 	m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
246 	tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
247 
248 	{
249 		const rr::Program						program(&m_vertexShader, &m_fragmentShader);
250 		const rr::MultisamplePixelBufferAccess	referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
251 		const rr::RenderTarget					renderTarget(referenceColorBuffer);
252 		const rr::RenderState					renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
253 		const rr::Renderer						renderer;
254 		const rr::VertexAttrib					vertexAttrib[] =
255 		{
256 			rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
257 		};
258 
259 		renderer.draw(rr::DrawCommand(	renderState,
260 										renderTarget,
261 										program,
262 										DE_LENGTH_OF_ARRAY(vertexAttrib),
263 										&vertexAttrib[0],
264 										rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
265 
266 	}
267 
268 }
269 
getColorPixels(void) const270 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
271 {
272 	return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
273 										m_refImage.getAccess().getWidth(),
274 										m_refImage.getAccess().getHeight(),
275 										m_refImage.getAccess().getDepth(),
276 										m_refImage.getAccess().getDataPtr());
277 }
278 
VulkanDrawContext(Context & context,const DrawState & drawState,const DrawCallData & drawCallData,const VulkanProgram & vulkanProgram)279 VulkanDrawContext::VulkanDrawContext ( Context&				context,
280 									  const DrawState&		drawState,
281 									  const DrawCallData&	drawCallData,
282 									  const VulkanProgram&	vulkanProgram)
283 	: DrawContext	(drawState, drawCallData)
284 	, m_context		(context)
285 	, m_program		(vulkanProgram)
286 {
287 	const DeviceInterface&	vk						= m_context.getDeviceInterface();
288 	const VkDevice			device					= m_context.getDevice();
289 	Allocator&				allocator				= m_context.getDefaultAllocator();
290 	VkImageSubresourceRange	colorSubresourceRange;
291 	Move<VkSampler>			sampler;
292 
293 	// Command buffer
294 	{
295 		m_cmdPool			= makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
296 		m_cmdBuffer			= makeCommandBuffer(vk, device, *m_cmdPool);
297 	}
298 
299 	// Color attachment image
300 	{
301 		const VkImageUsageFlags usage			= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
302 		colorSubresourceRange					= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
303 		const VkImageCreateInfo	imageCreateInfo	=
304 		{
305 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
306 			DE_NULL,																	// const void*				pNext;
307 			(VkImageCreateFlags)0,														// VkImageCreateFlags		flags;
308 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
309 			m_drawState.colorFormat,													// VkFormat					format;
310 			makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u),	// VkExtent3D				extent;
311 			1u,																			// uint32_t					mipLevels;
312 			1u,																			// uint32_t					arrayLayers;
313 			(VkSampleCountFlagBits)m_drawState.numSamples,								// VkSampleCountFlagBits	samples;
314 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
315 			usage,																		// VkImageUsageFlags		usage;
316 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
317 			0u,																			// uint32_t					queueFamilyIndexCount;
318 			DE_NULL,																	// const uint32_t*			pQueueFamilyIndices;
319 			VK_IMAGE_LAYOUT_UNDEFINED,													// VkImageLayout			initialLayout;
320 		};
321 
322 		m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
323 		m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
324 
325 		// Buffer to copy attachment data after rendering
326 
327 		const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
328 		m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
329 			vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
330 
331 		{
332 			const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
333 			deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
334 			flushAlloc(vk, device, alloc);
335 		}
336 	}
337 
338 	// Vertex buffer
339 	{
340 		const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
341 		m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
342 			vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
343 
344 		const Allocation& alloc = m_vertexBuffer->getAllocation();
345 		deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
346 		flushAlloc(vk, device, alloc);
347 	}
348 
349 	// bind descriptor sets
350 	{
351 		if (!vulkanProgram.descriptorSetLayout)
352 			m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
353 		else
354 			m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout);
355 	}
356 
357 	// Renderpass
358 	{
359 		std::vector<VkAttachmentDescription> attachmentDescriptions;
360 		const VkAttachmentDescription attachDescriptors[] =
361 		{
362 			{
363 				(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
364 				m_drawState.colorFormat,							// VkFormat							format;
365 				(VkSampleCountFlagBits)m_drawState.numSamples,		// VkSampleCountFlagBits			samples;
366 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
367 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
368 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
369 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
370 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout;
371 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					finalLayout;
372 			},
373 			{
374 				(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
375 				m_drawState.depthFormat,							// VkFormat							format
376 				(VkSampleCountFlagBits)m_drawState.numSamples,		// VkSampleCountFlagBits			samples
377 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp
378 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
379 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp
380 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp
381 				VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout
382 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					finalLayout
383 
384 			}
385 		};
386 
387 		const VkAttachmentReference attachmentReferences[] =
388 		{
389 			{
390 				0u,													// uint32_t			attachment
391 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout
392 			},
393 			{
394 				1u,													// uint32_t			attachment
395 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
396 			},
397 			{
398 				VK_ATTACHMENT_UNUSED,								// deUint32         attachment;
399 				VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout    layout;
400 			}
401 		};
402 
403 		attachmentDescriptions.push_back(attachDescriptors[0]);
404 		if (!!vulkanProgram.depthImageView)
405 			attachmentDescriptions.push_back(attachDescriptors[1]);
406 
407 		deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2;
408 		const VkSubpassDescription subpassDescription =
409 		{
410 			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
411 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
412 			0u,													// deUint32							inputAttachmentCount;
413 			DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
414 			1u,													// deUint32							colorAttachmentCount;
415 			&attachmentReferences[0],							// const VkAttachmentReference*		pColorAttachments;
416 			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
417 			&attachmentReferences[depthReferenceNdx],			// const VkAttachmentReference*		pDepthStencilAttachment;
418 			0u,													// deUint32							preserveAttachmentCount;
419 			DE_NULL												// const deUint32*					pPreserveAttachments;
420 		};
421 
422 		const VkRenderPassCreateInfo renderPassInfo =
423 		{
424 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
425 			DE_NULL,											// const void*						pNext;
426 			(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
427 			(deUint32)attachmentDescriptions.size(),			// deUint32							attachmentCount;
428 			&attachmentDescriptions[0],							// const VkAttachmentDescription*	pAttachments;
429 			1u,													// deUint32							subpassCount;
430 			&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
431 			0u,													// deUint32							dependencyCount;
432 			DE_NULL												// const VkSubpassDependency*		pDependencies;
433 		};
434 
435 		m_renderPass = createRenderPass(vk, device, &renderPassInfo);
436 	}
437 
438 	// Framebuffer
439 	{
440 		std::vector<VkImageView>	attachmentBindInfos;
441 		deUint32					numAttachments;
442 		attachmentBindInfos.push_back(*m_colorImageView);
443 		if (!!vulkanProgram.depthImageView)
444 			attachmentBindInfos.push_back(vulkanProgram.depthImageView);
445 
446 		numAttachments = (deUint32)(attachmentBindInfos.size());
447 		const VkFramebufferCreateInfo framebufferInfo = {
448 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType						sType;
449 			DE_NULL,										// const void*							pNext;
450 			(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags				flags;
451 			*m_renderPass,									// VkRenderPass							renderPass;
452 			numAttachments,									// uint32_t								attachmentCount;
453 			&attachmentBindInfos[0],						// const VkImageView*					pAttachments;
454 			m_drawState.renderSize.x(),						// uint32_t								width;
455 			m_drawState.renderSize.y(),						// uint32_t								height;
456 			1u,												// uint32_t								layers;
457 		};
458 
459 		m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
460 	}
461 
462 	// Graphics pipeline
463 	{
464 		VkShaderModule	vertShader			= DE_NULL;
465 		VkShaderModule	tessControlShader	= DE_NULL;
466 		VkShaderModule	tessEvalShader		= DE_NULL;
467 		VkShaderModule	geomShader			= DE_NULL;
468 		VkShaderModule	fragShader			= DE_NULL;
469 
470 		DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
471 
472 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_drawState.renderSize));
473 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_drawState.renderSize));
474 
475 		const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
476 		{
477 			VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType;
478 			DE_NULL,														// const void*								pNext;
479 			(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags	flags;
480 			m_drawState.depthClampEnable,									// VkBool32									depthClampEnable;
481 			VK_FALSE,														// VkBool32									rasterizerDiscardEnable;
482 			VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
483 			VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
484 			VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace;
485 			VK_FALSE,														// VkBool32									depthBiasEnable;
486 			0.0f,															// float									depthBiasConstantFactor;
487 			0.0f,															// float									depthBiasClamp;
488 			0.0f,															// float									depthBiasSlopeFactor;
489 			m_drawState.lineWidth,											// float									lineWidth;
490 		};
491 
492 		const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
493 		{
494 			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
495 			DE_NULL,													// const void*								pNext;
496 			(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
497 			(VkSampleCountFlagBits)m_drawState.numSamples,				// VkSampleCountFlagBits					rasterizationSamples;
498 			m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE,		// VkBool32									sampleShadingEnable;
499 			m_drawState.sampleShadingEnable ? 1.0f : 0.0f,				// float									minSampleShading;
500 			DE_NULL,													// const VkSampleMask*						pSampleMask;
501 			VK_FALSE,													// VkBool32									alphaToCoverageEnable;
502 			VK_FALSE													// VkBool32									alphaToOneEnable;
503 		};
504 
505 		const VkStencilOpState stencilOpState = makeStencilOpState(
506 			VK_STENCIL_OP_KEEP,		// stencil fail
507 			VK_STENCIL_OP_KEEP,		// depth & stencil pass
508 			VK_STENCIL_OP_KEEP,		// depth only fail
509 			VK_COMPARE_OP_NEVER,	// compare op
510 			0u,						// compare mask
511 			0u,						// write mask
512 			0u);					// reference
513 
514 		if (m_drawState.depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds)
515 			TCU_THROW(NotSupportedError, "depthBounds not supported");
516 
517 		const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
518 		{
519 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
520 			DE_NULL,													// const void*								pNext;
521 			(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
522 			m_drawState.depthTestEnable,								// VkBool32									depthTestEnable;
523 			m_drawState.depthWriteEnable,								// VkBool32									depthWriteEnable;
524 			mapCompareOp(m_drawState.compareOp),						// VkCompareOp								depthCompareOp;
525 			m_drawState.depthBoundsTestEnable,							// VkBool32									depthBoundsTestEnable
526 			VK_FALSE,													// VkBool32									stencilTestEnable;
527 			stencilOpState,												// VkStencilOpState							front;
528 			stencilOpState,												// VkStencilOpState							back;
529 			0.0f,														// float									minDepthBounds;
530 			1.0f,														// float									maxDepthBounds;
531 		};
532 
533 		const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
534 		const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
535 		{
536 			m_drawState.blendEnable,			// VkBool32					blendEnable;
537 			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
538 			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
539 			VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
540 			VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
541 			VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
542 			VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
543 			colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
544 		};
545 
546 		const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
547 		{
548 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
549 			DE_NULL,													// const void*									pNext;
550 			(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
551 			VK_FALSE,													// VkBool32										logicOpEnable;
552 			VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
553 			1u,															// deUint32										attachmentCount;
554 			&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
555 			{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
556 		};
557 
558 		VkShaderStageFlags stageFlags = (VkShaderStageFlags)0;
559 
560 		DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
561 		for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
562 		{
563 			m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
564 
565 			stageFlags |= m_program.shaders[shaderNdx].stage;
566 
567 			switch(m_program.shaders[shaderNdx].stage)
568 			{
569 				case VK_SHADER_STAGE_VERTEX_BIT:
570 					vertShader = *m_shaderModules[shaderNdx];
571 					break;
572 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
573 					tessControlShader = *m_shaderModules[shaderNdx];
574 					break;
575 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
576 					tessEvalShader = *m_shaderModules[shaderNdx];
577 					break;
578 				case VK_SHADER_STAGE_GEOMETRY_BIT:
579 					geomShader = *m_shaderModules[shaderNdx];
580 					break;
581 				default:
582 					DE_ASSERT(m_program.shaders[shaderNdx].stage == VK_SHADER_STAGE_FRAGMENT_BIT);
583 					fragShader = *m_shaderModules[shaderNdx];
584 					break;
585 			}
586 		}
587 
588 		DE_ASSERT(
589 			(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
590 			(stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
591 
592 		m_pipeline = makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
593 										  device,								// const VkDevice                                device
594 										  *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
595 										  vertShader,							// const VkShaderModule                          vertexShaderModule
596 										  tessControlShader,					// const VkShaderModule                          tessellationControlShaderModule
597 										  tessEvalShader,						// const VkShaderModule                          tessellationEvalShaderModule
598 										  geomShader,							// const VkShaderModule                          geometryShaderModule
599 										  fragShader,							// const VkShaderModule                          fragmentShaderModule
600 										  *m_renderPass,						// const VkRenderPass                            renderPass
601 										  viewports,							// const std::vector<VkViewport>&                viewports
602 										  scissors,								// const std::vector<VkRect2D>&                  scissors
603 										  m_drawState.topology,					// const VkPrimitiveTopology                     topology
604 										  0u,									// const deUint32                                subpass
605 										  m_drawState.numPatchControlPoints,	// const deUint32                                patchControlPoints
606 										  DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
607 										  &pipelineRasterizationStateInfo,		// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
608 										  &pipelineMultisampleStateInfo,		// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
609 										  &pipelineDepthStencilStateInfo,		// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
610 										  &pipelineColorBlendStateInfo);		// const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
611 	}
612 
613 	// Record commands
614 	{
615 		const VkDeviceSize zeroOffset = 0ull;
616 
617 		beginCommandBuffer(vk, *m_cmdBuffer);
618 		if (!!vulkanProgram.descriptorSet)
619 			vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL);
620 
621 		// Begin render pass
622 		if (!!vulkanProgram.depthImageView)
623 			beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0.0f, 0);
624 		else
625 			beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
626 
627 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
628 		vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
629 
630 		vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
631 		endRenderPass(vk, *m_cmdBuffer);
632 
633 		// Barrier: draw -> copy from image
634 		{
635 			const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
636 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
637 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
638 				**m_colorImage, colorSubresourceRange);
639 
640 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
641 				0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
642 		}
643 
644 		// Resolve multisample image
645 		{
646 			if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
647 			{
648 				const VkImageResolve imageResolve =
649 				{
650 					makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
651 					{ 0, 0, 0},
652 					makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
653 					{ 0, 0, 0},
654 					makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
655 				};
656 
657 				const VkImageCreateInfo resolveImageCreateInfo =
658 				{
659 					VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,				// VkStructureType			sType
660 					DE_NULL,											// const void*				pNext
661 					(VkImageCreateFlags)0,								// VkImageCreateFlags		flags
662 					VK_IMAGE_TYPE_2D,									// VkImageType				imageType
663 					m_drawState.colorFormat,							// VkFormat					format
664 					makeExtent3D(m_drawState.renderSize.x(),			// VkExtent3D				extent;
665 							m_drawState.renderSize.y(), 1u),
666 					1u,													// uint32_t					mipLevels
667 					1u,													// uint32_t					arrayLayers
668 					VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits	samples
669 					VK_IMAGE_TILING_OPTIMAL,							// VkImaageTiling			tiling
670 					VK_IMAGE_USAGE_TRANSFER_DST_BIT |					// VkImageUsageFlags		usage
671 					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
672 					VK_SHARING_MODE_EXCLUSIVE,							// VkSharingModeExclusive	sharingMode
673 					0u,													// uint32_t					queueFamilyIndexCount
674 					DE_NULL,											// const uint32_t*			pQueueFamilyIndices
675 					VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout			initialLayout
676 				};
677 
678 				m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
679 
680 				const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
681 						0u, VK_ACCESS_TRANSFER_READ_BIT,
682 						VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
683 						**m_resolveImage, colorSubresourceRange);
684 
685 				vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
686 						0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
687 
688 				vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
689 						**m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
690 
691 				const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
692 					VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
693 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
694 					**m_resolveImage, colorSubresourceRange);
695 
696 				vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
697 					0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
698 			}
699 			else
700 				m_resolveImage = m_colorImage;
701 
702 			const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
703 					makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
704 			vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
705 		}
706 
707 		// Barrier: copy to buffer -> host read
708 		{
709 			const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
710 				VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
711 				**m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
712 
713 			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
714 				0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
715 		}
716 
717 		endCommandBuffer(vk, *m_cmdBuffer);
718 	}
719 }
720 
~VulkanDrawContext(void)721 VulkanDrawContext::~VulkanDrawContext (void)
722 {
723 }
724 
draw(void)725 void VulkanDrawContext::draw (void)
726 {
727 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
728 	const VkDevice			device		= m_context.getDevice();
729 	const VkQueue			queue		= m_context.getUniversalQueue();
730 	tcu::TestLog&			log			= m_context.getTestContext().getLog();
731 
732 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
733 
734 	log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
735 }
736 
getColorPixels(void) const737 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
738 {
739 	const DeviceInterface&	vk			= m_context.getDeviceInterface();
740 	const VkDevice			device		= m_context.getDevice();
741 
742 	const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
743 	invalidateAlloc(vk, device, alloc);
744 
745 	return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
746 }
747 } // drawutil
748 } // vkt
749