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