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