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 "vkBarrierUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "rrRenderer.hpp"
34 #include "rrRenderState.hpp"
35 #include "rrPrimitiveTypes.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "deArrayUtil.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkCmdUtil.hpp"
41
42 namespace vkt
43 {
44 namespace drawutil
45 {
46
47 using namespace de;
48 using namespace tcu;
49 using namespace vk;
50
mapCompareOp(rr::TestFunc compareFunc)51 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
52 {
53 switch (compareFunc)
54 {
55 case rr::TESTFUNC_NEVER: return VK_COMPARE_OP_NEVER;
56 case rr::TESTFUNC_LESS: return VK_COMPARE_OP_LESS;
57 case rr::TESTFUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
58 case rr::TESTFUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
59 case rr::TESTFUNC_GREATER: return VK_COMPARE_OP_GREATER;
60 case rr::TESTFUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
61 case rr::TESTFUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
62 case rr::TESTFUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
63 default:
64 DE_ASSERT(false);
65 }
66 return VK_COMPARE_OP_LAST;
67 }
68
mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology & primitiveTopology)69 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
70 {
71 static const rr::PrimitiveType primitiveTypeTable[] =
72 {
73 rr::PRIMITIVETYPE_POINTS,
74 rr::PRIMITIVETYPE_LINES,
75 rr::PRIMITIVETYPE_LINE_STRIP,
76 rr::PRIMITIVETYPE_TRIANGLES,
77 rr::PRIMITIVETYPE_TRIANGLE_STRIP,
78 rr::PRIMITIVETYPE_TRIANGLE_FAN,
79 rr::PRIMITIVETYPE_LINES_ADJACENCY,
80 rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY,
81 rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY,
82 rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY
83 };
84
85 return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
86 }
87
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)88 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
89 const VkBufferUsageFlags usage)
90 {
91 const VkBufferCreateInfo bufferCreateInfo =
92 {
93 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
94 DE_NULL, // const void* pNext;
95 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
96 bufferSize, // VkDeviceSize size;
97 usage, // VkBufferUsageFlags usage;
98 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
99 0u, // deUint32 queueFamilyIndexCount;
100 DE_NULL, // const deUint32* pQueueFamilyIndices;
101 };
102 return bufferCreateInfo;
103 }
104
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)105 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
106 {
107 const VkCommandPoolCreateInfo info =
108 {
109 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
110 DE_NULL, // const void* pNext;
111 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
112 queueFamilyIndex, // deUint32 queueFamilyIndex;
113 };
114 return createCommandPool(vk, device, &info);
115 }
116
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)117 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
118 {
119 const VkCommandBufferAllocateInfo info =
120 {
121 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
122 DE_NULL, // const void* pNext;
123 commandPool, // VkCommandPool commandPool;
124 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
125 1u, // deUint32 commandBufferCount;
126 };
127 return allocateCommandBuffer(vk, device, &info);
128 }
129
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)130 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
131 const VkDevice device,
132 const VkDescriptorPool descriptorPool,
133 const VkDescriptorSetLayout setLayout)
134 {
135 const VkDescriptorSetAllocateInfo info =
136 {
137 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
138 DE_NULL, // const void* pNext;
139 descriptorPool, // VkDescriptorPool descriptorPool;
140 1u, // deUint32 descriptorSetCount;
141 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
142 };
143 return allocateDescriptorSet(vk, device, &info);
144 }
145
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)146 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
147 const VkDevice device,
148 const VkDescriptorSetLayout descriptorSetLayout)
149 {
150 const VkPipelineLayoutCreateInfo info =
151 {
152 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
153 DE_NULL, // const void* pNext;
154 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
155 1u, // deUint32 setLayoutCount;
156 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
157 0u, // deUint32 pushConstantRangeCount;
158 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
159 };
160 return createPipelineLayout(vk, device, &info);
161 }
162
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)163 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
164 const VkDevice device)
165 {
166 const VkPipelineLayoutCreateInfo info =
167 {
168 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
169 DE_NULL, // const void* pNext;
170 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
171 0u, // deUint32 setLayoutCount;
172 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
173 0u, // deUint32 pushConstantRangeCount;
174 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
175 };
176 return createPipelineLayout(vk, device, &info);
177 }
178
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)179 Move<VkImageView> makeImageView (const DeviceInterface& vk,
180 const VkDevice device,
181 const VkImage image,
182 const VkImageViewType viewType,
183 const VkFormat format,
184 const VkImageSubresourceRange subresourceRange)
185 {
186 const VkImageViewCreateInfo imageViewParams =
187 {
188 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
189 DE_NULL, // const void* pNext;
190 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
191 image, // VkImage image;
192 viewType, // VkImageViewType viewType;
193 format, // VkFormat format;
194 makeComponentMappingRGBA(), // VkComponentMapping components;
195 subresourceRange, // VkImageSubresourceRange subresourceRange;
196 };
197 return createImageView(vk, device, &imageViewParams);
198 }
199
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)200 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers,
201 const VkExtent3D extent)
202 {
203 const VkBufferImageCopy copyParams =
204 {
205 0ull, // VkDeviceSize bufferOffset;
206 0u, // deUint32 bufferRowLength;
207 0u, // deUint32 bufferImageHeight;
208 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
209 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
210 extent, // VkExtent3D imageExtent;
211 };
212 return copyParams;
213 }
214
getPrimitiveTopologyShortName(const VkPrimitiveTopology topology)215 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
216 {
217 std::string name(getPrimitiveTopologyName(topology));
218 return de::toLower(name.substr(22));
219 }
220
DrawState(const vk::VkPrimitiveTopology topology_,deUint32 renderWidth_,deUint32 renderHeight_)221 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_)
222 : topology (topology_)
223 , colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
224 , renderSize (tcu::UVec2(renderWidth_, renderHeight_))
225 , depthClampEnable (false)
226 , depthTestEnable (false)
227 , depthWriteEnable (false)
228 , compareOp (rr::TESTFUNC_LESS)
229 , depthBoundsTestEnable (false)
230 , blendEnable (false)
231 , lineWidth (1.0)
232 , numPatchControlPoints (0)
233 , numSamples (VK_SAMPLE_COUNT_1_BIT)
234 , sampleShadingEnable (false)
235 {
236 DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
237 }
238
~ReferenceDrawContext(void)239 ReferenceDrawContext::~ReferenceDrawContext (void)
240 {
241 }
242
draw(void)243 void ReferenceDrawContext::draw (void)
244 {
245 m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
246 tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
247
248 {
249 const rr::Program program(&m_vertexShader, &m_fragmentShader);
250 const rr::MultisamplePixelBufferAccess referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
251 const rr::RenderTarget renderTarget(referenceColorBuffer);
252 const rr::RenderState renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
253 const rr::Renderer renderer;
254 const rr::VertexAttrib vertexAttrib[] =
255 {
256 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
257 };
258
259 renderer.draw(rr::DrawCommand( renderState,
260 renderTarget,
261 program,
262 DE_LENGTH_OF_ARRAY(vertexAttrib),
263 &vertexAttrib[0],
264 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
265
266 }
267
268 }
269
getColorPixels(void) const270 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
271 {
272 return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
273 m_refImage.getAccess().getWidth(),
274 m_refImage.getAccess().getHeight(),
275 m_refImage.getAccess().getDepth(),
276 m_refImage.getAccess().getDataPtr());
277 }
278
VulkanDrawContext(Context & context,const DrawState & drawState,const DrawCallData & drawCallData,const VulkanProgram & vulkanProgram)279 VulkanDrawContext::VulkanDrawContext ( Context& context,
280 const DrawState& drawState,
281 const DrawCallData& drawCallData,
282 const VulkanProgram& vulkanProgram)
283 : DrawContext (drawState, drawCallData)
284 , m_context (context)
285 , m_program (vulkanProgram)
286 {
287 const DeviceInterface& vk = m_context.getDeviceInterface();
288 const VkDevice device = m_context.getDevice();
289 Allocator& allocator = m_context.getDefaultAllocator();
290 VkImageSubresourceRange colorSubresourceRange;
291 Move<VkSampler> sampler;
292
293 // Command buffer
294 {
295 m_cmdPool = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
296 m_cmdBuffer = makeCommandBuffer(vk, device, *m_cmdPool);
297 }
298
299 // Color attachment image
300 {
301 const VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
302 colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
303 const VkImageCreateInfo imageCreateInfo =
304 {
305 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
306 DE_NULL, // const void* pNext;
307 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
308 VK_IMAGE_TYPE_2D, // VkImageType imageType;
309 m_drawState.colorFormat, // VkFormat format;
310 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u), // VkExtent3D extent;
311 1u, // uint32_t mipLevels;
312 1u, // uint32_t arrayLayers;
313 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
314 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
315 usage, // VkImageUsageFlags usage;
316 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
317 0u, // uint32_t queueFamilyIndexCount;
318 DE_NULL, // const uint32_t* pQueueFamilyIndices;
319 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
320 };
321
322 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
323 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
324
325 // Buffer to copy attachment data after rendering
326
327 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
328 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
329 vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
330
331 {
332 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
333 deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
334 flushAlloc(vk, device, alloc);
335 }
336 }
337
338 // Vertex buffer
339 {
340 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
341 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
342 vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
343
344 const Allocation& alloc = m_vertexBuffer->getAllocation();
345 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
346 flushAlloc(vk, device, alloc);
347 }
348
349 // bind descriptor sets
350 {
351 if (!vulkanProgram.descriptorSetLayout)
352 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
353 else
354 m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout);
355 }
356
357 // Renderpass
358 {
359 std::vector<VkAttachmentDescription> attachmentDescriptions;
360 const VkAttachmentDescription attachDescriptors[] =
361 {
362 {
363 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
364 m_drawState.colorFormat, // VkFormat format;
365 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples;
366 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
367 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
368 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
369 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
370 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
371 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
372 },
373 {
374 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
375 m_drawState.depthFormat, // VkFormat format
376 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples
377 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
378 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
379 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
380 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
381 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
382 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout
383
384 }
385 };
386
387 const VkAttachmentReference attachmentReferences[] =
388 {
389 {
390 0u, // uint32_t attachment
391 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
392 },
393 {
394 1u, // uint32_t attachment
395 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout
396 },
397 {
398 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
399 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
400 }
401 };
402
403 attachmentDescriptions.push_back(attachDescriptors[0]);
404 if (!!vulkanProgram.depthImageView)
405 attachmentDescriptions.push_back(attachDescriptors[1]);
406
407 deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2;
408 const VkSubpassDescription subpassDescription =
409 {
410 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
411 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
412 0u, // deUint32 inputAttachmentCount;
413 DE_NULL, // const VkAttachmentReference* pInputAttachments;
414 1u, // deUint32 colorAttachmentCount;
415 &attachmentReferences[0], // const VkAttachmentReference* pColorAttachments;
416 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
417 &attachmentReferences[depthReferenceNdx], // const VkAttachmentReference* pDepthStencilAttachment;
418 0u, // deUint32 preserveAttachmentCount;
419 DE_NULL // const deUint32* pPreserveAttachments;
420 };
421
422 const VkRenderPassCreateInfo renderPassInfo =
423 {
424 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
425 DE_NULL, // const void* pNext;
426 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
427 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
428 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
429 1u, // deUint32 subpassCount;
430 &subpassDescription, // const VkSubpassDescription* pSubpasses;
431 0u, // deUint32 dependencyCount;
432 DE_NULL // const VkSubpassDependency* pDependencies;
433 };
434
435 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
436 }
437
438 // Framebuffer
439 {
440 std::vector<VkImageView> attachmentBindInfos;
441 deUint32 numAttachments;
442 attachmentBindInfos.push_back(*m_colorImageView);
443 if (!!vulkanProgram.depthImageView)
444 attachmentBindInfos.push_back(vulkanProgram.depthImageView);
445
446 numAttachments = (deUint32)(attachmentBindInfos.size());
447 const VkFramebufferCreateInfo framebufferInfo = {
448 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
449 DE_NULL, // const void* pNext;
450 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
451 *m_renderPass, // VkRenderPass renderPass;
452 numAttachments, // uint32_t attachmentCount;
453 &attachmentBindInfos[0], // const VkImageView* pAttachments;
454 m_drawState.renderSize.x(), // uint32_t width;
455 m_drawState.renderSize.y(), // uint32_t height;
456 1u, // uint32_t layers;
457 };
458
459 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
460 }
461
462 // Graphics pipeline
463 {
464 VkShaderModule vertShader = DE_NULL;
465 VkShaderModule tessControlShader = DE_NULL;
466 VkShaderModule tessEvalShader = DE_NULL;
467 VkShaderModule geomShader = DE_NULL;
468 VkShaderModule fragShader = DE_NULL;
469
470 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
471
472 const std::vector<VkViewport> viewports (1, makeViewport(m_drawState.renderSize));
473 const std::vector<VkRect2D> scissors (1, makeRect2D(m_drawState.renderSize));
474
475 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
476 {
477 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
478 DE_NULL, // const void* pNext;
479 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
480 m_drawState.depthClampEnable, // VkBool32 depthClampEnable;
481 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
482 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
483 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
484 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
485 VK_FALSE, // VkBool32 depthBiasEnable;
486 0.0f, // float depthBiasConstantFactor;
487 0.0f, // float depthBiasClamp;
488 0.0f, // float depthBiasSlopeFactor;
489 m_drawState.lineWidth, // float lineWidth;
490 };
491
492 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
493 {
494 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
495 DE_NULL, // const void* pNext;
496 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
497 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits rasterizationSamples;
498 m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable;
499 m_drawState.sampleShadingEnable ? 1.0f : 0.0f, // float minSampleShading;
500 DE_NULL, // const VkSampleMask* pSampleMask;
501 VK_FALSE, // VkBool32 alphaToCoverageEnable;
502 VK_FALSE // VkBool32 alphaToOneEnable;
503 };
504
505 const VkStencilOpState stencilOpState = makeStencilOpState(
506 VK_STENCIL_OP_KEEP, // stencil fail
507 VK_STENCIL_OP_KEEP, // depth & stencil pass
508 VK_STENCIL_OP_KEEP, // depth only fail
509 VK_COMPARE_OP_NEVER, // compare op
510 0u, // compare mask
511 0u, // write mask
512 0u); // reference
513
514 if (m_drawState.depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds)
515 TCU_THROW(NotSupportedError, "depthBounds not supported");
516
517 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
518 {
519 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
520 DE_NULL, // const void* pNext;
521 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
522 m_drawState.depthTestEnable, // VkBool32 depthTestEnable;
523 m_drawState.depthWriteEnable, // VkBool32 depthWriteEnable;
524 mapCompareOp(m_drawState.compareOp), // VkCompareOp depthCompareOp;
525 m_drawState.depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable
526 VK_FALSE, // VkBool32 stencilTestEnable;
527 stencilOpState, // VkStencilOpState front;
528 stencilOpState, // VkStencilOpState back;
529 0.0f, // float minDepthBounds;
530 1.0f, // float maxDepthBounds;
531 };
532
533 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
534 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
535 {
536 m_drawState.blendEnable, // VkBool32 blendEnable;
537 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
538 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
539 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
540 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
541 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
542 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
543 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
544 };
545
546 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
547 {
548 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
549 DE_NULL, // const void* pNext;
550 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
551 VK_FALSE, // VkBool32 logicOpEnable;
552 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
553 1u, // deUint32 attachmentCount;
554 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
555 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
556 };
557
558 VkShaderStageFlags stageFlags = (VkShaderStageFlags)0;
559
560 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
561 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
562 {
563 m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
564
565 stageFlags |= m_program.shaders[shaderNdx].stage;
566
567 switch(m_program.shaders[shaderNdx].stage)
568 {
569 case VK_SHADER_STAGE_VERTEX_BIT:
570 vertShader = *m_shaderModules[shaderNdx];
571 break;
572 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
573 tessControlShader = *m_shaderModules[shaderNdx];
574 break;
575 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
576 tessEvalShader = *m_shaderModules[shaderNdx];
577 break;
578 case VK_SHADER_STAGE_GEOMETRY_BIT:
579 geomShader = *m_shaderModules[shaderNdx];
580 break;
581 default:
582 DE_ASSERT(m_program.shaders[shaderNdx].stage == VK_SHADER_STAGE_FRAGMENT_BIT);
583 fragShader = *m_shaderModules[shaderNdx];
584 break;
585 }
586 }
587
588 DE_ASSERT(
589 (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
590 (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
591
592 m_pipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
593 device, // const VkDevice device
594 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
595 vertShader, // const VkShaderModule vertexShaderModule
596 tessControlShader, // const VkShaderModule tessellationControlShaderModule
597 tessEvalShader, // const VkShaderModule tessellationEvalShaderModule
598 geomShader, // const VkShaderModule geometryShaderModule
599 fragShader, // const VkShaderModule fragmentShaderModule
600 *m_renderPass, // const VkRenderPass renderPass
601 viewports, // const std::vector<VkViewport>& viewports
602 scissors, // const std::vector<VkRect2D>& scissors
603 m_drawState.topology, // const VkPrimitiveTopology topology
604 0u, // const deUint32 subpass
605 m_drawState.numPatchControlPoints, // const deUint32 patchControlPoints
606 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
607 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
608 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
609 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
610 &pipelineColorBlendStateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
611 }
612
613 // Record commands
614 {
615 const VkDeviceSize zeroOffset = 0ull;
616
617 beginCommandBuffer(vk, *m_cmdBuffer);
618 if (!!vulkanProgram.descriptorSet)
619 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL);
620
621 // Begin render pass
622 if (!!vulkanProgram.depthImageView)
623 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0.0f, 0);
624 else
625 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
626
627 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
628 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
629
630 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
631 endRenderPass(vk, *m_cmdBuffer);
632
633 // Barrier: draw -> copy from image
634 {
635 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
636 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
637 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
638 **m_colorImage, colorSubresourceRange);
639
640 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
641 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
642 }
643
644 // Resolve multisample image
645 {
646 if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
647 {
648 const VkImageResolve imageResolve =
649 {
650 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
651 { 0, 0, 0},
652 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
653 { 0, 0, 0},
654 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
655 };
656
657 const VkImageCreateInfo resolveImageCreateInfo =
658 {
659 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
660 DE_NULL, // const void* pNext
661 (VkImageCreateFlags)0, // VkImageCreateFlags flags
662 VK_IMAGE_TYPE_2D, // VkImageType imageType
663 m_drawState.colorFormat, // VkFormat format
664 makeExtent3D(m_drawState.renderSize.x(), // VkExtent3D extent;
665 m_drawState.renderSize.y(), 1u),
666 1u, // uint32_t mipLevels
667 1u, // uint32_t arrayLayers
668 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
669 VK_IMAGE_TILING_OPTIMAL, // VkImaageTiling tiling
670 VK_IMAGE_USAGE_TRANSFER_DST_BIT | // VkImageUsageFlags usage
671 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
672 VK_SHARING_MODE_EXCLUSIVE, // VkSharingModeExclusive sharingMode
673 0u, // uint32_t queueFamilyIndexCount
674 DE_NULL, // const uint32_t* pQueueFamilyIndices
675 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
676 };
677
678 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
679
680 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
681 0u, VK_ACCESS_TRANSFER_READ_BIT,
682 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
683 **m_resolveImage, colorSubresourceRange);
684
685 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
686 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
687
688 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
689 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
690
691 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
692 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
693 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
694 **m_resolveImage, colorSubresourceRange);
695
696 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
697 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
698 }
699 else
700 m_resolveImage = m_colorImage;
701
702 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
703 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
704 vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, ©Region);
705 }
706
707 // Barrier: copy to buffer -> host read
708 {
709 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
710 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
711 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
712
713 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
714 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
715 }
716
717 endCommandBuffer(vk, *m_cmdBuffer);
718 }
719 }
720
~VulkanDrawContext(void)721 VulkanDrawContext::~VulkanDrawContext (void)
722 {
723 }
724
draw(void)725 void VulkanDrawContext::draw (void)
726 {
727 const DeviceInterface& vk = m_context.getDeviceInterface();
728 const VkDevice device = m_context.getDevice();
729 const VkQueue queue = m_context.getUniversalQueue();
730 tcu::TestLog& log = m_context.getTestContext().getLog();
731
732 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
733
734 log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
735 }
736
getColorPixels(void) const737 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
738 {
739 const DeviceInterface& vk = m_context.getDeviceInterface();
740 const VkDevice device = m_context.getDevice();
741
742 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
743 invalidateAlloc(vk, device, alloc);
744
745 return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
746 }
747 } // drawutil
748 } // vkt
749