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 47using namespace vkt::ExternalMemoryUtil; 48using namespace vk; 49using std::vector; 50 51namespace vkt 52{ 53namespace Draw 54{ 55namespace 56{ 57 58const deUint32 SEED = 0xc2a39fu; 59 60struct DrawParams 61{ 62 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 71class PassthruVertShader : public rr::VertexShader 72{ 73public: 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 82 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 99class PassthruFragShader : public rr::FragmentShader 100{ 101public: 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 109 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 124class OHOSNativeBufferTestInstance : public TestInstance 125{ 126public: 127 OHOSNativeBufferTestInstance (Context& context, DrawParams data); 128 ~OHOSNativeBufferTestInstance (void); 129 130 tcu::TestStatus iterate (void); 131 132private: 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 146OHOSNativeBufferTestInstance::OHOSNativeBufferTestInstance (Context& context, DrawParams data) 147 : vkt::TestInstance (context) 148 , m_data (data) 149{ 150 generateDrawData(); 151} 152 153OHOSNativeBufferTestInstance::~OHOSNativeBufferTestInstance (void) 154{ 155} 156 157void 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 182class 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 193private: 194 DrawParams m_data; 195 std::string m_vertShaderSource; 196 std::string m_fragShaderSource; 197}; 198 199OHOSNativeBufferTestCase::OHOSNativeBufferTestCase (tcu::TestContext& context, const char* name, const DrawParams data) 200 : vkt::TestCase (context, name) 201 , m_data (data) 202{ 203 initShaderSources(); 204} 205 206OHOSNativeBufferTestCase::~OHOSNativeBufferTestCase (void) 207{ 208} 209 210void 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 216void 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 227void 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 255TestInstance* OHOSNativeBufferTestCase::createInstance (Context& context) const 256{ 257 return new OHOSNativeBufferTestInstance(context, m_data); 258} 259 260void 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 275tcu::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 668void 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 689tcu::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