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