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::__anon1b564c8b0111::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, ®ion);
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