• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 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
21  * \brief OHOS Native Buffer Draw Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktDrawOHOSNativeBufferTests.hpp"
25 
26 #include "vktDrawBaseClass.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkCmdUtil.hpp"
29 #include "vkTypeUtil.hpp"
30 #include "vktTestGroupUtil.hpp"
31 
32 #include "../util/vktExternalMemoryUtil.hpp"
33 
34 #include "deDefs.h"
35 #include "deRandom.hpp"
36 
37 #include "tcuTestCase.hpp"
38 #include "tcuTextureUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "tcuTestLog.hpp"
42 
43 #include "rrRenderer.hpp"
44 
45 #include <string>
46 
47 using namespace vkt::ExternalMemoryUtil;
48 using namespace vk;
49 using std::vector;
50 
51 namespace vkt
52 {
53 namespace Draw
54 {
55 namespace
56 {
57 
58 const deUint32 SEED = 0xc2a39fu;
59 
60 struct DrawParams
61 {
DrawParamsvkt::Draw::__anonfcf020ad0111::DrawParams62 	DrawParams (deUint32 numVertices, deUint32 numLayers)
63 	: m_numVertices(numVertices), m_numLayers(numLayers) {}
64 
65 	deUint32					m_numVertices;
66 	deUint32					m_numLayers;
67 	vector<PositionColorVertex>	m_vertices;
68 };
69 
70 // Reference renderer shaders
71 class PassthruVertShader : public rr::VertexShader
72 {
73 public:
PassthruVertShader(void)74 	PassthruVertShader (void)
75 	: rr::VertexShader (2, 1)
76 	{
77 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
78 		m_inputs[1].type	= rr::GENERICVECTYPE_FLOAT;
79 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
80 	}
81 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const82 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
83 	{
84 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
85 		{
86 			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
87 																	 packets[packetNdx]->instanceNdx,
88 																	 packets[packetNdx]->vertexNdx);
89 
90 			tcu::Vec4 color = rr::readVertexAttribFloat(inputs[1],
91 														packets[packetNdx]->instanceNdx,
92 														packets[packetNdx]->vertexNdx);
93 
94 			packets[packetNdx]->outputs[0] = color;
95 		}
96 	}
97 };
98 
99 class PassthruFragShader : public rr::FragmentShader
100 {
101 public:
PassthruFragShader(void)102 	PassthruFragShader (void)
103 		: rr::FragmentShader(1, 1)
104 	{
105 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
106 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
107 	}
108 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const109 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets,
110                          const rr::FragmentShadingContext& context) const
111 	{
112 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
113 		{
114 			rr::FragmentPacket& packet = packets[packetNdx];
115 			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
116 			{
117 				tcu::Vec4 color = rr::readVarying<float>(packet, context, 0, fragNdx);
118 				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
119 			}
120 		}
121 	}
122 };
123 
124 class OHOSNativeBufferTestInstance : public TestInstance
125 {
126 public:
127 					OHOSNativeBufferTestInstance		(Context& context, DrawParams data);
128 					~OHOSNativeBufferTestInstance	    (void);
129 
130 	tcu::TestStatus	iterate				(void);
131 
132 private:
133 	void			generateDrawData	(void);
134 	void			generateRefImage	(const tcu::PixelBufferAccess& access, const vector<tcu::Vec4>& vertices,
135                                          const vector<tcu::Vec4>& colors) const;
136 
137 	DrawParams							m_data;
138 
139 	enum
140 	{
141 		WIDTH = 256,
142 		HEIGHT = 256
143 	};
144 };
145 
OHOSNativeBufferTestInstance(Context & context,DrawParams data)146 OHOSNativeBufferTestInstance::OHOSNativeBufferTestInstance (Context& context, DrawParams data)
147 	: vkt::TestInstance			(context)
148 	, m_data					(data)
149 {
150 	generateDrawData();
151 }
152 
~OHOSNativeBufferTestInstance(void)153 OHOSNativeBufferTestInstance::~OHOSNativeBufferTestInstance (void)
154 {
155 }
156 
generateRefImage(const tcu::PixelBufferAccess & access,const vector<tcu::Vec4> & vertices,const vector<tcu::Vec4> & colors) const157 void OHOSNativeBufferTestInstance::generateRefImage (const tcu::PixelBufferAccess& access,
158                                                      const vector<tcu::Vec4>& vertices,
159                                                      const vector<tcu::Vec4>& colors) const
160 {
161 	const PassthruVertShader				vertShader;
162 	const PassthruFragShader				fragShader;
163 	const rr::Program						program			(&vertShader, &fragShader);
164 	const rr::MultisamplePixelBufferAccess	colorBuffer	=
165                                                     rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(access);
166 	const rr::RenderTarget					renderTarget	(colorBuffer);
167 	const rr::RenderState					renderState		((rr::ViewportState(colorBuffer)),
168                                                         m_context.getDeviceProperties().limits.subPixelPrecisionBits);
169 	const rr::Renderer						renderer;
170 
171 	const rr::VertexAttrib	vertexAttribs[] =
172 	{
173 		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertices[0]),
174 		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &colors[0])
175 	};
176 
177 	renderer.draw(rr::DrawCommand(renderState, renderTarget, program, DE_LENGTH_OF_ARRAY(vertexAttribs),
178 								  &vertexAttribs[0], rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES,
179                                   (deUint32)vertices.size(), 0)));
180 }
181 
182 class OHOSNativeBufferTestCase : public TestCase
183 {
184 	public:
185 					                OHOSNativeBufferTestCase(tcu::TestContext& context, const char* name,
186                                                              const DrawParams data);
187 									~OHOSNativeBufferTestCase(void);
188 	virtual	void					initPrograms		(SourceCollections& programCollection) const;
189 	virtual void					initShaderSources	(void);
190 	virtual void					checkSupport		(Context& context) const;
191 	virtual TestInstance*			createInstance		(Context& context) const;
192 
193 private:
194 	DrawParams											m_data;
195 	std::string											m_vertShaderSource;
196 	std::string											m_fragShaderSource;
197 };
198 
OHOSNativeBufferTestCase(tcu::TestContext & context,const char * name,const DrawParams data)199 OHOSNativeBufferTestCase::OHOSNativeBufferTestCase (tcu::TestContext& context, const char* name, const DrawParams data)
200 	: vkt::TestCase	(context, name)
201 	, m_data		(data)
202 {
203 	initShaderSources();
204 }
205 
~OHOSNativeBufferTestCase(void)206 OHOSNativeBufferTestCase::~OHOSNativeBufferTestCase	(void)
207 {
208 }
209 
initPrograms(SourceCollections & programCollection) const210 void OHOSNativeBufferTestCase::initPrograms (SourceCollections& programCollection) const
211 {
212 	programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
213 	programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
214 }
215 
checkSupport(Context & context) const216 void OHOSNativeBufferTestCase::checkSupport (Context& context) const
217 {
218 	const InstanceInterface&				vki				= context.getInstanceInterface();
219 	vk::VkPhysicalDevice					physicalDevice	= context.getPhysicalDevice();
220 	const vk::VkPhysicalDeviceProperties	properties		= vk::getPhysicalDeviceProperties(vki, physicalDevice);
221 
222 	// Each layer is exposed as its own color attachment.
223 	if (m_data.m_numLayers > properties.limits.maxColorAttachments)
224 		TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");
225 }
226 
initShaderSources(void)227 void OHOSNativeBufferTestCase::initShaderSources (void)
228 {
229 	std::stringstream vertShader;
230 	vertShader	<< "#version 430\n"
231 				<< "layout(location = 0) in vec4 in_position;\n"
232 				<< "layout(location = 1) in vec4 in_color;\n"
233 				<< "layout(location = 0) out vec4 out_color;\n"
234 
235 				<< "void main() {\n"
236 				<< "    gl_Position  = in_position;\n"
237 				<< "    out_color    = in_color;\n"
238 				<< "}\n";
239 
240 	m_vertShaderSource = vertShader.str();
241 
242 	std::stringstream fragShader;
243 	fragShader	<< "#version 430\n"
244 				<< "layout(location = 0) in vec4 in_color;\n"
245 				<< "layout(location = 0) out vec4 out_color;\n"
246 
247 				<< "void main()\n"
248 				<< "{\n"
249 				<< "    out_color = in_color;\n"
250 				<< "}\n";
251 
252 	m_fragShaderSource = fragShader.str();
253 }
254 
createInstance(Context & context) const255 TestInstance* OHOSNativeBufferTestCase::createInstance (Context& context) const
256 {
257 	return new OHOSNativeBufferTestInstance(context, m_data);
258 }
259 
generateDrawData(void)260 void OHOSNativeBufferTestInstance::generateDrawData (void)
261 {
262 	de::Random rnd (SEED ^ m_data.m_numLayers ^ m_data.m_numVertices);
263 
264 	for (deUint32 i = 0; i < m_data.m_numVertices; i++)
265 	{
266 		const float f0 = rnd.getFloat(-1.0f, 1.0f);
267 		const float f1 = rnd.getFloat(-1.0f, 1.0f);
268 
269 		m_data.m_vertices.push_back(PositionColorVertex(
270 			tcu::Vec4(f0, f1, 1.0f, 1.0f),	// Coord
271 			tcu::randomVec4(rnd)));			// Color
272 	}
273 }
274 
iterate(void)275 tcu::TestStatus OHOSNativeBufferTestInstance::iterate (void)
276 {
277 	const DeviceInterface&						vk						= m_context.getDeviceInterface();
278 	const VkFormat								colorAttachmentFormat	= VK_FORMAT_R8G8B8A8_UNORM;
279 	tcu::TestLog								&log					= m_context.getTestContext().getLog();
280 	const VkQueue								queue					= m_context.getUniversalQueue();
281 	const VkDevice								device					= m_context.getDevice();
282 	const deUint32								queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
283 	const PipelineLayoutCreateInfo				pipelineLayoutCreateInfo;
284 	const Unique<VkPipelineLayout>				pipelineLayout			(createPipelineLayout(vk, device,
285                                                                          &pipelineLayoutCreateInfo));
286 	vector<Move<VkBuffer>>						resultBuffers;
287 	vector<de::MovePtr<Allocation>>				resultBufferAllocations;
288 
289 	for (deUint32 i = 0u; i < m_data.m_numLayers; i++)
290 	{
291 		const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
292 		const VkDeviceSize			pixelSize	= mapVkFormat(colorAttachmentFormat).getPixelSize();
293 		const VkBufferCreateInfo	createInfo	=
294 		{
295 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
296 			DE_NULL,								// const void*			pNext
297 			0u,										// VkBufferCreateFlags	flags
298 			WIDTH * HEIGHT * pixelSize,				// VkDeviceSize			size
299 			bufferUsage,							// VkBufferUsageFlags	usage
300 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
301 			0u,										// uint32_t				queueFamilyIndexCount
302 			DE_NULL									// const uint32_t*		pQueueFamilyIndices
303 		};
304 
305 		resultBuffers.push_back(createBuffer(vk, device, &createInfo));
306 		resultBufferAllocations.push_back(m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk,
307                                           device, *resultBuffers.back()), MemoryRequirement::HostVisible));
308 		VK_CHECK(vk.bindBufferMemory(device, *resultBuffers.back(), resultBufferAllocations.back()->getMemory(),
309                                      resultBufferAllocations.back()->getOffset()));
310 	}
311 
312 	const VkExtent3D							targetImageExtent		= { WIDTH, HEIGHT, 1 };
313 	const ImageCreateInfo						targetImageCreateInfo	(VK_IMAGE_TYPE_2D, colorAttachmentFormat,
314                                                                          targetImageExtent, 1, m_data.m_numLayers,
315                                                                          VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
316                                                                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
317                                                                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
318                                                                          VK_IMAGE_USAGE_TRANSFER_DST_BIT);
319 
320 	OHOSNativeBufferExternalApi* api = OHOSNativeBufferExternalApi::getInstance();
321 
322 	if (!api)
323 		TCU_THROW(NotSupportedError, "OHOS Navite Buffer not supported");
324 
325 	m_context.requireDeviceFunctionality("VK_OHOS_external_memory");
326 
327 	deUint64 requiredUsage = api->VKUsageToOHOSUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
328 
329     if (targetImageCreateInfo.arrayLayers > 1) {
330         TCU_THROW(NotSupportedError, "Required number of layers for OHOS Native Buffer not supported");
331     }
332 
333 	pt::OHOSNativeBufferPtr bufferPtr = api->Allocate(WIDTH, HEIGHT,
334                                                 api->VKFormatToOHOSFormat(colorAttachmentFormat), requiredUsage);
335 
336 	if (bufferPtr.internal == DE_NULL)
337 		TCU_THROW(NotSupportedError, "Required number of layers for OHOS Native Buffer not supported");
338 
339 	NativeHandle			nativeHandle(bufferPtr);
340 	const Unique<VkImage>	colorTargetImage (createExternalImage(vk, device, queueFamilyIndex,
341 											  VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS,
342                                               colorAttachmentFormat, WIDTH, HEIGHT, VK_IMAGE_TILING_OPTIMAL, 0u,
343 											  targetImageCreateInfo.usage, targetImageCreateInfo.mipLevels,
344                                               targetImageCreateInfo.arrayLayers));
345 
346 	deUint32 ohosFormat	= 0;
347 	api->Describe(nativeHandle.GetOhosNativeBuffer(), DE_NULL, DE_NULL, &ohosFormat, DE_NULL, DE_NULL);
348 
349 	VkNativeBufferPropertiesOHOS	ohosProperties		=
350 	{
351 		VK_STRUCTURE_TYPE_NATIVE_BUFFER_PROPERTIES_OHOS,	            // VkStructureType    sType
352 		DE_NULL,														// void*              pNext
353 		0u,																// VkDeviceSize       allocationSize
354 		0u																// uint32_t           memoryTypeBits
355 	};
356 
357 	vk.GetNativeBufferPropertiesOHOS(device, nativeHandle.GetOhosNativeBuffer(), &ohosProperties);
358 
359 	const VkImportNativeBufferInfoOHOS	importInfo		=
360 	{
361 		VK_STRUCTURE_TYPE_IMPORT_NATIVE_BUFFER_INFO_OHOS,	            // VkStructureType            sType
362 		DE_NULL,														// const void*                pNext
363 		nativeHandle.GetOhosNativeBuffer()							    // struct AHardwareBuffer*    buffer
364 	};
365 
366 	const VkMemoryDedicatedAllocateInfo			dedicatedInfo		=
367 	{
368 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,	// VkStructureType    sType
369 		&importInfo,											// const void*        pNext
370 		*colorTargetImage,										// VkImage            image
371 		DE_NULL,												// VkBuffer           buffer
372 	};
373 
374 	const VkMemoryAllocateInfo					allocateInfo		=
375 	{
376 			VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,			// VkStructureType    sType
377 			(const void*)&dedicatedInfo,					// const void*        pNext
378 			ohosProperties.allocationSize,					// VkDeviceSize       allocationSize
379 			chooseMemoryType(ohosProperties.memoryTypeBits)	// uint32_t           memoryTypeIndex
380 	};
381 
382 	const Unique<VkDeviceMemory>				colorImageMemory	(allocateMemory(vk, device, &allocateInfo));
383 	VK_CHECK(vk.bindImageMemory(device, *colorTargetImage, *colorImageMemory, 0u));
384 
385 	vector<Move<VkImageView>>					imageViews;
386 	vector<VkImageView>							colorAttachments;
387 	RenderPassCreateInfo						renderPassCreateInfo;
388 
389 	for (deUint32 i = 0u; i < m_data.m_numLayers; i++)
390 	{
391 		const VkImageSubresourceRange	subresourceRange	=
392 		{
393 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags    aspectMask
394 			0u,							// uint32_t              baseMipLevel
395 			1u,							// uint32_t              levelCount
396 			i,							// uint32_t              baseArrayLayer
397 			1u,							// uint32_t              layerCount
398 		};
399 
400 		const VkImageViewCreateInfo		imageViewCreateInfo	=
401 		{
402 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType            sType
403 			DE_NULL,									// const void*                pNext
404 			0u,											// VkImageViewCreateFlags     flags
405 			*colorTargetImage,							// VkImage                    image
406 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType            viewType
407 			colorAttachmentFormat,						// VkFormat                   format
408 			ComponentMapping(),							// VkComponentMapping         components
409 			subresourceRange							// VkImageSubresourceRange    subresourceRange
410 		};
411 
412 		imageViews.push_back(createImageView(vk, device, &imageViewCreateInfo));
413 		colorAttachments.push_back(*imageViews.back());
414 
415 		renderPassCreateInfo.addAttachment(AttachmentDescription(colorAttachmentFormat,
416 																 VK_SAMPLE_COUNT_1_BIT,
417 																 VK_ATTACHMENT_LOAD_OP_CLEAR,
418 																 VK_ATTACHMENT_STORE_OP_STORE,
419 																 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
420 																 VK_ATTACHMENT_STORE_OP_STORE,
421 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
422 																 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
423 
424 
425 		const VkAttachmentReference		colorAttachmentReference	=
426 		{
427 			i,
428 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
429 		};
430 
431 		renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
432 														   0,
433 														   0,
434 														   DE_NULL,
435 														   1u,
436 														   &colorAttachmentReference,
437 														   DE_NULL,
438 														   AttachmentReference(),
439 														   0,
440 														   DE_NULL));
441 	}
442 
443 	Unique<VkRenderPass>				renderPass				(createRenderPass(vk, device, &renderPassCreateInfo));
444 
445 	const FramebufferCreateInfo			framebufferCreateInfo	(*renderPass, colorAttachments, WIDTH, HEIGHT, 1);
446 	Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, device, &framebufferCreateInfo));
447 
448 	const VkVertexInputBindingDescription vertexInputBindingDescription =
449 	{
450 		0,									// uint32_t             binding
451 		(deUint32)sizeof(tcu::Vec4) * 2,	// uint32_t             stride
452 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate    inputRate
453 	};
454 
455 	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
456 	{
457 
458 		{
459 			0u,								// uint32_t    location
460 			0u,								// uint32_t    binding
461 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat    format
462 			0u								// uint32_t    offset
463 		},
464 		{
465 			1u,								// uint32_t    location
466 			0u,								// uint32_t    binding
467 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat    format
468 			(deUint32)(sizeof(float)* 4),	// uint32_t    offset
469 		}
470 	};
471 
472 	PipelineCreateInfo::VertexInputState	vertexInputState		= PipelineCreateInfo::VertexInputState(1,
473                                                                       &vertexInputBindingDescription, 2,
474                                                                       vertexInputAttributeDescriptions);
475 	const VkDeviceSize						dataSize				= m_data.m_vertices.size() *
476                                                                       sizeof(PositionColorVertex);
477 	de::SharedPtr<Buffer>					vertexBuffer			= Buffer::createAndAlloc(vk, device,
478                                                                       BufferCreateInfo(dataSize,
479 																	  VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
480                                                                       m_context.getDefaultAllocator(),
481                                                                       MemoryRequirement::HostVisible);
482 	deUint8*								ptr						= reinterpret_cast<deUint8*>(
483                                                                       vertexBuffer->getBoundMemory().getHostPtr());
484 
485 	deMemcpy(ptr, &(m_data.m_vertices[0]), static_cast<size_t>(dataSize));
486 	flushAlloc(vk, device, vertexBuffer->getBoundMemory());
487 
488 	const CmdPoolCreateInfo					cmdPoolCreateInfo		(queueFamilyIndex);
489 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, &cmdPoolCreateInfo));
490 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool,
491                                                                      VK_COMMAND_BUFFER_LEVEL_PRIMARY));
492 	const Unique<VkShaderModule>			vs						(createShaderModule(vk, device,
493                                                                      m_context.getBinaryCollection().get("vert"), 0));
494 	const Unique<VkShaderModule>			fs						(createShaderModule(vk, device,
495                                                                      m_context.getBinaryCollection().get("frag"), 0));
496 	VkViewport								viewport				= makeViewport(WIDTH, HEIGHT);
497 	VkRect2D								scissor					= makeRect2D(WIDTH, HEIGHT);
498 	vector<Move<VkPipeline>>				pipelines;
499 
500 	PipelineCreateInfo pipelineCreateInfo(*pipelineLayout, *renderPass, 0, 0);
501 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
502 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
503 	pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
504 	pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
505 	PipelineCreateInfo::ColorBlendState::Attachment	attachment;
506 	pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1u, &attachment));
507 	pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, vector<VkViewport>(1, viewport),
508                                                                   vector<VkRect2D>(1, scissor)));
509 	pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
510 	pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
511 	pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
512 
513 	for (deUint32 i = 0; i < m_data.m_numLayers; i++)
514 	{
515 		pipelineCreateInfo.subpass = i;
516 		pipelines.push_back(createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo));
517 	}
518 
519 	beginCommandBuffer(vk, *cmdBuffer, 0u);
520 
521 	const VkImageMemoryBarrier				initialTransition		=
522 	{
523 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType	sType
524 		DE_NULL,									// const void*		pNext
525 		0u,											// VkAccessFlags	srcAccessMask
526 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags	dstAccessMask
527 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout	oldLayout
528 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout	newLayout
529 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex
530 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex
531 		*colorTargetImage,							// VkImage			image
532         // VkImageSubresourceRange	subresourceRange
533 		makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, m_data.m_numLayers)
534 	};
535 
536 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
537                          (vk::VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0,
538                          (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &initialTransition);
539 
540 	const VkRect2D					renderArea				= makeRect2D(WIDTH, HEIGHT);
541 
542 	vector<VkClearValue>			clearColors	(m_data.m_numLayers, makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f));
543 
544 	const VkRenderPassBeginInfo		renderPassBeginInfo		=
545 	{
546 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType         sType
547 		DE_NULL,									// const void*             pNext
548 		*renderPass,								// VkRenderPass            renderPass
549 		*framebuffer,								// VkFramebuffer           framebuffer
550 		renderArea,									// VkRect2D                renderArea
551 		(deUint32)clearColors.size(),				// deUint32                clearValueCount
552 		clearColors.data(),							// const VkClearValue*     pClearValues
553 	};
554 
555 	vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
556 
557 	const VkDeviceSize						vertexBufferOffset		= 0;
558 	const VkBuffer							vertexBufferObj			= vertexBuffer->object();
559 
560 	vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBufferObj, &vertexBufferOffset);
561 	for (deUint32 i = 0; i < m_data.m_numLayers; i++)
562 	{
563 		if (i != 0)
564 			vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
565 
566 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[i]);
567 		vk.cmdDraw(*cmdBuffer, 9u, 1u, i * 9u, 0u);
568 	}
569 
570 	endRenderPass(vk, *cmdBuffer);
571 
572 	const VkImageMemoryBarrier				imageBarrier			=
573 	{
574 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType
575 		DE_NULL,									// const void*				pNext
576 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask
577 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask
578 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout
579 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout
580 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex
581 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					destQueueFamilyIndex
582 		*colorTargetImage,							// VkImage					image
583         // VkImageSubresourceRange	subresourceRange;
584 		makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, m_data.m_numLayers)
585 	};
586 
587 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
588 						  0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
589 
590 	for (deUint32 i = 0; i < m_data.m_numLayers; i++)
591 	{
592 		const VkImageSubresourceLayers	subresource	=
593 		{
594 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
595 			0u,							// deUint32				mipLevel
596 			i,							// deUint32				baseArrayLayer
597 			1u							// deUint32				layerCount
598 		};
599 
600 		const VkBufferImageCopy			region		=
601 		{
602 			0ull,							// VkDeviceSize					bufferOffset
603 			0u,								// deUint32						bufferRowLength
604 			0u,								// deUint32						bufferImageHeight
605 			subresource,					// VkImageSubresourceLayers		imageSubresource
606 			makeOffset3D(0, 0, 0),			// VkOffset3D					imageOffset
607 			makeExtent3D(WIDTH, HEIGHT, 1u)	// VkExtent3D					imageExtent
608 		};
609 
610 		vk.cmdCopyImageToBuffer(*cmdBuffer, *colorTargetImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *resultBuffers[i],
611                                  1u, &region);
612 
613 		const VkBufferMemoryBarrier	bufferBarrier =
614 		{
615 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
616 			DE_NULL,									// const void*		pNext
617 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
618 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
619 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex
620 			VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex
621 			*resultBuffers[i],							// VkBuffer			buffer
622 			0ull,										// VkDeviceSize		offset
623 			VK_WHOLE_SIZE								// VkDeviceSize		size
624 		};
625 
626 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
627 							  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
628 	}
629 
630 	endCommandBuffer(vk, *cmdBuffer);
631 
632 	submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
633 
634 	qpTestResult res = QP_TEST_RESULT_PASS;
635 
636 	for (deUint32 i = 0; i < m_data.m_numLayers; i++)
637 	{
638 		invalidateMappedMemoryRange(vk, m_context.getDevice(), resultBufferAllocations[i]->getMemory(),
639 									resultBufferAllocations[i]->getOffset(), VK_WHOLE_SIZE);
640 
641 		tcu::TextureLevel					refImage(mapVkFormat(colorAttachmentFormat), WIDTH, HEIGHT);
642 		tcu::clear(refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
643 
644 		vector<tcu::Vec4>					vertices;
645 		vector<tcu::Vec4>					colors;
646 
647 		for (int v = 0; v < 9; v++)
648 		{
649 			int idx = i * 9 + v;
650 			vertices.push_back(m_data.m_vertices[idx].position);
651 			colors.push_back(m_data.m_vertices[idx].color);
652 		}
653 
654 		generateRefImage(refImage.getAccess(), vertices, colors);
655 
656 		const tcu::TextureFormat			format			(mapVkFormat(colorAttachmentFormat));
657 		const void *const					ptrResult		(resultBufferAllocations[i]->getHostPtr());
658 		const tcu::ConstPixelBufferAccess	renderedFrame	(format, WIDTH, HEIGHT, 1, ptrResult);
659 
660 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", refImage.getAccess(), renderedFrame, 0.053f,
661                                tcu::COMPARE_LOG_RESULT))
662 			res = QP_TEST_RESULT_FAIL;
663 	}
664 
665 	return tcu::TestStatus(res, qpGetTestResultName(res));
666 }
667 
CreateOHOSNativeBufferDrawTests(tcu::TestCaseGroup * testGroup)668 void CreateOHOSNativeBufferDrawTests (tcu::TestCaseGroup* testGroup)
669 {
670 	// Draw triangle list to a single layer color buffer
671 	testGroup->addChild(new OHOSNativeBufferTestCase(testGroup->getTestContext(), "triangle_list", DrawParams(9u, 1u)));
672 
673 	// Draw triangle list to a color buffer with three layers
674 	testGroup->addChild(
675         new OHOSNativeBufferTestCase(testGroup->getTestContext(), "triangle_list_layers_3", DrawParams(9u * 3u, 3u)));
676 
677 	// Draw triangle list to a color buffer with five layers
678 	testGroup->addChild(
679         new OHOSNativeBufferTestCase(testGroup->getTestContext(), "triangle_list_layers_5", DrawParams(9u * 5u, 5u)));
680 
681 	// Draw triangle list to a color buffer with eight layers
682 	testGroup->addChild(
683         new OHOSNativeBufferTestCase(testGroup->getTestContext(), "triangle_list_layers_8", DrawParams(9u * 8u, 8u)));
684 
685 }
686 
687 }
688 
CreateOHOSNativeBufferTests(tcu::TestContext & testCtx)689 tcu::TestCaseGroup*	CreateOHOSNativeBufferTests(tcu::TestContext& testCtx)
690 {
691 	// Draw tests using OHOS Native Buffer
692 	return createTestGroup(testCtx, "ohos_native_buffer", CreateOHOSNativeBufferDrawTests);
693 }
694 
695 }
696 }
697