1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Google Inc.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Utility for generating simple work
23 *//*--------------------------------------------------------------------*/
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 "tcuTestLog.hpp"
35 #include "deArrayUtil.hpp"
36 #include "vkBuilderUtil.hpp"
47 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
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;
62 return VK_COMPARE_OP_LAST;
65 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
67 static const rr::PrimitiveType primitiveTypeTable[] =
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
81 return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
84 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
85 const VkBufferUsageFlags usage)
87 const VkBufferCreateInfo bufferCreateInfo =
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;
98 return bufferCreateInfo;
101 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
102 const VkAccessFlags dstAccessMask,
103 const VkBuffer buffer,
104 const VkDeviceSize offset,
105 const VkDeviceSize bufferSizeBytes)
107 const VkBufferMemoryBarrier barrier =
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;
122 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
123 const VkAccessFlags dstAccessMask,
124 const VkImageLayout oldLayout,
125 const VkImageLayout newLayout,
127 const VkImageSubresourceRange subresourceRange)
129 const VkImageMemoryBarrier barrier =
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;
145 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
147 const VkCommandPoolCreateInfo info =
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;
154 return createCommandPool(vk, device, &info);
157 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
159 const VkCommandBufferAllocateInfo info =
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;
167 return allocateCommandBuffer(vk, device, &info);
170 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
171 const VkDevice device,
172 const VkDescriptorPool descriptorPool,
173 const VkDescriptorSetLayout setLayout)
175 const VkDescriptorSetAllocateInfo info =
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;
183 return allocateDescriptorSet(vk, device, &info);
186 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
187 const VkDevice device,
188 const VkDescriptorSetLayout descriptorSetLayout)
190 const VkPipelineLayoutCreateInfo info =
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;
200 return createPipelineLayout(vk, device, &info);
203 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
204 const VkDevice device)
206 const VkPipelineLayoutCreateInfo info =
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;
216 return createPipelineLayout(vk, device, &info);
219 Move<VkImageView> makeImageView (const DeviceInterface& vk,
220 const VkDevice device,
222 const VkImageViewType viewType,
223 const VkFormat format,
224 const VkImageSubresourceRange subresourceRange)
226 const VkImageViewCreateInfo imageViewParams =
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;
237 return createImageView(vk, device, &imageViewParams);
240 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers,
241 const VkExtent3D extent)
243 const VkBufferImageCopy copyParams =
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;
255 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
257 const VkCommandBufferBeginInfo info =
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;
264 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
267 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
269 VK_CHECK(vk.endCommandBuffer(commandBuffer));
272 void submitCommandsAndWait (const DeviceInterface& vk,
273 const VkDevice device,
275 const VkCommandBuffer commandBuffer)
277 const VkFenceCreateInfo fenceInfo =
279 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
280 DE_NULL, // const void* pNext;
281 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags;
283 const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
285 const VkSubmitInfo submitInfo =
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;
297 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
298 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
301 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
303 std::string name(getPrimitiveTopologyName(topology));
304 return de::toLower(name.substr(22));
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 , blendEnable (false)
317 , numPatchControlPoints (0)
318 , numSamples (VK_SAMPLE_COUNT_1_BIT)
319 , sampleShadingEnable (false)
321 DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
324 ReferenceDrawContext::~ReferenceDrawContext (void)
328 void ReferenceDrawContext::draw (void)
330 m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
331 tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
334 const rr::Program program(&m_vertexShader, &m_fragmentShader);
335 const rr::MultisamplePixelBufferAccess referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
336 const rr::RenderTarget renderTarget(referenceColorBuffer);
337 const rr::RenderState renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
338 const rr::Renderer renderer;
339 const rr::VertexAttrib vertexAttrib[] =
341 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
344 renderer.draw(rr::DrawCommand( renderState,
347 DE_LENGTH_OF_ARRAY(vertexAttrib),
349 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
355 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
357 return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
358 m_refImage.getAccess().getWidth(),
359 m_refImage.getAccess().getHeight(),
360 m_refImage.getAccess().getDepth(),
361 m_refImage.getAccess().getDataPtr());
364 VulkanDrawContext::VulkanDrawContext ( Context& context,
365 const DrawState& drawState,
366 const DrawCallData& drawCallData,
367 VulkanProgram& vulkanProgram)
368 : DrawContext (drawState, drawCallData)
369 , m_context (context)
370 , m_program (vulkanProgram)
372 const DeviceInterface& vk = m_context.getDeviceInterface();
373 const VkDevice device = m_context.getDevice();
374 Allocator& allocator = m_context.getDefaultAllocator();
375 VkImageSubresourceRange colorSubresourceRange;
376 Move<VkSampler> sampler;
380 m_cmdPool = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
381 m_cmdBuffer = makeCommandBuffer(vk, device, *m_cmdPool);
384 // Color attachment image
386 const VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
387 colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
388 const VkImageCreateInfo imageCreateInfo =
390 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
391 DE_NULL, // const void* pNext;
392 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
393 VK_IMAGE_TYPE_2D, // VkImageType imageType;
394 m_drawState.colorFormat, // VkFormat format;
395 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u), // VkExtent3D extent;
396 1u, // uint32_t mipLevels;
397 1u, // uint32_t arrayLayers;
398 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
399 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
400 usage, // VkImageUsageFlags usage;
401 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
402 0u, // uint32_t queueFamilyIndexCount;
403 DE_NULL, // const uint32_t* pQueueFamilyIndices;
404 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
407 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
408 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
410 // Buffer to copy attachment data after rendering
412 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
413 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
414 vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
417 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
418 deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
419 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
425 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
426 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
427 vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
429 const Allocation& alloc = m_vertexBuffer->getAllocation();
430 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
431 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
434 // bind descriptor sets
436 if (!vulkanProgram.descriptorSetLayout)
437 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
439 m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout.get());
444 std::vector<VkAttachmentDescription> attachmentDescriptions;
445 const VkAttachmentDescription attachDescriptors[] =
448 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
449 m_drawState.colorFormat, // VkFormat format;
450 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
451 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
452 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
453 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
454 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
455 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
456 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
459 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
460 m_drawState.depthFormat, // VkFormat format
461 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples
462 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
463 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
464 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
465 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
466 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
467 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout
472 const VkAttachmentReference attachmentReferences[] =
475 0u, // uint32_t attachment
476 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
479 1u, // uint32_t attachment
480 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
483 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
484 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
488 attachmentDescriptions.push_back(attachDescriptors[0]);
489 if (vulkanProgram.depthImageView)
490 attachmentDescriptions.push_back(attachDescriptors[1]);
492 deUint32 depthReferenceNdx = vulkanProgram.depthImageView ? 1 : 2;
493 const VkSubpassDescription subpassDescription =
495 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
496 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
497 0u, // deUint32 inputAttachmentCount;
498 DE_NULL, // const VkAttachmentReference* pInputAttachments;
499 1u, // deUint32 colorAttachmentCount;
500 &attachmentReferences[0], // const VkAttachmentReference* pColorAttachments;
501 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
502 &attachmentReferences[depthReferenceNdx], // const VkAttachmentReference* pDepthStencilAttachment;
503 0u, // deUint32 preserveAttachmentCount;
504 DE_NULL // const deUint32* pPreserveAttachments;
507 const VkRenderPassCreateInfo renderPassInfo =
509 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
510 DE_NULL, // const void* pNext;
511 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
512 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
513 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
514 1u, // deUint32 subpassCount;
515 &subpassDescription, // const VkSubpassDescription* pSubpasses;
516 0u, // deUint32 dependencyCount;
517 DE_NULL // const VkSubpassDependency* pDependencies;
520 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
525 std::vector<VkImageView> attachmentBindInfos;
526 deUint32 numAttachments;
527 attachmentBindInfos.push_back(*m_colorImageView);
528 if (vulkanProgram.depthImageView)
529 attachmentBindInfos.push_back(*vulkanProgram.depthImageView);
531 numAttachments = (deUint32)(attachmentBindInfos.size());
532 const VkFramebufferCreateInfo framebufferInfo = {
533 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
536 *m_renderPass, // VkRenderPass renderPass;
537 numAttachments, // uint32_t attachmentCount;
538 &attachmentBindInfos[0], // const VkImageView* pAttachments;
539 m_drawState.renderSize.x(), // uint32_t width;
540 m_drawState.renderSize.y(), // uint32_t height;
541 1u, // uint32_t layers;
544 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
549 const deUint32 vertexStride = sizeof(Vec4);
550 const VkFormat vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT;
552 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
554 const VkVertexInputBindingDescription bindingDesc =
556 0u, // uint32_t binding;
557 vertexStride, // uint32_t stride;
558 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
560 const VkVertexInputAttributeDescription attributeDesc =
562 0u, // uint32_t location;
563 0u, // uint32_t binding;
564 vertexFormat, // VkFormat format;
565 0u, // uint32_t offset;
568 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
570 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
571 DE_NULL, // const void* pNext;
572 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
573 1u, // uint32_t vertexBindingDescriptionCount;
574 &bindingDesc, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
575 1u, // uint32_t vertexAttributeDescriptionCount;
576 &attributeDesc, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
579 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
581 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
582 DE_NULL, // const void* pNext;
583 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
584 m_drawState.topology, // VkPrimitiveTopology topology;
585 VK_FALSE, // VkBool32 primitiveRestartEnable;
588 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
590 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
591 DE_NULL, // const void* pNext;
592 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
593 m_drawState.numPatchControlPoints, // uint32_t patchControlPoints;
596 const VkViewport viewport = makeViewport(
598 static_cast<float>(m_drawState.renderSize.x()), static_cast<float>(m_drawState.renderSize.y()),
601 const VkRect2D scissor = {
603 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()),
606 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
608 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
609 DE_NULL, // const void* pNext;
610 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
611 1u, // uint32_t viewportCount;
612 &viewport, // const VkViewport* pViewports;
613 1u, // uint32_t scissorCount;
614 &scissor, // const VkRect2D* pScissors;
617 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
619 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
620 DE_NULL, // const void* pNext;
621 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
622 m_drawState.depthClampEnable, // VkBool32 depthClampEnable;
623 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
624 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
625 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
626 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
627 VK_FALSE, // VkBool32 depthBiasEnable;
628 0.0f, // float depthBiasConstantFactor;
629 0.0f, // float depthBiasClamp;
630 0.0f, // float depthBiasSlopeFactor;
631 m_drawState.lineWidth, // float lineWidth;
634 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
636 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
637 DE_NULL, // const void* pNext;
638 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
639 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits rasterizationSamples;
640 m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable;
641 m_drawState.sampleShadingEnable ? 1.0f : 0.0f, // float minSampleShading;
642 DE_NULL, // const VkSampleMask* pSampleMask;
643 VK_FALSE, // VkBool32 alphaToCoverageEnable;
644 VK_FALSE // VkBool32 alphaToOneEnable;
647 const VkStencilOpState stencilOpState = makeStencilOpState(
648 VK_STENCIL_OP_KEEP, // stencil fail
649 VK_STENCIL_OP_KEEP, // depth & stencil pass
650 VK_STENCIL_OP_KEEP, // depth only fail
651 VK_COMPARE_OP_NEVER, // compare op
656 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
658 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
659 DE_NULL, // const void* pNext;
660 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
661 m_drawState.depthTestEnable, // VkBool32 depthTestEnable;
662 m_drawState.depthWriteEnable, // VkBool32 depthWriteEnable;
663 mapCompareOp(m_drawState.compareOp), // VkCompareOp depthCompareOp;
664 VK_TRUE, // VkBool32 depthBoundsTestEnable;
665 VK_FALSE, // VkBool32 stencilTestEnable;
666 stencilOpState, // VkStencilOpState front;
667 stencilOpState, // VkStencilOpState back;
668 0.0f, // float minDepthBounds;
669 1.0f, // float maxDepthBounds;
672 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
673 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
675 m_drawState.blendEnable, // VkBool32 blendEnable;
676 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
677 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
678 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
679 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
680 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
681 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
682 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
685 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
687 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
688 DE_NULL, // const void* pNext;
689 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
690 VK_FALSE, // VkBool32 logicOpEnable;
691 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
692 1u, // deUint32 attachmentCount;
693 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
694 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
697 // Create shader stages
699 std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
700 VkShaderStageFlags stageFlags = (VkShaderStageFlags)0;
702 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
703 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
705 m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
707 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
709 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
710 DE_NULL, // const void* pNext;
711 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
712 m_program.shaders[shaderNdx].stage, // VkShaderStageFlagBits stage;
713 *m_shaderModules[shaderNdx], // VkShaderModule module;
714 "main", // const char* pName;
715 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
718 shaderStages.push_back(pipelineShaderStageInfo);
719 stageFlags |= m_program.shaders[shaderNdx].stage;
723 (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
724 (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
726 const bool tessellationEnabled = (m_drawState.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
727 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
729 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
730 DE_NULL, // const void* pNext;
731 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
732 static_cast<deUint32>(shaderStages.size()), // deUint32 stageCount;
733 &shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
734 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
735 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
736 (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
737 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
738 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
739 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
740 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
741 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
742 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
743 *m_pipelineLayout, // VkPipelineLayout layout;
744 *m_renderPass, // VkRenderPass renderPass;
745 0u, // deUint32 subpass;
746 DE_NULL, // VkPipeline basePipelineHandle;
747 0, // deInt32 basePipelineIndex;
750 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
755 const VkDeviceSize zeroOffset = 0ull;
757 beginCommandBuffer(vk, *m_cmdBuffer);
758 if (vulkanProgram.descriptorSet)
759 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &*vulkanProgram.descriptorSet, 0u, DE_NULL);
763 std::vector<VkClearValue> clearValues;
765 clearValues.push_back(makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
766 if (vulkanProgram.depthImageView)
767 clearValues.push_back(makeClearValueDepthStencil(0.0, 0));
769 const VkRect2D renderArea =
772 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y())
775 const VkRenderPassBeginInfo renderPassBeginInfo = {
776 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
777 DE_NULL, // const void* pNext;
778 *m_renderPass, // VkRenderPass renderPass;
779 *m_framebuffer, // VkFramebuffer framebuffer;
780 renderArea, // VkRect2D renderArea;
781 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount;
782 &clearValues[0], // const VkClearValue* pClearValues;
785 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
788 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
789 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
791 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
792 vk.cmdEndRenderPass(*m_cmdBuffer);
794 // Barrier: draw -> copy from image
796 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
797 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
798 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
799 **m_colorImage, colorSubresourceRange);
801 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
802 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
805 // Resolve multisample image
807 if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
809 const VkImageResolve imageResolve =
811 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
813 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
815 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
818 const VkImageCreateInfo resolveImageCreateInfo =
820 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
821 DE_NULL, // const void* pNext
822 (VkImageCreateFlags)0, // VkImageCreateFlags flags
823 VK_IMAGE_TYPE_2D, // VkImageType imageType
824 m_drawState.colorFormat, // VkFormat format
825 makeExtent3D(m_drawState.renderSize.x(), // VkExtent3D extent;
826 m_drawState.renderSize.y(), 1u),
827 1u, // uint32_t mipLevels
828 1u, // uint32_t arrayLayers
829 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
830 VK_IMAGE_TILING_OPTIMAL, // VkImaageTiling tiling
831 VK_IMAGE_USAGE_TRANSFER_DST_BIT | // VkImageUsageFlags usage
832 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
833 VK_SHARING_MODE_EXCLUSIVE, // VkSharingModeExclusive sharingMode
834 0u, // uint32_t queueFamilyIndexCount
835 DE_NULL, // const uint32_t* pQueueFamilyIndices
836 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
839 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
841 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
842 0u, VK_ACCESS_TRANSFER_READ_BIT,
843 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
844 **m_resolveImage, colorSubresourceRange);
846 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
847 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
849 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
850 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
852 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
853 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
854 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
855 **m_resolveImage, colorSubresourceRange);
857 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
858 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
861 m_resolveImage = m_colorImage;
863 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
864 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
865 vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, ©Region);
868 // Barrier: copy to buffer -> host read
870 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
871 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
872 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
874 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
875 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
878 endCommandBuffer(vk, *m_cmdBuffer);
882 VulkanDrawContext::~VulkanDrawContext (void)
886 void VulkanDrawContext::draw (void)
888 const DeviceInterface& vk = m_context.getDeviceInterface();
889 const VkDevice device = m_context.getDevice();
890 const VkQueue queue = m_context.getUniversalQueue();
891 tcu::TestLog& log = m_context.getTestContext().getLog();
893 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
895 log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
898 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
900 const DeviceInterface& vk = m_context.getDeviceInterface();
901 const VkDevice device = m_context.getDevice();
903 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
904 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
906 return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());