1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Imagination Technologies Ltd.
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 Robustness Utilities
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRobustnessUtil.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 #include "vkDefs.hpp"
28 #include "vkImageUtil.hpp"
29 #include "vkPrograms.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "tcuCommandLine.hpp"
36 #include "deMath.h"
37 #include <iomanip>
38 #include <limits>
39 #include <sstream>
40
41 namespace vkt
42 {
43 namespace robustness
44 {
45
46 using namespace vk;
47
createRobustBufferAccessDevice(Context & context)48 Move<VkDevice> createRobustBufferAccessDevice (Context& context)
49 {
50 const float queuePriority = 1.0f;
51
52 // Create a universal queue that supports graphics and compute
53 const VkDeviceQueueCreateInfo queueParams =
54 {
55 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
56 DE_NULL, // const void* pNext;
57 0u, // VkDeviceQueueCreateFlags flags;
58 context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
59 1u, // deUint32 queueCount;
60 &queuePriority // const float* pQueuePriorities;
61 };
62
63 VkPhysicalDeviceFeatures enabledFeatures = context.getDeviceFeatures();
64 enabledFeatures.robustBufferAccess = true;
65
66 const VkDeviceCreateInfo deviceParams =
67 {
68 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
69 DE_NULL, // const void* pNext;
70 0u, // VkDeviceCreateFlags flags;
71 1u, // deUint32 queueCreateInfoCount;
72 &queueParams, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
73 0u, // deUint32 enabledLayerCount;
74 DE_NULL, // const char* const* ppEnabledLayerNames;
75 0u, // deUint32 enabledExtensionCount;
76 DE_NULL, // const char* const* ppEnabledExtensionNames;
77 &enabledFeatures // const VkPhysicalDeviceFeatures* pEnabledFeatures;
78 };
79
80 return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
81 context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceParams);
82 }
83
areEqual(float a,float b)84 bool areEqual (float a, float b)
85 {
86 return deFloatAbs(a - b) <= 0.001f;
87 }
88
isValueZero(const void * valuePtr,size_t valueSizeInBytes)89 bool isValueZero (const void* valuePtr, size_t valueSizeInBytes)
90 {
91 const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr);
92
93 for (size_t i = 0; i < valueSizeInBytes; i++)
94 {
95 if (bytePtr[i] != 0)
96 return false;
97 }
98
99 return true;
100 }
101
isValueWithinBuffer(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)102 bool isValueWithinBuffer (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
103 {
104 const deUint8* byteBuffer = reinterpret_cast<const deUint8*>(buffer);
105
106 if (bufferSize < ((VkDeviceSize)valueSizeInBytes))
107 return false;
108
109 for (VkDeviceSize i = 0; i <= (bufferSize - valueSizeInBytes); i++)
110 {
111 if (!deMemCmp(&byteBuffer[i], valuePtr, valueSizeInBytes))
112 return true;
113 }
114
115 return false;
116 }
117
isValueWithinBufferOrZero(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)118 bool isValueWithinBufferOrZero (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
119 {
120 return isValueWithinBuffer(buffer, bufferSize, valuePtr, valueSizeInBytes) || isValueZero(valuePtr, valueSizeInBytes);
121 }
122
verifyOutOfBoundsVec4(const void * vecPtr,VkFormat bufferFormat)123 bool verifyOutOfBoundsVec4 (const void* vecPtr, VkFormat bufferFormat)
124 {
125 if (isUintFormat(bufferFormat))
126 {
127 const deUint32* data = (deUint32*)vecPtr;
128
129 return data[0] == 0u
130 && data[1] == 0u
131 && data[2] == 0u
132 && (data[3] == 0u || data[3] == 1u || data[3] == std::numeric_limits<deUint32>::max());
133 }
134 else if (isIntFormat(bufferFormat))
135 {
136 const deInt32* data = (deInt32*)vecPtr;
137
138 return data[0] == 0
139 && data[1] == 0
140 && data[2] == 0
141 && (data[3] == 0 || data[3] == 1 || data[3] == std::numeric_limits<deInt32>::max());
142 }
143 else if (isFloatFormat(bufferFormat))
144 {
145 const float* data = (float*)vecPtr;
146
147 return areEqual(data[0], 0.0f)
148 && areEqual(data[1], 0.0f)
149 && areEqual(data[2], 0.0f)
150 && (areEqual(data[3], 0.0f) || areEqual(data[3], 1.0f));
151 }
152 else if (bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
153 {
154 return *((deUint32*)vecPtr) == 0xc0000000u;
155 }
156
157 DE_ASSERT(false);
158 return false;
159 }
160
populateBufferWithTestValues(void * buffer,VkDeviceSize size,VkFormat format)161 void populateBufferWithTestValues (void* buffer, VkDeviceSize size, VkFormat format)
162 {
163 // Assign a sequence of 32-bit values
164 for (VkDeviceSize scalarNdx = 0; scalarNdx < size / 4; scalarNdx++)
165 {
166 const deUint32 valueIndex = (deUint32)(2 + scalarNdx); // Do not use 0 or 1
167
168 if (isUintFormat(format))
169 {
170 reinterpret_cast<deUint32*>(buffer)[scalarNdx] = valueIndex;
171 }
172 else if (isIntFormat(format))
173 {
174 reinterpret_cast<deInt32*>(buffer)[scalarNdx] = -deInt32(valueIndex);
175 }
176 else if (isFloatFormat(format))
177 {
178 reinterpret_cast<float*>(buffer)[scalarNdx] = float(valueIndex);
179 }
180 else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
181 {
182 const deUint32 r = ((valueIndex + 0) & ((2u << 10) - 1u));
183 const deUint32 g = ((valueIndex + 1) & ((2u << 10) - 1u));
184 const deUint32 b = ((valueIndex + 2) & ((2u << 10) - 1u));
185 const deUint32 a = ((valueIndex + 0) & ((2u << 2) - 1u));
186
187 reinterpret_cast<deUint32*>(buffer)[scalarNdx] = (a << 30) | (b << 20) | (g << 10) | r;
188 }
189 else
190 {
191 DE_ASSERT(false);
192 }
193 }
194 }
195
logValue(std::ostringstream & logMsg,const void * valuePtr,VkFormat valueFormat,size_t valueSize)196 void logValue (std::ostringstream& logMsg, const void* valuePtr, VkFormat valueFormat, size_t valueSize)
197 {
198 if (isUintFormat(valueFormat))
199 {
200 logMsg << *reinterpret_cast<const deUint32*>(valuePtr);
201 }
202 else if (isIntFormat(valueFormat))
203 {
204 logMsg << *reinterpret_cast<const deInt32*>(valuePtr);
205 }
206 else if (isFloatFormat(valueFormat))
207 {
208 logMsg << *reinterpret_cast<const float*>(valuePtr);
209 }
210 else
211 {
212 const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr);
213 const std::ios::fmtflags streamFlags = logMsg.flags();
214
215 logMsg << std::hex;
216 for (size_t i = 0; i < valueSize; i++)
217 {
218 logMsg << " " << (deUint32)bytePtr[i];
219 }
220 logMsg.flags(streamFlags);
221 }
222 }
223
224 // TestEnvironment
225
TestEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet)226 TestEnvironment::TestEnvironment (Context& context,
227 VkDevice device,
228 VkDescriptorSetLayout descriptorSetLayout,
229 VkDescriptorSet descriptorSet)
230 : m_context (context)
231 , m_device (device)
232 , m_descriptorSetLayout (descriptorSetLayout)
233 , m_descriptorSet (descriptorSet)
234 {
235 const DeviceInterface& vk = context.getDeviceInterface();
236
237 // Create command pool
238 {
239 const VkCommandPoolCreateInfo commandPoolParams =
240 {
241 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
242 DE_NULL, // const void* pNext;
243 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
244 context.getUniversalQueueFamilyIndex() // deUint32 queueFamilyIndex;
245 };
246
247 m_commandPool = createCommandPool(vk, m_device, &commandPoolParams);
248 }
249
250 // Create command buffer
251 {
252 const VkCommandBufferAllocateInfo commandBufferAllocateInfo =
253 {
254 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
255 DE_NULL, // const void* pNext;
256 *m_commandPool, // VkCommandPool commandPool;
257 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
258 1u, // deUint32 bufferCount;
259 };
260
261 m_commandBuffer = allocateCommandBuffer(vk, m_device, &commandBufferAllocateInfo);
262 }
263 }
264
getCommandBuffer(void)265 VkCommandBuffer TestEnvironment::getCommandBuffer (void)
266 {
267 return *m_commandBuffer;
268 }
269
270 // GraphicsEnvironment
271
GraphicsEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet,const VertexBindings & vertexBindings,const VertexAttributes & vertexAttributes,const DrawConfig & drawConfig)272 GraphicsEnvironment::GraphicsEnvironment (Context& context,
273 VkDevice device,
274 VkDescriptorSetLayout descriptorSetLayout,
275 VkDescriptorSet descriptorSet,
276 const VertexBindings& vertexBindings,
277 const VertexAttributes& vertexAttributes,
278 const DrawConfig& drawConfig)
279
280 : TestEnvironment (context, device, descriptorSetLayout, descriptorSet)
281 , m_renderSize (16, 16)
282 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
283 {
284 const DeviceInterface& vk = context.getDeviceInterface();
285 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
286 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
287 SimpleAllocator memAlloc (vk, m_device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
288
289 // Create color image and view
290 {
291 const VkImageCreateInfo colorImageParams =
292 {
293 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
294 DE_NULL, // const void* pNext;
295 0u, // VkImageCreateFlags flags;
296 VK_IMAGE_TYPE_2D, // VkImageType imageType;
297 m_colorFormat, // VkFormat format;
298 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
299 1u, // deUint32 mipLevels;
300 1u, // deUint32 arrayLayers;
301 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
302 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
303 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
304 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
305 1u, // deUint32 queueFamilyIndexCount;
306 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
307 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
308 };
309
310 m_colorImage = createImage(vk, m_device, &colorImageParams);
311 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, m_device, *m_colorImage), MemoryRequirement::Any);
312 VK_CHECK(vk.bindImageMemory(m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
313
314 const VkImageViewCreateInfo colorAttachmentViewParams =
315 {
316 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
317 DE_NULL, // const void* pNext;
318 0u, // VkImageViewCreateFlags flags;
319 *m_colorImage, // VkImage image;
320 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
321 m_colorFormat, // VkFormat format;
322 componentMappingRGBA, // VkComponentMapping components;
323 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
324 };
325
326 m_colorAttachmentView = createImageView(vk, m_device, &colorAttachmentViewParams);
327 }
328
329 // Create render pass
330 m_renderPass = makeRenderPass(vk, m_device, m_colorFormat);
331
332 // Create framebuffer
333 {
334 const VkFramebufferCreateInfo framebufferParams =
335 {
336 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
337 DE_NULL, // const void* pNext;
338 0u, // VkFramebufferCreateFlags flags;
339 *m_renderPass, // VkRenderPass renderPass;
340 1u, // deUint32 attachmentCount;
341 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
342 (deUint32)m_renderSize.x(), // deUint32 width;
343 (deUint32)m_renderSize.y(), // deUint32 height;
344 1u // deUint32 layers;
345 };
346
347 m_framebuffer = createFramebuffer(vk, m_device, &framebufferParams);
348 }
349
350 // Create pipeline layout
351 {
352 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
353 {
354 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
355 DE_NULL, // const void* pNext;
356 0u, // VkPipelineLayoutCreateFlags flags;
357 1u, // deUint32 setLayoutCount;
358 &m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
359 0u, // deUint32 pushConstantRangeCount;
360 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
361 };
362
363 m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams);
364 }
365
366 m_vertexShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("vertex"), 0);
367 m_fragmentShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("fragment"), 0);
368
369 // Create pipeline
370 {
371 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
372 {
373 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
374 DE_NULL, // const void* pNext;
375 0u, // VkPipelineVertexInputStateCreateFlags flags;
376 (deUint32)vertexBindings.size(), // deUint32 vertexBindingDescriptionCount;
377 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
378 (deUint32)vertexAttributes.size(), // deUint32 vertexAttributeDescriptionCount;
379 vertexAttributes.data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
380 };
381
382 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
383 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
384
385 m_graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
386 m_device, // const VkDevice device
387 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
388 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
389 DE_NULL, // const VkShaderModule tessellationControlShaderModule
390 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
391 DE_NULL, // const VkShaderModule geometryShaderModule
392 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
393 *m_renderPass, // const VkRenderPass renderPass
394 viewports, // const std::vector<VkViewport>& viewports
395 scissors, // const std::vector<VkRect2D>& scissors
396 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
397 0u, // const deUint32 subpass
398 0u, // const deUint32 patchControlPoints
399 &vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
400 }
401
402 // Record commands
403 {
404 const VkImageMemoryBarrier imageLayoutBarrier =
405 {
406 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
407 DE_NULL, // const void* pNext;
408 (VkAccessFlags)0, // VkAccessFlags srcAccessMask;
409 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
410 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
411 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
412 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
413 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
414 *m_colorImage, // VkImage image;
415 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
416 };
417
418 beginCommandBuffer(vk, *m_commandBuffer, 0u);
419 {
420 vk.cmdPipelineBarrier(*m_commandBuffer,
421 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
422 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
423 (VkDependencyFlags)0,
424 0u, DE_NULL,
425 0u, DE_NULL,
426 1u, &imageLayoutBarrier);
427
428 beginRenderPass(vk, *m_commandBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
429 {
430 const std::vector<VkDeviceSize> vertexBufferOffsets(drawConfig.vertexBuffers.size(), 0ull);
431
432 vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
433 vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL);
434 vk.cmdBindVertexBuffers(*m_commandBuffer, 0, (deUint32)drawConfig.vertexBuffers.size(), drawConfig.vertexBuffers.data(), vertexBufferOffsets.data());
435
436 if (drawConfig.indexBuffer == DE_NULL || drawConfig.indexCount == 0)
437 {
438 vk.cmdDraw(*m_commandBuffer, drawConfig.vertexCount, drawConfig.instanceCount, 0, 0);
439 }
440 else
441 {
442 vk.cmdBindIndexBuffer(*m_commandBuffer, drawConfig.indexBuffer, 0, VK_INDEX_TYPE_UINT32);
443 vk.cmdDrawIndexed(*m_commandBuffer, drawConfig.indexCount, drawConfig.instanceCount, 0, 0, 0);
444 }
445 }
446 endRenderPass(vk, *m_commandBuffer);
447 }
448 endCommandBuffer(vk, *m_commandBuffer);
449 }
450 }
451
452 // ComputeEnvironment
453
ComputeEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet)454 ComputeEnvironment::ComputeEnvironment (Context& context,
455 VkDevice device,
456 VkDescriptorSetLayout descriptorSetLayout,
457 VkDescriptorSet descriptorSet)
458
459 : TestEnvironment (context, device, descriptorSetLayout, descriptorSet)
460 {
461 const DeviceInterface& vk = context.getDeviceInterface();
462
463 // Create pipeline layout
464 {
465 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
466 {
467 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
468 DE_NULL, // const void* pNext;
469 0u, // VkPipelineLayoutCreateFlags flags;
470 1u, // deUint32 setLayoutCount;
471 &m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
472 0u, // deUint32 pushConstantRangeCount;
473 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
474 };
475
476 m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams);
477 }
478
479 // Create compute pipeline
480 {
481 m_computeShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("compute"), 0);
482
483 const VkPipelineShaderStageCreateInfo computeStageParams =
484 {
485 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
486 DE_NULL, // const void* pNext;
487 0u, // VkPipelineShaderStageCreateFlags flags;
488 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
489 *m_computeShaderModule, // VkShaderModule module;
490 "main", // const char* pName;
491 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
492 };
493
494 const VkComputePipelineCreateInfo computePipelineParams =
495 {
496 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
497 DE_NULL, // const void* pNext;
498 0u, // VkPipelineCreateFlags flags;
499 computeStageParams, // VkPipelineShaderStageCreateInfo stage;
500 *m_pipelineLayout, // VkPipelineLayout layout;
501 DE_NULL, // VkPipeline basePipelineHandle;
502 0u // deInt32 basePipelineIndex;
503 };
504
505 m_computePipeline = createComputePipeline(vk, m_device, DE_NULL, &computePipelineParams);
506 }
507
508 // Record commands
509 {
510 beginCommandBuffer(vk, *m_commandBuffer, 0u);
511 vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
512 vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL);
513 vk.cmdDispatch(*m_commandBuffer, 32, 32, 1);
514 endCommandBuffer(vk, *m_commandBuffer);
515 }
516 }
517
518 } // robustness
519 } // vkt
520