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