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