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