1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Descriptor set tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "amber/vktAmberTestCase.hpp"
25 #include "vktApiDescriptorSetTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vkCmdUtil.hpp"
28 #include "vkMemUtil.hpp"
29 #include "vktApiBufferComputeInstance.hpp"
30 #include "vktApiComputeInstanceResultBuffer.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkObjUtil.hpp"
33
34 #include "vkQueryUtil.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkPrograms.hpp"
37
38 namespace vkt
39 {
40 namespace api
41 {
42
43 namespace
44 {
45
46 using namespace std;
47 using namespace vk;
48
49 // Descriptor set layout used to create a pipeline layout is destroyed prior to creating a pipeline
createPipelineLayoutDestroyDescriptorSetLayout(Context & context)50 Move<VkPipelineLayout> createPipelineLayoutDestroyDescriptorSetLayout(Context &context)
51 {
52 const DeviceInterface &vk = context.getDeviceInterface();
53 const VkDevice device = context.getDevice();
54 Unique<VkDescriptorSetLayout> descriptorSetLayout(createDescriptorSetLayout(context));
55
56 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
57 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
58 DE_NULL, // const void* pNext;
59 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
60 1u, // uint32_t setLayoutCount;
61 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
62 0u, // uint32_t pushConstantRangeCount;
63 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
64 };
65
66 return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
67 }
68
descriptorSetLayoutLifetimeGraphicsTest(Context & context)69 tcu::TestStatus descriptorSetLayoutLifetimeGraphicsTest(Context &context)
70 {
71 const DeviceInterface &vk = context.getDeviceInterface();
72 const VkDevice device = context.getDevice();
73 uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
74 const VkQueue queue = context.getUniversalQueue();
75
76 Unique<VkPipelineLayout> pipelineLayout(createPipelineLayoutDestroyDescriptorSetLayout(context));
77
78 const Unique<VkShaderModule> vertexShaderModule(
79 createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
80
81 const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
82 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
83 DE_NULL, // const void* pNext;
84 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
85 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
86 vertexShaderModule.get(), // VkShaderModule shader;
87 "main", // const char* pName;
88 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
89 };
90
91 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
92 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
93 DE_NULL, // const void* pNext;
94 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
95 0u, // uint32_t vertexBindingDescriptionCount;
96 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
97 0u, // uint32_t vertexAttributeDescriptionCount;
98 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
99 };
100
101 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
102 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
103 DE_NULL, // const void* pNext;
104 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
105 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
106 VK_FALSE // VkBool32 primitiveRestartEnable;
107 };
108
109 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
110 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
111 DE_NULL, // const void* pNext;
112 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
113 VK_FALSE, // VkBool32 depthClampEnable;
114 VK_TRUE, // VkBool32 rasterizerDiscardEnable;
115 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
116 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
117 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
118 VK_FALSE, // VkBool32 depthBiasEnable;
119 0.0f, // float depthBiasConstantFactor;
120 0.0f, // float depthBiasClamp;
121 0.0f, // float depthBiasSlopeFactor;
122 1.0f // float lineWidth;
123 };
124
125 const VkSubpassDescription subpassDescription = {
126 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
127 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
128 0u, // uint32_t inputAttachmentCount
129 DE_NULL, // const VkAttachmentReference* pInputAttachments
130 0u, // uint32_t colorAttachmentCount
131 DE_NULL, // const VkAttachmentReference* pColorAttachments
132 DE_NULL, // const VkAttachmentReference* pResolveAttachments
133 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
134 0u, // uint32_t preserveAttachmentCount
135 DE_NULL // const uint32_t* pPreserveAttachments
136 };
137
138 const VkRenderPassCreateInfo renderPassCreateInfo = {
139 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
140 DE_NULL, // const void* pNext;
141 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
142 0u, // uint32_t attachmentCount
143 DE_NULL, // const VkAttachmentDescription* pAttachments
144 1u, // uint32_t subpassCount
145 &subpassDescription, // const VkSubpassDescription* pSubpasses
146 0u, // uint32_t dependencyCount
147 DE_NULL // const VkSubpassDependency* pDependencies
148 };
149
150 Unique<VkRenderPass> renderPass(createRenderPass(vk, device, &renderPassCreateInfo));
151
152 const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
153 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
154 DE_NULL, // const void* pNext;
155 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
156 1u, // uint32_t stageCount;
157 &shaderStageCreateInfo, // const VkPipelineShaderStageCreateInfo* pStages;
158 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
159 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
160 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
161 DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
162 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
163 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
164 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
165 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
166 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
167 pipelineLayout.get(), // VkPipelineLayout layout;
168 renderPass.get(), // VkRenderPass renderPass;
169 0u, // uint32_t subpass;
170 DE_NULL, // VkPipeline basePipelineHandle;
171 0 // int basePipelineIndex;
172 };
173
174 Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
175
176 VkFramebufferCreateInfo framebufferCreateInfo{
177 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
178 DE_NULL, // const void* pNext
179 0, // VkFramebufferCreateFlags flags
180 *renderPass, // VkRenderPass renderPass
181 0, // uint32_t attachmentCount
182 DE_NULL, // const VkImageView* pAttachments
183 16, // uint32_t width
184 16, // uint32_t height
185 1 // uint32_t layers
186 };
187
188 Move<VkFramebuffer> framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
189
190 const VkCommandPoolCreateInfo cmdPoolInfo = {
191 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // Stype
192 DE_NULL, // PNext
193 DE_NULL, // flags
194 queueFamilyIndex, // queuefamilyindex
195 };
196
197 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
198
199 const VkCommandBufferAllocateInfo cmdBufParams = {
200 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
201 DE_NULL, // const void* pNext;
202 *cmdPool, // VkCommandPool pool;
203 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
204 1u, // uint32_t bufferCount;
205 };
206
207 const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));
208
209 const VkRenderPassBeginInfo renderPassBeginInfo = {
210 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, DE_NULL, *renderPass, *framebuffer, {{0, 0}, {16, 16}}, 0, DE_NULL};
211
212 beginCommandBuffer(vk, *cmdBuf, 0u);
213 {
214 vk.cmdBeginRenderPass(*cmdBuf, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
215 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
216 vk.cmdDraw(*cmdBuf, 3u, 1u, 0, 0);
217 vk.cmdEndRenderPass(*cmdBuf);
218 }
219 endCommandBuffer(vk, *cmdBuf);
220
221 submitCommandsAndWait(vk, device, queue, *cmdBuf);
222
223 // Test should always pass
224 return tcu::TestStatus::pass("Pass");
225 }
226
descriptorSetLayoutLifetimeComputeTest(Context & context)227 tcu::TestStatus descriptorSetLayoutLifetimeComputeTest(Context &context)
228 {
229 const DeviceInterface &vk = context.getDeviceInterface();
230 const VkDevice device = context.getDevice();
231 uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
232 const VkQueue queue = context.getUniversalQueue();
233 Allocator &allocator = context.getDefaultAllocator();
234 const ComputeInstanceResultBuffer result(vk, device, allocator, 0.0f);
235
236 Unique<VkPipelineLayout> pipelineLayout(createPipelineLayoutDestroyDescriptorSetLayout(context));
237
238 const Unique<VkShaderModule> computeShaderModule(
239 createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
240
241 const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
242 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
243 DE_NULL, // const void* pNext;
244 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
245 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
246 computeShaderModule.get(), // VkShaderModule shader;
247 "main", // const char* pName;
248 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
249 };
250
251 const VkComputePipelineCreateInfo computePipelineCreateInfo = {
252 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
253 DE_NULL, // const void* pNext
254 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags
255 shaderStageCreateInfo, // VkPipelineShaderStageCreateInfo stage
256 pipelineLayout.get(), // VkPipelineLayout layout
257 DE_NULL, // VkPipeline basePipelineHandle
258 0 // int basePipelineIndex
259 };
260
261 const uint32_t offset = (0u);
262 const uint32_t addressableSize = 256;
263 const uint32_t dataSize = 8;
264 de::MovePtr<Allocation> bufferMem;
265 const Unique<VkBuffer> buffer(createDataBuffer(context, offset, addressableSize, 0x00, dataSize, 0x5A, &bufferMem));
266 const Unique<VkDescriptorSetLayout> descriptorSetLayout(createDescriptorSetLayout(context));
267 const Unique<VkDescriptorPool> descriptorPool(createDescriptorPool(context));
268 const Unique<VkDescriptorSet> descriptorSet(
269 createDescriptorSet(context, *descriptorPool, *descriptorSetLayout, *buffer, offset, result.getBuffer()));
270
271 Unique<VkPipeline> computePipeline(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
272
273 const VkCommandPoolCreateInfo cmdPoolInfo = {
274 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // Stype
275 DE_NULL, // PNext
276 DE_NULL, // flags
277 queueFamilyIndex, // queuefamilyindex
278 };
279
280 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
281
282 const VkCommandBufferAllocateInfo cmdBufParams = {
283 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 *cmdPool, // VkCommandPool pool;
286 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
287 1u, // uint32_t bufferCount;
288 };
289
290 const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));
291
292 beginCommandBuffer(vk, *cmdBuf, 0u);
293 {
294 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
295 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &*descriptorSet, 0,
296 0);
297 vk.cmdDispatch(*cmdBuf, 1u, 1u, 1u);
298 }
299 endCommandBuffer(vk, *cmdBuf);
300
301 submitCommandsAndWait(vk, device, queue, *cmdBuf);
302
303 // Test should always pass
304 return tcu::TestStatus::pass("Pass");
305 }
306
emptyDescriptorSetLayoutTest(Context & context,VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)307 tcu::TestStatus emptyDescriptorSetLayoutTest(Context &context,
308 VkDescriptorSetLayoutCreateFlags descriptorSetLayoutCreateFlags)
309 {
310 const DeviceInterface &vk = context.getDeviceInterface();
311 const VkDevice device = context.getDevice();
312
313 #ifndef CTS_USES_VULKANSC
314 if (descriptorSetLayoutCreateFlags == VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)
315 if (!context.isDeviceFunctionalitySupported("VK_KHR_push_descriptor"))
316 TCU_THROW(NotSupportedError, "VK_KHR_push_descriptor extension not supported");
317 #endif // CTS_USES_VULKANSC
318
319 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
320 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
321 DE_NULL, // const void* pNext;
322 descriptorSetLayoutCreateFlags, // VkDescriptorSetLayoutCreateFlags flags;
323 0u, // uint32_t bindingCount;
324 DE_NULL // const VkDescriptorSetLayoutBinding* pBindings;
325 };
326
327 Unique<VkDescriptorSetLayout> descriptorSetLayout(
328 createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));
329
330 // Test should always pass
331 return tcu::TestStatus::pass("Pass");
332 }
333
descriptorSetLayoutBindingOrderingTest(Context & context)334 tcu::TestStatus descriptorSetLayoutBindingOrderingTest(Context &context)
335 {
336 /*
337 This test tests that if dstBinding has fewer than
338 descriptorCount array elements remaining starting from dstArrayElement,
339 then the remainder will be used to update the subsequent binding.
340 */
341
342 const DeviceInterface &vk = context.getDeviceInterface();
343 const VkDevice device = context.getDevice();
344 uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
345 const VkQueue queue = context.getUniversalQueue();
346
347 const Unique<VkShaderModule> computeShaderModule(
348 createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
349
350 de::MovePtr<BufferWithMemory> buffer;
351 buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
352 vk, device, context.getDefaultAllocator(), makeBufferCreateInfo(4u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
353 MemoryRequirement::HostVisible));
354 uint32_t *bufferPtr = (uint32_t *)buffer->getAllocation().getHostPtr();
355 *bufferPtr = 5;
356
357 de::MovePtr<BufferWithMemory> resultBuffer;
358 resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
359 vk, device, context.getDefaultAllocator(), makeBufferCreateInfo(4u * 3, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
360 MemoryRequirement::HostVisible));
361
362 const VkDescriptorBufferInfo descriptorBufferInfos[] = {
363 {
364 buffer->get(), // VkBuffer buffer
365 0u, // VkDeviceSize offset
366 VK_WHOLE_SIZE // VkDeviceSize range
367 },
368 {
369 buffer->get(), // VkBuffer buffer
370 0u, // VkDeviceSize offset
371 VK_WHOLE_SIZE // VkDeviceSize range
372 },
373 {
374 buffer->get(), // VkBuffer buffer
375 0u, // VkDeviceSize offset
376 VK_WHOLE_SIZE // VkDeviceSize range
377 },
378 };
379
380 const VkDescriptorBufferInfo descriptorBufferInfoResult = {
381 resultBuffer->get(), // VkBuffer buffer
382 0u, // VkDeviceSize offset
383 VK_WHOLE_SIZE // VkDeviceSize range
384 };
385
386 const VkDescriptorSetLayoutBinding layoutBindings[] = {
387 {
388 0u, // uint32_t binding;
389 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
390 2u, // uint32_t descriptorCount;
391 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
392 DE_NULL // const VkSampler* pImmutableSamplers;
393 },
394 {
395 1u, // uint32_t binding;
396 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
397 1u, // uint32_t descriptorCount;
398 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
399 DE_NULL // const VkSampler* pImmutableSamplers;
400 },
401 {
402 2u, // uint32_t binding;
403 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
404 1u, // uint32_t descriptorCount;
405 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
406 DE_NULL // const VkSampler* pImmutableSamplers;
407 }};
408
409 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
410 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
411 DE_NULL, // const void* pNext;
412 0u, // VkDescriptorSetLayoutCreateFlags flags;
413 DE_LENGTH_OF_ARRAY(layoutBindings), // uint32_t bindingCount;
414 layoutBindings // const VkDescriptorSetLayoutBinding* pBindings;
415 };
416
417 Move<VkDescriptorSetLayout> descriptorSetLayout(
418 createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo));
419
420 const VkDescriptorPoolSize poolSize[] = {
421 {
422 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType type
423 3u // uint32_t descriptorCount
424 },
425 {
426 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType type
427 1u // uint32_t descriptorCount
428 }};
429
430 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
431 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
432 DE_NULL, // const void* pNext
433 0u, // VkDescriptorPoolCreateFlags flags
434 1u, // uint32_t maxSets
435 2u, // uint32_t poolSizeCount
436 poolSize // const VkDescriptorPoolSize* pPoolSizes
437 };
438
439 Move<VkDescriptorPool> descriptorPool(createDescriptorPool(vk, device, &descriptorPoolCreateInfo));
440
441 VkDescriptorSet descriptorSet;
442 {
443 const VkDescriptorSetAllocateInfo allocInfo = {
444 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructure sType
445 DE_NULL, // const void* pNext
446 *descriptorPool, // VkDescriptorPool descriptorPool
447 1u, // uint32_t descriptorSetCount
448 &*descriptorSetLayout // const VkDescriptorSetLayout* pSetLayouts
449 };
450
451 VK_CHECK(vk.allocateDescriptorSets(device, &allocInfo, &descriptorSet));
452 }
453
454 const VkWriteDescriptorSet descriptorWrite = {
455 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
456 DE_NULL, // const void* pNext
457 descriptorSet, // VkDescriptorSet dstSet
458 0u, // uint32_t dstBinding
459 0u, // uint32_t dstArrayElement
460 3u, // uint32_t descriptorCount
461 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType
462 DE_NULL, // const VkDescriptorImageInfo pImageInfo
463 descriptorBufferInfos, // const VkDescriptorBufferInfo* pBufferInfo
464 DE_NULL // const VkBufferView* pTexelBufferView
465 };
466
467 const VkWriteDescriptorSet descriptorWriteResult = {
468 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
469 DE_NULL, // const void* pNext
470 descriptorSet, // VkDescriptorSet dstSet
471 2u, // uint32_t dstBinding
472 0u, // uint32_t dstArrayElement
473 1u, // uint32_t descriptorCount
474 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType
475 DE_NULL, // const VkDescriptorImageInfo pImageInfo
476 &descriptorBufferInfoResult, // const VkDescriptorBufferInfo* pBufferInfo
477 DE_NULL // const VkBufferView* pTexelBufferView
478 };
479
480 const VkCommandPoolCreateInfo cmdPoolInfo = {
481 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType Stype
482 DE_NULL, // const void* PNext
483 DE_NULL, // VkCommandPoolCreateFlags flags
484 queueFamilyIndex, // uint32_t queuefamilyindex
485 };
486
487 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
488
489 const VkCommandBufferAllocateInfo cmdBufParams = {
490 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
491 DE_NULL, // const void* pNext;
492 *cmdPool, // VkCommandPool pool;
493 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
494 1u, // uint32_t bufferCount;
495 };
496
497 const Unique<VkCommandBuffer> cmdBuf(allocateCommandBuffer(vk, device, &cmdBufParams));
498
499 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
500 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
501 DE_NULL, // const void* pNext
502 0, // VkPipelineLayoutCreateFlags flags
503 1u, // uint32_t setLayoutCount
504 &*descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts
505 0u, // uint32_t pushConstantRangeCount
506 nullptr // const VkPushConstantRange* pPushConstantRanges
507 };
508
509 Move<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, device, &pipelineLayoutCreateInfo));
510
511 const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
512 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
513 DE_NULL, // const void* pNext;
514 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
515 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
516 computeShaderModule.get(), // VkShaderModule shader;
517 "main", // const char* pName;
518 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
519 };
520
521 const VkComputePipelineCreateInfo computePipelineCreateInfo = {
522 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
523 DE_NULL, // const void* pNext
524 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags
525 shaderStageCreateInfo, // VkPipelineShaderStageCreateInfo stage
526 *pipelineLayout, // VkPipelineLayout layout
527 DE_NULL, // VkPipeline basePipelineHandle
528 0 // int basePipelineIndex
529 };
530
531 Unique<VkPipeline> computePipeline(createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
532
533 beginCommandBuffer(vk, *cmdBuf, 0u);
534 {
535 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
536 vk.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
537 vk.updateDescriptorSets(device, 1u, &descriptorWriteResult, 0u, DE_NULL);
538 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1u, &descriptorSet, 0,
539 nullptr);
540 flushAlloc(vk, device, buffer->getAllocation());
541 vk.cmdDispatch(*cmdBuf, 1u, 1u, 1u);
542 }
543
544 endCommandBuffer(vk, *cmdBuf);
545 submitCommandsAndWait(vk, device, queue, *cmdBuf);
546
547 const Allocation &bufferAllocationResult = resultBuffer->getAllocation();
548 invalidateAlloc(vk, device, bufferAllocationResult);
549
550 const uint32_t *resultPtr = static_cast<uint32_t *>(bufferAllocationResult.getHostPtr());
551
552 if (resultPtr[0] == 5 && resultPtr[1] == 5 && resultPtr[2] == 5)
553 return tcu::TestStatus::pass("Pass");
554 else
555 return tcu::TestStatus::fail("Fail");
556 }
557 } // namespace
558
createDescriptorSetLayoutLifetimeGraphicsSource(SourceCollections & dst)559 void createDescriptorSetLayoutLifetimeGraphicsSource(SourceCollections &dst)
560 {
561 dst.glslSources.add("vertex") << glu::VertexSource("#version 310 es\n"
562 "void main (void)\n"
563 "{\n"
564 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
565 "}\n");
566 }
567
createDescriptorSetLayoutLifetimeComputeSource(SourceCollections & dst)568 void createDescriptorSetLayoutLifetimeComputeSource(SourceCollections &dst)
569 {
570 dst.glslSources.add("compute") << glu::ComputeSource(
571 "#version 310 es\n"
572 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
573 "void main (void)\n"
574 "{\n"
575 "}\n");
576 }
577
createDescriptorSetLayoutBindingOrderingSource(SourceCollections & dst)578 void createDescriptorSetLayoutBindingOrderingSource(SourceCollections &dst)
579 {
580 dst.glslSources.add("compute") << glu::ComputeSource(
581 "#version 310 es\n"
582 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
583 "layout (set = 0, binding = 0) uniform UniformBuffer0 {\n"
584 " int data;\n"
585 "} uniformbufferarray[2];\n"
586 "layout (set = 0, binding = 1) uniform UniformBuffer2 {\n"
587 " int data;\n"
588 "} uniformbuffer2;\n"
589 "layout (set = 0, binding = 2) buffer StorageBuffer {\n"
590 " int result0;\n"
591 " int result1;\n"
592 " int result2;\n"
593 "} results;\n"
594 "\n"
595 "void main (void)\n"
596 "{\n"
597 " results.result0 = uniformbufferarray[0].data;\n"
598 " results.result1 = uniformbufferarray[1].data;\n"
599 " results.result2 = uniformbuffer2.data;\n"
600 "}\n");
601 }
602
createDescriptorSetLayoutLifetimeTests(tcu::TestContext & testCtx)603 tcu::TestCaseGroup *createDescriptorSetLayoutLifetimeTests(tcu::TestContext &testCtx)
604 {
605 // Descriptor set layout lifetime tests
606 de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutLifetimeTests(
607 new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_lifetime"));
608
609 // Test descriptor set layout lifetime in graphics pipeline
610 addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "graphics",
611 createDescriptorSetLayoutLifetimeGraphicsSource,
612 descriptorSetLayoutLifetimeGraphicsTest);
613 // Test descriptor set layout lifetime in compute pipeline
614 addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "compute",
615 createDescriptorSetLayoutLifetimeComputeSource, descriptorSetLayoutLifetimeComputeTest);
616
617 return descriptorSetLayoutLifetimeTests.release();
618 }
619
createEmptyDescriptorSetLayoutTests(tcu::TestContext & testCtx)620 tcu::TestCaseGroup *createEmptyDescriptorSetLayoutTests(tcu::TestContext &testCtx)
621 {
622 // Create empty descriptor set layout tests
623 de::MovePtr<tcu::TestCaseGroup> emptyDescriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "empty_set"));
624
625 // Create empty desciptor set layout
626 addFunctionCase(emptyDescriptorSetLayoutTests.get(), "normal", emptyDescriptorSetLayoutTest,
627 (VkDescriptorSetLayoutCreateFlags)0u);
628 #ifndef CTS_USES_VULKANSC
629 // Removed from Vulkan SC test set: VK_KHR_push_descriptor extension removed from Vulkan SC
630 // Create empty push descriptor set layout
631 addFunctionCase(emptyDescriptorSetLayoutTests.get(), "push_descriptor", emptyDescriptorSetLayoutTest,
632 (VkDescriptorSetLayoutCreateFlags)VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
633 #endif // CTS_USES_VULKANSC
634 return emptyDescriptorSetLayoutTests.release();
635 }
636
createDescriptorSetLayoutBindingOrderingTests(tcu::TestContext & testCtx)637 tcu::TestCaseGroup *createDescriptorSetLayoutBindingOrderingTests(tcu::TestContext &testCtx)
638 {
639 de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutBindingOrderingTests(
640 new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_binding"));
641 // Test subsequent binding update with remaining elements
642 addFunctionCaseWithPrograms(descriptorSetLayoutBindingOrderingTests.get(), "update_subsequent_binding",
643 createDescriptorSetLayoutBindingOrderingSource, descriptorSetLayoutBindingOrderingTest);
644
645 #ifndef CTS_USES_VULKANSC
646 static const char dataDir[] = "api/descriptor_set/descriptor_set_layout_binding";
647 descriptorSetLayoutBindingOrderingTests->addChild(
648 cts_amber::createAmberTestCase(testCtx, "layout_binding_order", "Test descriptor set layout binding order",
649 dataDir, "layout_binding_order.amber"));
650 #endif // CTS_USES_VULKANSC
651
652 return descriptorSetLayoutBindingOrderingTests.release();
653 }
654
createDescriptorSetLayoutTests(tcu::TestContext & testCtx)655 tcu::TestCaseGroup *createDescriptorSetLayoutTests(tcu::TestContext &testCtx)
656 {
657 de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout"));
658
659 descriptorSetLayoutTests->addChild(createEmptyDescriptorSetLayoutTests(testCtx));
660
661 return descriptorSetLayoutTests.release();
662 }
663
createDescriptorSetTests(tcu::TestContext & testCtx)664 tcu::TestCaseGroup *createDescriptorSetTests(tcu::TestContext &testCtx)
665 {
666 de::MovePtr<tcu::TestCaseGroup> descriptorSetTests(new tcu::TestCaseGroup(testCtx, "descriptor_set"));
667
668 descriptorSetTests->addChild(createDescriptorSetLayoutLifetimeTests(testCtx));
669 descriptorSetTests->addChild(createDescriptorSetLayoutTests(testCtx));
670 descriptorSetTests->addChild(createDescriptorSetLayoutBindingOrderingTests(testCtx));
671
672 return descriptorSetTests.release();
673 }
674
675 } // namespace api
676 } // namespace vkt
677