1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Intel Corporation
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 Command draw Tests - Base Class
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawBaseClass.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkCmdUtil.hpp"
28 #include "vkTypeUtil.hpp"
29
30 namespace vkt
31 {
32 namespace Draw
33 {
34
DrawTestsBaseClass(Context & context,const char * vertexShaderName,const char * fragmentShaderName,const SharedGroupParams groupParams,vk::VkPrimitiveTopology topology,const uint32_t layers)35 DrawTestsBaseClass::DrawTestsBaseClass(Context &context, const char *vertexShaderName, const char *fragmentShaderName,
36 const SharedGroupParams groupParams, vk::VkPrimitiveTopology topology,
37 const uint32_t layers)
38 : TestInstance(context)
39 , m_colorAttachmentFormat(vk::VK_FORMAT_R8G8B8A8_UNORM)
40 , m_groupParams(groupParams)
41 , m_topology(topology)
42 , m_layers(layers)
43 , m_vk(context.getDeviceInterface())
44 , m_vertexShaderName(vertexShaderName)
45 , m_fragmentShaderName(fragmentShaderName)
46 {
47 }
48
initialize(void)49 void DrawTestsBaseClass::initialize(void)
50 {
51 const vk::VkDevice device = m_context.getDevice();
52 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
53 const auto viewMask = getDefaultViewMask();
54 const auto multiview = (viewMask != 0u);
55
56 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
57 m_pipelineLayout = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
58
59 const vk::VkExtent3D targetImageExtent = {WIDTH, HEIGHT, 1};
60 const ImageCreateInfo targetImageCreateInfo(vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, targetImageExtent, 1,
61 m_layers, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_IMAGE_TILING_OPTIMAL,
62 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
63 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
64 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
65
66 m_colorTargetImage = Image::createAndAlloc(m_vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(),
67 m_context.getUniversalQueueFamilyIndex());
68
69 const ImageSubresourceRange colorSRR(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_layers);
70 const auto imageViewType = (multiview ? vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY : vk::VK_IMAGE_VIEW_TYPE_2D);
71 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), imageViewType, m_colorAttachmentFormat,
72 colorSRR);
73 m_colorTargetView = vk::createImageView(m_vk, device, &colorTargetViewInfo);
74
75 // create renderpass and framebuffer only when we are not using dynamic rendering
76 if (!m_groupParams->useDynamicRendering)
77 {
78 RenderPassCreateInfo renderPassCreateInfo;
79 renderPassCreateInfo.addAttachment(AttachmentDescription(
80 m_colorAttachmentFormat, vk::VK_SAMPLE_COUNT_1_BIT, vk::VK_ATTACHMENT_LOAD_OP_LOAD,
81 vk::VK_ATTACHMENT_STORE_OP_STORE, vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, vk::VK_ATTACHMENT_STORE_OP_STORE,
82 vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL));
83
84 const vk::VkAttachmentReference colorAttachmentReference{0, vk::VK_IMAGE_LAYOUT_GENERAL};
85
86 renderPassCreateInfo.addSubpass(SubpassDescription(vk::VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, 1,
87 &colorAttachmentReference, DE_NULL, AttachmentReference(), 0,
88 DE_NULL));
89
90 const std::vector<uint32_t> viewMasks(1u, viewMask);
91
92 const vk::VkRenderPassMultiviewCreateInfo multiviewCreateInfo = {
93 vk::VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, // VkStructureType sType;
94 nullptr, // const void* pNext;
95 de::sizeU32(viewMasks), // uint32_t subpassCount;
96 de::dataOrNull(viewMasks), // const uint32_t* pViewMasks;
97 0u, // uint32_t dependencyCount;
98 nullptr, // const int32_t* pViewOffsets;
99 de::sizeU32(viewMasks), // uint32_t correlationMaskCount;
100 de::dataOrNull(viewMasks), // const uint32_t* pCorrelationMasks;
101 };
102
103 if (multiview)
104 renderPassCreateInfo.pNext = &multiviewCreateInfo;
105
106 m_renderPass = vk::createRenderPass(m_vk, device, &renderPassCreateInfo);
107
108 // create framebuffer
109 std::vector<vk::VkImageView> colorAttachments{*m_colorTargetView};
110 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
111 m_framebuffer = vk::createFramebuffer(m_vk, device, &framebufferCreateInfo);
112 }
113
114 const vk::VkVertexInputBindingDescription vertexInputBindingDescription = {
115 0,
116 sizeof(VertexElementData),
117 vk::VK_VERTEX_INPUT_RATE_VERTEX,
118 };
119
120 const vk::VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
121 {0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u}, // VertexElementData::position
122 {1u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT,
123 static_cast<uint32_t>(sizeof(tcu::Vec4))}, // VertexElementData::color
124 {2u, 0u, vk::VK_FORMAT_R32_SINT,
125 static_cast<uint32_t>(sizeof(tcu::Vec4)) * 2} // VertexElementData::refVertexIndex
126 };
127
128 m_vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
129 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),
130 vertexInputAttributeDescriptions);
131
132 const vk::VkDeviceSize dataSize = m_data.size() * sizeof(VertexElementData);
133 m_vertexBuffer =
134 Buffer::createAndAlloc(m_vk, device, BufferCreateInfo(dataSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
135 m_context.getDefaultAllocator(), vk::MemoryRequirement::HostVisible);
136
137 uint8_t *ptr = reinterpret_cast<uint8_t *>(m_vertexBuffer->getBoundMemory().getHostPtr());
138 deMemcpy(ptr, &m_data[0], static_cast<size_t>(dataSize));
139
140 vk::flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
141
142 const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
143 m_cmdPool = vk::createCommandPool(m_vk, device, &cmdPoolCreateInfo);
144 m_cmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
145
146 if (m_groupParams->useSecondaryCmdBuffer)
147 m_secCmdBuffer = vk::allocateCommandBuffer(m_vk, device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY);
148
149 initPipeline(device);
150 }
151
initPipeline(const vk::VkDevice device)152 void DrawTestsBaseClass::initPipeline(const vk::VkDevice device)
153 {
154 const vk::Unique<vk::VkShaderModule> vs(
155 createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
156 const vk::Unique<vk::VkShaderModule> fs(
157 createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
158
159 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
160
161 vk::VkViewport viewport = vk::makeViewport(WIDTH, HEIGHT);
162 vk::VkRect2D scissor = vk::makeRect2D(WIDTH, HEIGHT);
163
164 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
165 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
166 pipelineCreateInfo.addShader(
167 PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
168 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
169 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(m_topology));
170 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
171 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, std::vector<vk::VkViewport>(1, viewport),
172 std::vector<vk::VkRect2D>(1, scissor)));
173 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
174 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
175 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
176
177 #ifndef CTS_USES_VULKANSC
178 const auto viewMask = getDefaultViewMask();
179
180 vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo{vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
181 DE_NULL,
182 viewMask,
183 1u,
184 &m_colorAttachmentFormat,
185 vk::VK_FORMAT_UNDEFINED,
186 vk::VK_FORMAT_UNDEFINED};
187
188 if (m_groupParams->useDynamicRendering)
189 pipelineCreateInfo.pNext = &renderingCreateInfo;
190 #endif // CTS_USES_VULKANSC
191
192 m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo);
193 }
194
preRenderBarriers(void)195 void DrawTestsBaseClass::preRenderBarriers(void)
196 {
197 const vk::VkClearValue clearColor{{{0.0f, 0.0f, 0.0f, 1.0f}}};
198
199 initialTransitionColor2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
200 vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, m_layers);
201
202 const ImageSubresourceRange subresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT);
203 m_vk.cmdClearColorImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, &clearColor.color,
204 1, &subresourceRange);
205
206 const vk::VkMemoryBarrier memBarrier{
207 vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
208 vk::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT};
209
210 m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
211 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0,
212 DE_NULL);
213 }
214
beginLegacyRender(vk::VkCommandBuffer cmdBuffer,const vk::VkSubpassContents content)215 void DrawTestsBaseClass::beginLegacyRender(vk::VkCommandBuffer cmdBuffer, const vk::VkSubpassContents content)
216 {
217 const vk::VkRect2D renderArea = vk::makeRect2D(WIDTH, HEIGHT);
218
219 vk::beginRenderPass(m_vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, content);
220 }
221
endLegacyRender(vk::VkCommandBuffer cmdBuffer)222 void DrawTestsBaseClass::endLegacyRender(vk::VkCommandBuffer cmdBuffer)
223 {
224 vk::endRenderPass(m_vk, cmdBuffer);
225 }
226
227 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(const vk::DeviceInterface & vk,const vk::VkRenderingFlagsKHR renderingFlags)228 void DrawTestsBaseClass::beginSecondaryCmdBuffer(const vk::DeviceInterface &vk,
229 const vk::VkRenderingFlagsKHR renderingFlags)
230 {
231 vk::VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
232 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
233 DE_NULL, // const void* pNext;
234 renderingFlags, // VkRenderingFlagsKHR flags;
235 getDefaultViewMask(), // uint32_t viewMask;
236 1u, // uint32_t colorAttachmentCount;
237 &m_colorAttachmentFormat, // const VkFormat* pColorAttachmentFormats;
238 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
239 vk::VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
240 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
241 };
242 const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo = vk::initVulkanStructure(&inheritanceRenderingInfo);
243
244 vk::VkCommandBufferUsageFlags usageFlags = vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
245 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
246 usageFlags |= vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
247
248 const vk::VkCommandBufferBeginInfo commandBufBeginParams{
249 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
250 DE_NULL, // const void* pNext;
251 usageFlags, // VkCommandBufferUsageFlags flags;
252 &bufferInheritanceInfo};
253
254 VK_CHECK(vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams));
255 }
256
beginDynamicRender(vk::VkCommandBuffer cmdBuffer,const vk::VkRenderingFlagsKHR renderingFlags)257 void DrawTestsBaseClass::beginDynamicRender(vk::VkCommandBuffer cmdBuffer, const vk::VkRenderingFlagsKHR renderingFlags)
258 {
259 const vk::VkClearValue clearColor{{{0.0f, 0.0f, 0.0f, 1.0f}}};
260 const vk::VkRect2D renderArea = vk::makeRect2D(WIDTH, HEIGHT);
261
262 vk::beginRendering(m_vk, cmdBuffer, *m_colorTargetView, renderArea, clearColor, vk::VK_IMAGE_LAYOUT_GENERAL,
263 vk::VK_ATTACHMENT_LOAD_OP_LOAD, renderingFlags, m_layers, getDefaultViewMask());
264 }
265
endDynamicRender(vk::VkCommandBuffer cmdBuffer)266 void DrawTestsBaseClass::endDynamicRender(vk::VkCommandBuffer cmdBuffer)
267 {
268 vk::endRendering(m_vk, cmdBuffer);
269 }
270 #endif // CTS_USES_VULKANSC
271
getDefaultViewMask(void) const272 uint32_t DrawTestsBaseClass::getDefaultViewMask(void) const
273 {
274 const bool multiview = (m_layers > 1u);
275 const uint32_t viewMask = (multiview ? ((1u << m_layers) - 1u) : 0u);
276 return viewMask;
277 }
278
279 } // namespace Draw
280 } // namespace vkt
281