1 /*-------------------------------------------------------------------------
2 * Vulkan CTS Framework
3 * --------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Google Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Utility for generating simple work
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawUtil.hpp"
26 #include "rrMultisamplePixelBufferAccess.hpp"
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkTypeUtil.hpp"
30 #include "rrRenderer.hpp"
31 #include "rrRenderState.hpp"
32 #include "rrPrimitiveTypes.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "deArrayUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "tcuTestLog.hpp"
37
38 namespace vkt
39 {
40 namespace drawutil
41 {
42
43 using namespace de;
44 using namespace tcu;
45 using namespace vk;
46
mapCompareOp(rr::TestFunc compareFunc)47 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
48 {
49 switch (compareFunc)
50 {
51 case rr::TESTFUNC_NEVER: return VK_COMPARE_OP_NEVER;
52 case rr::TESTFUNC_LESS: return VK_COMPARE_OP_LESS;
53 case rr::TESTFUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
54 case rr::TESTFUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
55 case rr::TESTFUNC_GREATER: return VK_COMPARE_OP_GREATER;
56 case rr::TESTFUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
57 case rr::TESTFUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
58 case rr::TESTFUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
59 default:
60 DE_ASSERT(false);
61 }
62 return VK_COMPARE_OP_LAST;
63 }
64
mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology & primitiveTopology)65 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
66 {
67 static const rr::PrimitiveType primitiveTypeTable[] =
68 {
69 rr::PRIMITIVETYPE_POINTS,
70 rr::PRIMITIVETYPE_LINES,
71 rr::PRIMITIVETYPE_LINE_STRIP,
72 rr::PRIMITIVETYPE_TRIANGLES,
73 rr::PRIMITIVETYPE_TRIANGLE_STRIP,
74 rr::PRIMITIVETYPE_TRIANGLE_FAN,
75 rr::PRIMITIVETYPE_LINES_ADJACENCY,
76 rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY,
77 rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY,
78 rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY
79 };
80
81 return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
82 }
83
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)84 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
85 const VkBufferUsageFlags usage)
86 {
87 const VkBufferCreateInfo bufferCreateInfo =
88 {
89 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
90 DE_NULL, // const void* pNext;
91 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
92 bufferSize, // VkDeviceSize size;
93 usage, // VkBufferUsageFlags usage;
94 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
95 0u, // deUint32 queueFamilyIndexCount;
96 DE_NULL, // const deUint32* pQueueFamilyIndices;
97 };
98 return bufferCreateInfo;
99 }
100
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)101 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
102 const VkAccessFlags dstAccessMask,
103 const VkBuffer buffer,
104 const VkDeviceSize offset,
105 const VkDeviceSize bufferSizeBytes)
106 {
107 const VkBufferMemoryBarrier barrier =
108 {
109 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
110 DE_NULL, // const void* pNext;
111 srcAccessMask, // VkAccessFlags srcAccessMask;
112 dstAccessMask, // VkAccessFlags dstAccessMask;
113 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
114 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
115 buffer, // VkBuffer buffer;
116 offset, // VkDeviceSize offset;
117 bufferSizeBytes, // VkDeviceSize size;
118 };
119 return barrier;
120 }
121
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)122 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
123 const VkAccessFlags dstAccessMask,
124 const VkImageLayout oldLayout,
125 const VkImageLayout newLayout,
126 const VkImage image,
127 const VkImageSubresourceRange subresourceRange)
128 {
129 const VkImageMemoryBarrier barrier =
130 {
131 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
132 DE_NULL, // const void* pNext;
133 srcAccessMask, // VkAccessFlags outputMask;
134 dstAccessMask, // VkAccessFlags inputMask;
135 oldLayout, // VkImageLayout oldLayout;
136 newLayout, // VkImageLayout newLayout;
137 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
138 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
139 image, // VkImage image;
140 subresourceRange, // VkImageSubresourceRange subresourceRange;
141 };
142 return barrier;
143 }
144
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)145 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
146 {
147 const VkCommandPoolCreateInfo info =
148 {
149 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
150 DE_NULL, // const void* pNext;
151 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
152 queueFamilyIndex, // deUint32 queueFamilyIndex;
153 };
154 return createCommandPool(vk, device, &info);
155 }
156
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)157 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
158 {
159 const VkCommandBufferAllocateInfo info =
160 {
161 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
162 DE_NULL, // const void* pNext;
163 commandPool, // VkCommandPool commandPool;
164 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
165 1u, // deUint32 commandBufferCount;
166 };
167 return allocateCommandBuffer(vk, device, &info);
168 }
169
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)170 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
171 const VkDevice device,
172 const VkDescriptorPool descriptorPool,
173 const VkDescriptorSetLayout setLayout)
174 {
175 const VkDescriptorSetAllocateInfo info =
176 {
177 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
178 DE_NULL, // const void* pNext;
179 descriptorPool, // VkDescriptorPool descriptorPool;
180 1u, // deUint32 descriptorSetCount;
181 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
182 };
183 return allocateDescriptorSet(vk, device, &info);
184 }
185
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)186 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
187 const VkDevice device,
188 const VkDescriptorSetLayout descriptorSetLayout)
189 {
190 const VkPipelineLayoutCreateInfo info =
191 {
192 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
193 DE_NULL, // const void* pNext;
194 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
195 1u, // deUint32 setLayoutCount;
196 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
197 0u, // deUint32 pushConstantRangeCount;
198 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
199 };
200 return createPipelineLayout(vk, device, &info);
201 }
202
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)203 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
204 const VkDevice device)
205 {
206 const VkPipelineLayoutCreateInfo info =
207 {
208 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
211 0u, // deUint32 setLayoutCount;
212 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
213 0u, // deUint32 pushConstantRangeCount;
214 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
215 };
216 return createPipelineLayout(vk, device, &info);
217 }
218
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)219 Move<VkImageView> makeImageView (const DeviceInterface& vk,
220 const VkDevice device,
221 const VkImage image,
222 const VkImageViewType viewType,
223 const VkFormat format,
224 const VkImageSubresourceRange subresourceRange)
225 {
226 const VkImageViewCreateInfo imageViewParams =
227 {
228 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
229 DE_NULL, // const void* pNext;
230 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
231 image, // VkImage image;
232 viewType, // VkImageViewType viewType;
233 format, // VkFormat format;
234 makeComponentMappingRGBA(), // VkComponentMapping components;
235 subresourceRange, // VkImageSubresourceRange subresourceRange;
236 };
237 return createImageView(vk, device, &imageViewParams);
238 }
239
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)240 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers,
241 const VkExtent3D extent)
242 {
243 const VkBufferImageCopy copyParams =
244 {
245 0ull, // VkDeviceSize bufferOffset;
246 0u, // deUint32 bufferRowLength;
247 0u, // deUint32 bufferImageHeight;
248 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
249 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
250 extent, // VkExtent3D imageExtent;
251 };
252 return copyParams;
253 }
254
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)255 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
256 {
257 const VkCommandBufferBeginInfo info =
258 {
259 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
260 DE_NULL, // const void* pNext;
261 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
262 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
263 };
264 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
265 }
266
endCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)267 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
268 {
269 VK_CHECK(vk.endCommandBuffer(commandBuffer));
270 }
271
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer)272 void submitCommandsAndWait (const DeviceInterface& vk,
273 const VkDevice device,
274 const VkQueue queue,
275 const VkCommandBuffer commandBuffer)
276 {
277 const VkFenceCreateInfo fenceInfo =
278 {
279 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
280 DE_NULL, // const void* pNext;
281 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags;
282 };
283 const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
284
285 const VkSubmitInfo submitInfo =
286 {
287 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
288 DE_NULL, // const void* pNext;
289 0u, // uint32_t waitSemaphoreCount;
290 DE_NULL, // const VkSemaphore* pWaitSemaphores;
291 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
292 1u, // uint32_t commandBufferCount;
293 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
294 0u, // uint32_t signalSemaphoreCount;
295 DE_NULL, // const VkSemaphore* pSignalSemaphores;
296 };
297 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
298 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
299 }
300
getPrimitiveTopologyShortName(const VkPrimitiveTopology topology)301 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
302 {
303 std::string name(getPrimitiveTopologyName(topology));
304 return de::toLower(name.substr(22));
305 }
306
DrawState(const vk::VkPrimitiveTopology topology_,deUint32 renderWidth_,deUint32 renderHeight_)307 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_)
308 : topology (topology_)
309 , colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
310 , renderSize (tcu::UVec2(renderWidth_, renderHeight_))
311 , depthClampEnable (false)
312 , depthTestEnable (false)
313 , depthWriteEnable (false)
314 , compareOp (rr::TESTFUNC_LESS)
315 , depthBoundsTestEnable (false)
316 , blendEnable (false)
317 , lineWidth (1.0)
318 , numPatchControlPoints (0)
319 , numSamples (VK_SAMPLE_COUNT_1_BIT)
320 , sampleShadingEnable (false)
321 {
322 DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
323 }
324
~ReferenceDrawContext(void)325 ReferenceDrawContext::~ReferenceDrawContext (void)
326 {
327 }
328
draw(void)329 void ReferenceDrawContext::draw (void)
330 {
331 m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
332 tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
333
334 {
335 const rr::Program program(&m_vertexShader, &m_fragmentShader);
336 const rr::MultisamplePixelBufferAccess referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
337 const rr::RenderTarget renderTarget(referenceColorBuffer);
338 const rr::RenderState renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
339 const rr::Renderer renderer;
340 const rr::VertexAttrib vertexAttrib[] =
341 {
342 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
343 };
344
345 renderer.draw(rr::DrawCommand( renderState,
346 renderTarget,
347 program,
348 DE_LENGTH_OF_ARRAY(vertexAttrib),
349 &vertexAttrib[0],
350 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
351
352 }
353
354 }
355
getColorPixels(void) const356 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
357 {
358 return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
359 m_refImage.getAccess().getWidth(),
360 m_refImage.getAccess().getHeight(),
361 m_refImage.getAccess().getDepth(),
362 m_refImage.getAccess().getDataPtr());
363 }
364
VulkanDrawContext(Context & context,const DrawState & drawState,const DrawCallData & drawCallData,const VulkanProgram & vulkanProgram)365 VulkanDrawContext::VulkanDrawContext ( Context& context,
366 const DrawState& drawState,
367 const DrawCallData& drawCallData,
368 const VulkanProgram& vulkanProgram)
369 : DrawContext (drawState, drawCallData)
370 , m_context (context)
371 , m_program (vulkanProgram)
372 {
373 const DeviceInterface& vk = m_context.getDeviceInterface();
374 const VkDevice device = m_context.getDevice();
375 Allocator& allocator = m_context.getDefaultAllocator();
376 VkImageSubresourceRange colorSubresourceRange;
377 Move<VkSampler> sampler;
378
379 // Command buffer
380 {
381 m_cmdPool = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
382 m_cmdBuffer = makeCommandBuffer(vk, device, *m_cmdPool);
383 }
384
385 // Color attachment image
386 {
387 const VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
388 colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
389 const VkImageCreateInfo imageCreateInfo =
390 {
391 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
392 DE_NULL, // const void* pNext;
393 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
394 VK_IMAGE_TYPE_2D, // VkImageType imageType;
395 m_drawState.colorFormat, // VkFormat format;
396 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u), // VkExtent3D extent;
397 1u, // uint32_t mipLevels;
398 1u, // uint32_t arrayLayers;
399 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
400 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
401 usage, // VkImageUsageFlags usage;
402 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
403 0u, // uint32_t queueFamilyIndexCount;
404 DE_NULL, // const uint32_t* pQueueFamilyIndices;
405 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
406 };
407
408 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
409 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
410
411 // Buffer to copy attachment data after rendering
412
413 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
414 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
415 vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
416
417 {
418 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
419 deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
420 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
421 }
422 }
423
424 // Vertex buffer
425 {
426 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
427 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
428 vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
429
430 const Allocation& alloc = m_vertexBuffer->getAllocation();
431 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
432 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
433 }
434
435 // bind descriptor sets
436 {
437 if (!vulkanProgram.descriptorSetLayout)
438 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
439 else
440 m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout);
441 }
442
443 // Renderpass
444 {
445 std::vector<VkAttachmentDescription> attachmentDescriptions;
446 const VkAttachmentDescription attachDescriptors[] =
447 {
448 {
449 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
450 m_drawState.colorFormat, // VkFormat format;
451 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
452 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
453 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
454 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
455 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
456 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
457 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
458 },
459 {
460 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
461 m_drawState.depthFormat, // VkFormat format
462 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples
463 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
464 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
465 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
466 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
467 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
468 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout
469
470 }
471 };
472
473 const VkAttachmentReference attachmentReferences[] =
474 {
475 {
476 0u, // uint32_t attachment
477 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
478 },
479 {
480 1u, // uint32_t attachment
481 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
482 },
483 {
484 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
485 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
486 }
487 };
488
489 attachmentDescriptions.push_back(attachDescriptors[0]);
490 if (!!vulkanProgram.depthImageView)
491 attachmentDescriptions.push_back(attachDescriptors[1]);
492
493 deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2;
494 const VkSubpassDescription subpassDescription =
495 {
496 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
497 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
498 0u, // deUint32 inputAttachmentCount;
499 DE_NULL, // const VkAttachmentReference* pInputAttachments;
500 1u, // deUint32 colorAttachmentCount;
501 &attachmentReferences[0], // const VkAttachmentReference* pColorAttachments;
502 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
503 &attachmentReferences[depthReferenceNdx], // const VkAttachmentReference* pDepthStencilAttachment;
504 0u, // deUint32 preserveAttachmentCount;
505 DE_NULL // const deUint32* pPreserveAttachments;
506 };
507
508 const VkRenderPassCreateInfo renderPassInfo =
509 {
510 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
511 DE_NULL, // const void* pNext;
512 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
513 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
514 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
515 1u, // deUint32 subpassCount;
516 &subpassDescription, // const VkSubpassDescription* pSubpasses;
517 0u, // deUint32 dependencyCount;
518 DE_NULL // const VkSubpassDependency* pDependencies;
519 };
520
521 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
522 }
523
524 // Framebuffer
525 {
526 std::vector<VkImageView> attachmentBindInfos;
527 deUint32 numAttachments;
528 attachmentBindInfos.push_back(*m_colorImageView);
529 if (!!vulkanProgram.depthImageView)
530 attachmentBindInfos.push_back(vulkanProgram.depthImageView);
531
532 numAttachments = (deUint32)(attachmentBindInfos.size());
533 const VkFramebufferCreateInfo framebufferInfo = {
534 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
535 DE_NULL, // const void* pNext;
536 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
537 *m_renderPass, // VkRenderPass renderPass;
538 numAttachments, // uint32_t attachmentCount;
539 &attachmentBindInfos[0], // const VkImageView* pAttachments;
540 m_drawState.renderSize.x(), // uint32_t width;
541 m_drawState.renderSize.y(), // uint32_t height;
542 1u, // uint32_t layers;
543 };
544
545 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
546 }
547
548 // Graphics pipeline
549 {
550 const deUint32 vertexStride = sizeof(Vec4);
551 const VkFormat vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
552
553 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
554
555 const VkVertexInputBindingDescription bindingDesc =
556 {
557 0u, // uint32_t binding;
558 vertexStride, // uint32_t stride;
559 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
560 };
561 const VkVertexInputAttributeDescription attributeDesc =
562 {
563 0u, // uint32_t location;
564 0u, // uint32_t binding;
565 vertexFormat, // VkFormat format;
566 0u, // uint32_t offset;
567 };
568
569 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
570 {
571 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
572 DE_NULL, // const void* pNext;
573 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
574 1u, // uint32_t vertexBindingDescriptionCount;
575 &bindingDesc, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
576 1u, // uint32_t vertexAttributeDescriptionCount;
577 &attributeDesc, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
578 };
579
580 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
581 {
582 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
583 DE_NULL, // const void* pNext;
584 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
585 m_drawState.topology, // VkPrimitiveTopology topology;
586 VK_FALSE, // VkBool32 primitiveRestartEnable;
587 };
588
589 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
590 {
591 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
592 DE_NULL, // const void* pNext;
593 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
594 m_drawState.numPatchControlPoints, // uint32_t patchControlPoints;
595 };
596
597 const VkViewport viewport = makeViewport(
598 0.0f, 0.0f,
599 static_cast<float>(m_drawState.renderSize.x()), static_cast<float>(m_drawState.renderSize.y()),
600 0.0f, 1.0f);
601
602 const VkRect2D scissor = {
603 makeOffset2D(0, 0),
604 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()),
605 };
606
607 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
608 {
609 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
610 DE_NULL, // const void* pNext;
611 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
612 1u, // uint32_t viewportCount;
613 &viewport, // const VkViewport* pViewports;
614 1u, // uint32_t scissorCount;
615 &scissor, // const VkRect2D* pScissors;
616 };
617
618 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
619 {
620 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
621 DE_NULL, // const void* pNext;
622 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
623 m_drawState.depthClampEnable, // VkBool32 depthClampEnable;
624 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
625 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
626 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
627 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
628 VK_FALSE, // VkBool32 depthBiasEnable;
629 0.0f, // float depthBiasConstantFactor;
630 0.0f, // float depthBiasClamp;
631 0.0f, // float depthBiasSlopeFactor;
632 m_drawState.lineWidth, // float lineWidth;
633 };
634
635 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
636 {
637 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
638 DE_NULL, // const void* pNext;
639 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
640 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits rasterizationSamples;
641 m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable;
642 m_drawState.sampleShadingEnable ? 1.0f : 0.0f, // float minSampleShading;
643 DE_NULL, // const VkSampleMask* pSampleMask;
644 VK_FALSE, // VkBool32 alphaToCoverageEnable;
645 VK_FALSE // VkBool32 alphaToOneEnable;
646 };
647
648 const VkStencilOpState stencilOpState = makeStencilOpState(
649 VK_STENCIL_OP_KEEP, // stencil fail
650 VK_STENCIL_OP_KEEP, // depth & stencil pass
651 VK_STENCIL_OP_KEEP, // depth only fail
652 VK_COMPARE_OP_NEVER, // compare op
653 0u, // compare mask
654 0u, // write mask
655 0u); // reference
656
657 if (m_drawState.depthBoundsTestEnable && context.getDeviceFeatures().depthBounds)
658 TCU_THROW(NotSupportedError, "depthBounds not supported");
659
660 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
661 {
662 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
663 DE_NULL, // const void* pNext;
664 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
665 m_drawState.depthTestEnable, // VkBool32 depthTestEnable;
666 m_drawState.depthWriteEnable, // VkBool32 depthWriteEnable;
667 mapCompareOp(m_drawState.compareOp), // VkCompareOp depthCompareOp;
668 m_drawState.depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable
669 VK_FALSE, // VkBool32 stencilTestEnable;
670 stencilOpState, // VkStencilOpState front;
671 stencilOpState, // VkStencilOpState back;
672 0.0f, // float minDepthBounds;
673 1.0f, // float maxDepthBounds;
674 };
675
676 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
677 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
678 {
679 m_drawState.blendEnable, // VkBool32 blendEnable;
680 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
681 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
682 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
683 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
684 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
685 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
686 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
687 };
688
689 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
690 {
691 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
692 DE_NULL, // const void* pNext;
693 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
694 VK_FALSE, // VkBool32 logicOpEnable;
695 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
696 1u, // deUint32 attachmentCount;
697 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
698 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
699 };
700
701 // Create shader stages
702
703 std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
704 VkShaderStageFlags stageFlags = (VkShaderStageFlags)0;
705
706 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
707 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
708 {
709 m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
710
711 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
712 {
713 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
714 DE_NULL, // const void* pNext;
715 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
716 m_program.shaders[shaderNdx].stage, // VkShaderStageFlagBits stage;
717 *m_shaderModules[shaderNdx], // VkShaderModule module;
718 "main", // const char* pName;
719 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
720 };
721
722 shaderStages.push_back(pipelineShaderStageInfo);
723 stageFlags |= m_program.shaders[shaderNdx].stage;
724 }
725
726 DE_ASSERT(
727 (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
728 (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
729
730 const bool tessellationEnabled = (m_drawState.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
731 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
732 {
733 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
734 DE_NULL, // const void* pNext;
735 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
736 static_cast<deUint32>(shaderStages.size()), // deUint32 stageCount;
737 &shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
738 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
739 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
740 (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
741 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
742 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
743 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
744 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
745 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
746 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
747 *m_pipelineLayout, // VkPipelineLayout layout;
748 *m_renderPass, // VkRenderPass renderPass;
749 0u, // deUint32 subpass;
750 DE_NULL, // VkPipeline basePipelineHandle;
751 0, // deInt32 basePipelineIndex;
752 };
753
754 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
755 }
756
757 // Record commands
758 {
759 const VkDeviceSize zeroOffset = 0ull;
760
761 beginCommandBuffer(vk, *m_cmdBuffer);
762 if (!!vulkanProgram.descriptorSet)
763 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL);
764
765 // Begin render pass
766 {
767 std::vector<VkClearValue> clearValues;
768
769 clearValues.push_back(makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
770 if (!!vulkanProgram.depthImageView)
771 clearValues.push_back(makeClearValueDepthStencil(0.0, 0));
772
773 const VkRect2D renderArea =
774 {
775 makeOffset2D(0, 0),
776 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y())
777 };
778
779 const VkRenderPassBeginInfo renderPassBeginInfo = {
780 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
781 DE_NULL, // const void* pNext;
782 *m_renderPass, // VkRenderPass renderPass;
783 *m_framebuffer, // VkFramebuffer framebuffer;
784 renderArea, // VkRect2D renderArea;
785 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
786 &clearValues[0], // const VkClearValue* pClearValues;
787 };
788
789 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
790 }
791
792 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
793 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
794
795 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
796 vk.cmdEndRenderPass(*m_cmdBuffer);
797
798 // Barrier: draw -> copy from image
799 {
800 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
801 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
802 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
803 **m_colorImage, colorSubresourceRange);
804
805 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
806 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
807 }
808
809 // Resolve multisample image
810 {
811 if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
812 {
813 const VkImageResolve imageResolve =
814 {
815 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
816 { 0, 0, 0},
817 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
818 { 0, 0, 0},
819 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
820 };
821
822 const VkImageCreateInfo resolveImageCreateInfo =
823 {
824 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
825 DE_NULL, // const void* pNext
826 (VkImageCreateFlags)0, // VkImageCreateFlags flags
827 VK_IMAGE_TYPE_2D, // VkImageType imageType
828 m_drawState.colorFormat, // VkFormat format
829 makeExtent3D(m_drawState.renderSize.x(), // VkExtent3D extent;
830 m_drawState.renderSize.y(), 1u),
831 1u, // uint32_t mipLevels
832 1u, // uint32_t arrayLayers
833 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
834 VK_IMAGE_TILING_OPTIMAL, // VkImaageTiling tiling
835 VK_IMAGE_USAGE_TRANSFER_DST_BIT | // VkImageUsageFlags usage
836 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
837 VK_SHARING_MODE_EXCLUSIVE, // VkSharingModeExclusive sharingMode
838 0u, // uint32_t queueFamilyIndexCount
839 DE_NULL, // const uint32_t* pQueueFamilyIndices
840 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
841 };
842
843 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
844
845 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
846 0u, VK_ACCESS_TRANSFER_READ_BIT,
847 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
848 **m_resolveImage, colorSubresourceRange);
849
850 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
851 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
852
853 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
854 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
855
856 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
857 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
858 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
859 **m_resolveImage, colorSubresourceRange);
860
861 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
862 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
863 }
864 else
865 m_resolveImage = m_colorImage;
866
867 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
868 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
869 vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, ©Region);
870 }
871
872 // Barrier: copy to buffer -> host read
873 {
874 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
875 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
876 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
877
878 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
879 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
880 }
881
882 endCommandBuffer(vk, *m_cmdBuffer);
883 }
884 }
885
~VulkanDrawContext(void)886 VulkanDrawContext::~VulkanDrawContext (void)
887 {
888 }
889
draw(void)890 void VulkanDrawContext::draw (void)
891 {
892 const DeviceInterface& vk = m_context.getDeviceInterface();
893 const VkDevice device = m_context.getDevice();
894 const VkQueue queue = m_context.getUniversalQueue();
895 tcu::TestLog& log = m_context.getTestContext().getLog();
896
897 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
898
899 log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
900 }
901
getColorPixels(void) const902 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
903 {
904 const DeviceInterface& vk = m_context.getDeviceInterface();
905 const VkDevice device = m_context.getDevice();
906
907 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
908 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
909
910 return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
911 }
912 } // drawutil
913 } // vkt
914