1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 * Copyright (c) 2018 Google Inc.
7 * Copyright (c) 2018 ARM Limited.
8 * Copyright (c) 2023 LunarG, Inc.
9 * Copyright (c) 2023 Nintendo
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *
23 *//*!
24 * \file
25 * \brief Push Descriptor Tests
26 *//*--------------------------------------------------------------------*/
27
28 #include "vktPipelinePushDescriptorTests.hpp"
29 #include "vktPipelineClearUtil.hpp"
30 #include "vktPipelineImageUtil.hpp"
31 #include "vktPipelineVertexUtil.hpp"
32 #include "vktPipelineReferenceRenderer.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktCustomInstancesDevices.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkRef.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkCmdUtil.hpp"
43 #include "vkObjUtil.hpp"
44 #include "vkDeviceUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "deMemory.h"
47 #include "deUniquePtr.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuCommandLine.hpp"
50 #include <vector>
51
52 namespace vkt
53 {
54 namespace pipeline
55 {
56
57 using namespace vk;
58 using namespace std;
59
60 namespace
61 {
62 typedef vector<VkExtensionProperties> Extensions;
63 typedef de::SharedPtr<Unique<VkBuffer>> VkBufferSp;
64 typedef de::SharedPtr<Unique<VkImage>> VkImageSp;
65 typedef de::SharedPtr<Unique<VkImageView>> VkImageViewSp;
66 typedef de::SharedPtr<Unique<VkBufferView>> VkBufferViewSp;
67 typedef de::SharedPtr<Allocation> AllocationSp;
68 typedef de::SharedPtr<RenderPassWrapper> VkRenderPassSp;
69
70 constexpr VkDeviceSize kSizeofVec4 = static_cast<VkDeviceSize>(sizeof(tcu::Vec4));
71
72 struct TestParams
73 {
74 PipelineConstructionType pipelineConstructionType; // Used only by graphics pipeline tests
75 VkDescriptorType descriptorType;
76 uint32_t binding;
77 uint32_t numCalls; // Number of draw or dispatch calls
78 bool useMaintenance5;
79 };
80
calcItemSize(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,uint32_t numElements=1u)81 VkDeviceSize calcItemSize(const InstanceInterface &vki, VkPhysicalDevice physicalDevice, uint32_t numElements = 1u)
82 {
83 const auto minAlignment = getPhysicalDeviceProperties(vki, physicalDevice).limits.minStorageBufferOffsetAlignment;
84 const auto lcm = de::lcm(de::max(VkDeviceSize{1}, minAlignment), kSizeofVec4);
85 return de::roundUp(kSizeofVec4 * numElements, lcm);
86 }
87
checkAllSupported(const Extensions & supportedExtensions,const vector<string> & requiredExtensions)88 void checkAllSupported(const Extensions &supportedExtensions, const vector<string> &requiredExtensions)
89 {
90 for (auto &requiredExtName : requiredExtensions)
91 {
92 if (!isExtensionStructSupported(supportedExtensions, RequiredExtension(requiredExtName)))
93 TCU_THROW(NotSupportedError, (requiredExtName + " is not supported").c_str());
94 }
95 }
96
createInstanceWithGetPhysicalDeviceProperties2(Context & context,const Extensions & supportedExtensions)97 CustomInstance createInstanceWithGetPhysicalDeviceProperties2(Context &context, const Extensions &supportedExtensions)
98 {
99 vector<string> requiredExtensions = {"VK_KHR_get_physical_device_properties2"};
100 checkAllSupported(supportedExtensions, requiredExtensions);
101
102 return createCustomInstanceWithExtensions(context, requiredExtensions);
103 }
104
innerCString(const string & str)105 const char *innerCString(const string &str)
106 {
107 return str.c_str();
108 }
109
createDeviceWithPushDescriptor(const Context & context,const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const Extensions & supportedExtensions,const uint32_t queueFamilyIndex,const TestParams & params,std::vector<std::string> & enabledExtensions)110 Move<VkDevice> createDeviceWithPushDescriptor(const Context &context, const PlatformInterface &vkp, VkInstance instance,
111 const InstanceInterface &vki, VkPhysicalDevice physicalDevice,
112 const Extensions &supportedExtensions, const uint32_t queueFamilyIndex,
113 const TestParams ¶ms, std::vector<std::string> &enabledExtensions)
114 {
115
116 const float queuePriority = 1.0f;
117 const VkDeviceQueueCreateInfo queueInfo = {VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
118 nullptr,
119 (VkDeviceQueueCreateFlags)0,
120 queueFamilyIndex,
121 1u,
122 &queuePriority};
123
124 VkPhysicalDeviceFeatures features;
125 deMemset(&features, 0, sizeof(features));
126
127 VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT graphicsPipelineLibraryFeaturesEXT = initVulkanStructure();
128 VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeaturesKHR = initVulkanStructure();
129 VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeaturesEXT = initVulkanStructure(&dynamicRenderingFeaturesKHR);
130 VkPhysicalDeviceVulkan14Features vulkan14Features = initVulkanStructure();
131 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure();
132 bool useFeatures2 = params.pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC;
133
134 vector<string> requiredExtensionsStr;
135 if (context.getUsedApiVersion() > VK_API_VERSION_1_3)
136 {
137 useFeatures2 = true;
138 vulkan14Features.pushDescriptor = true;
139 vulkan14Features.maintenance5 = params.useMaintenance5;
140 dynamicRenderingFeaturesKHR.pNext = &vulkan14Features;
141 graphicsPipelineLibraryFeaturesEXT.pNext = &vulkan14Features;
142 }
143 else
144 {
145 requiredExtensionsStr.push_back("VK_KHR_push_descriptor");
146 if (params.useMaintenance5)
147 requiredExtensionsStr.push_back("VK_KHR_maintenance5");
148 }
149
150 if (isConstructionTypeLibrary(params.pipelineConstructionType))
151 {
152 features2.pNext = &graphicsPipelineLibraryFeaturesEXT;
153 requiredExtensionsStr.push_back("VK_KHR_pipeline_library");
154 requiredExtensionsStr.push_back("VK_EXT_graphics_pipeline_library");
155 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
156 if (!graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary)
157 TCU_THROW(NotSupportedError, "graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary required");
158 }
159 else if (isConstructionTypeShaderObject(params.pipelineConstructionType))
160 {
161 features2.pNext = &shaderObjectFeaturesEXT;
162 if (context.getUsedApiVersion() < VK_API_VERSION_1_3)
163 requiredExtensionsStr.push_back("VK_KHR_dynamic_rendering");
164 requiredExtensionsStr.push_back("VK_EXT_shader_object");
165 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
166 if (!shaderObjectFeaturesEXT.shaderObject)
167 TCU_THROW(NotSupportedError, "shaderObjectFeaturesEXT.shaderObject required");
168 if (!dynamicRenderingFeaturesKHR.dynamicRendering)
169 TCU_THROW(NotSupportedError, "dynamicRendering required");
170 }
171
172 vector<const char *> requiredExtensions;
173 checkAllSupported(supportedExtensions, requiredExtensionsStr);
174 // We need the contents of requiredExtensionsStr as a vector<const char*> in VkDeviceCreateInfo.
175 transform(begin(requiredExtensionsStr), end(requiredExtensionsStr), back_inserter(requiredExtensions),
176 innerCString);
177
178 // Enable validation layers on this device if validation has been requested from the command line.
179 const VkDeviceCreateInfo deviceParams = {VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
180 useFeatures2 ? &features2 : nullptr,
181 (VkDeviceCreateFlags)0,
182 1u,
183 &queueInfo,
184 0u,
185 nullptr,
186 static_cast<uint32_t>(requiredExtensions.size()),
187 de::dataOrNull(requiredExtensions),
188 useFeatures2 ? nullptr : &features};
189
190 for (const auto &enabledExt : requiredExtensions)
191 enabledExtensions.push_back(enabledExt);
192
193 return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki,
194 physicalDevice, &deviceParams, nullptr);
195 }
196
createQuads(uint32_t numQuads,float size)197 vector<Vertex4RGBA> createQuads(uint32_t numQuads, float size)
198 {
199 vector<Vertex4RGBA> vertices;
200
201 for (uint32_t quadNdx = 0; quadNdx < numQuads; quadNdx++)
202 {
203 const float xOffset = -0.5f + (float)quadNdx;
204 const tcu::Vec4 color(0.0f);
205 const Vertex4RGBA lowerLeftVertex = {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), color};
206 const Vertex4RGBA lowerRightVertex = {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), color};
207 const Vertex4RGBA UpperLeftVertex = {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), color};
208 const Vertex4RGBA UpperRightVertex = {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f), color};
209
210 vertices.push_back(lowerLeftVertex);
211 vertices.push_back(lowerRightVertex);
212 vertices.push_back(UpperLeftVertex);
213 vertices.push_back(UpperLeftVertex);
214 vertices.push_back(lowerRightVertex);
215 vertices.push_back(UpperRightVertex);
216 }
217
218 return vertices;
219 }
220
createTexQuads(uint32_t numQuads,float size)221 vector<Vertex4Tex4> createTexQuads(uint32_t numQuads, float size)
222 {
223 vector<Vertex4Tex4> vertices;
224
225 for (uint32_t quadNdx = 0; quadNdx < numQuads; quadNdx++)
226 {
227 const float xOffset = -0.5f + (float)quadNdx;
228 const Vertex4Tex4 lowerLeftVertex = {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f),
229 tcu::Vec4(-0.2f, -0.2f, 0.0f, 0.0f)};
230 const Vertex4Tex4 lowerRightVertex = {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f),
231 tcu::Vec4(1.2f, -0.2f, 0.0f, 0.0f)};
232 const Vertex4Tex4 UpperLeftVertex = {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f),
233 tcu::Vec4(-0.2f, 1.2f, 0.0f, 0.0f)};
234 const Vertex4Tex4 UpperRightVertex = {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f),
235 tcu::Vec4(1.2f, 1.2f, 0.0f, 0.0f)};
236
237 vertices.push_back(lowerLeftVertex);
238 vertices.push_back(lowerRightVertex);
239 vertices.push_back(UpperLeftVertex);
240 vertices.push_back(UpperLeftVertex);
241 vertices.push_back(lowerRightVertex);
242 vertices.push_back(UpperRightVertex);
243 }
244
245 return vertices;
246 }
247
248 static const tcu::Vec4 defaultTestColors[] =
249
250 {tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)};
251
252 class PushDescriptorBufferGraphicsTestInstance : public vkt::TestInstance
253 {
254 public:
255 PushDescriptorBufferGraphicsTestInstance(Context &context, const TestParams ¶ms);
256 virtual ~PushDescriptorBufferGraphicsTestInstance(void);
257 void init(void);
258 virtual tcu::TestStatus iterate(void);
259 tcu::TestStatus verifyImage(void);
260
261 private:
262 const TestParams m_params;
263 const PlatformInterface &m_vkp;
264 const Extensions m_instanceExtensions;
265 const CustomInstance m_instance;
266 const InstanceDriver &m_vki;
267 const VkPhysicalDevice m_physicalDevice;
268 const uint32_t m_queueFamilyIndex;
269 const Extensions m_deviceExtensions;
270 std::vector<std::string> m_deviceEnabledExtensions;
271 const Unique<VkDevice> m_device;
272 const DeviceDriver m_vkd;
273 const VkQueue m_queue;
274 SimpleAllocator m_allocator;
275 const tcu::UVec2 m_renderSize;
276 const VkFormat m_colorFormat;
277 Move<VkImage> m_colorImage;
278 de::MovePtr<Allocation> m_colorImageAlloc;
279 Move<VkImageView> m_colorAttachmentView;
280 RenderPassWrapper m_renderPass;
281 Move<VkFramebuffer> m_framebuffer;
282 ShaderWrapper m_vertexShaderModule;
283 ShaderWrapper m_fragmentShaderModule;
284 Move<VkBuffer> m_vertexBuffer;
285 de::MovePtr<Allocation> m_vertexBufferAlloc;
286 vector<VkBufferSp> m_buffers;
287 vector<AllocationSp> m_bufferAllocs;
288 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
289 PipelineLayoutWrapper m_preRasterizationStatePipelineLayout;
290 PipelineLayoutWrapper m_fragmentStatePipelineLayout;
291 GraphicsPipelineWrapper m_graphicsPipeline;
292 Move<VkCommandPool> m_cmdPool;
293 Move<VkCommandBuffer> m_cmdBuffer;
294 vector<Vertex4RGBA> m_vertices;
295 };
296
PushDescriptorBufferGraphicsTestInstance(Context & context,const TestParams & params)297 PushDescriptorBufferGraphicsTestInstance::PushDescriptorBufferGraphicsTestInstance(Context &context,
298 const TestParams ¶ms)
299 : vkt::TestInstance(context)
300 , m_params(params)
301 , m_vkp(context.getPlatformInterface())
302 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
303 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
304 , m_vki(m_instance.getDriver())
305 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
306 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
307 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
308 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
309 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
310 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
311 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
312 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
313 , m_renderSize(32, 32)
314 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
315 , m_graphicsPipeline(m_vki, m_vkd, m_physicalDevice, *m_device, m_deviceEnabledExtensions,
316 params.pipelineConstructionType)
317 , m_vertices(createQuads(params.numCalls, 0.25f))
318 {
319 }
320
init(void)321 void PushDescriptorBufferGraphicsTestInstance::init(void)
322 {
323 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
324 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
325
326 // Create color image
327 {
328
329 const VkImageCreateInfo colorImageParams = {
330 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
331 nullptr, // const void* pNext;
332 0u, // VkImageCreateFlags flags;
333 VK_IMAGE_TYPE_2D, // VkImageType imageType;
334 m_colorFormat, // VkFormat format;
335 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
336 1u, // uint32_t mipLevels;
337 1u, // uint32_t arrayLayers;
338 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
339 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
340 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
341 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
342 1u, // uint32_t queueFamilyIndexCount;
343 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
344 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
345 };
346
347 m_colorImage = createImage(m_vkd, *m_device, &colorImageParams);
348
349 // Allocate and bind color image memory
350 m_colorImageAlloc =
351 m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
352 VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(),
353 m_colorImageAlloc->getOffset()));
354 }
355
356 // Create color attachment view
357 {
358 const VkImageViewCreateInfo colorAttachmentViewParams = {
359 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
360 nullptr, // const void* pNext;
361 0u, // VkImageViewCreateFlags flags;
362 *m_colorImage, // VkImage image;
363 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
364 m_colorFormat, // VkFormat format;
365 componentMappingRGBA, // VkChannelMapping channels;
366 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}, // VkImageSubresourceRange subresourceRange;
367 };
368
369 m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
370 }
371
372 // Create render pass
373 m_renderPass = RenderPassWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, m_colorFormat);
374
375 // Create framebuffer
376 {
377 const VkImageView attachmentBindInfos[] = {*m_colorAttachmentView};
378
379 const VkFramebufferCreateInfo framebufferParams = {
380 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
381 nullptr, // const void* pNext;
382 0u, // VkFramebufferCreateFlags flags;
383 *m_renderPass, // VkRenderPass renderPass;
384 1u, // uint32_t attachmentCount;
385 attachmentBindInfos, // const VkImageView* pAttachments;
386 (uint32_t)m_renderSize.x(), // uint32_t width;
387 (uint32_t)m_renderSize.y(), // uint32_t height;
388 1u // uint32_t layers;
389 };
390
391 m_renderPass.createFramebuffer(m_vkd, *m_device, &framebufferParams, *m_colorImage);
392 }
393
394 // Create pipeline layout
395 {
396 // Create descriptor set layout
397 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
398 m_params.binding, // uint32_t binding;
399 m_params.descriptorType, // VkDescriptorType descriptorType;
400 1u, // uint32_t descriptorCount;
401 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlags stageFlags;
402 nullptr // const VkSampler* pImmutableSamplers;
403 };
404
405 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
406 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
407 nullptr, // const void* pNext;
408 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
409 1u, // uint32_t bindingCount;
410 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
411 };
412
413 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
414
415 // Create pipeline layout
416 VkPipelineLayoutCreateFlags pipelineLayoutFlags =
417 (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ?
418 0u :
419 uint32_t(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
420 VkPipelineLayoutCreateInfo pipelineLayoutParams{
421 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
422 nullptr, // const void* pNext;
423 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags;
424 1u, // uint32_t setLayoutCount;
425 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
426 0u, // uint32_t pushConstantRangeCount;
427 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
428 };
429
430 m_preRasterizationStatePipelineLayout =
431 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
432 pipelineLayoutParams.setLayoutCount = 0u;
433 pipelineLayoutParams.pSetLayouts = nullptr;
434 m_fragmentStatePipelineLayout =
435 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
436 }
437
438 // Create buffers. One color value in each buffer.
439 {
440 VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = vk::initVulkanStructure();
441 for (uint32_t bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
442 {
443 const VkBufferUsageFlags usageFlags = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ?
444 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT :
445 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
446
447 VkBufferCreateInfo bufferCreateInfo{
448 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
449 nullptr, // const void* pNext;
450 0u, // VkBufferCreateFlags flags
451 kSizeofVec4, // VkDeviceSize size;
452 usageFlags, // VkBufferUsageFlags usage;
453 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
454 1u, // uint32_t queueFamilyCount;
455 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
456 };
457
458 if (m_params.useMaintenance5)
459 {
460 bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)usageFlags;
461 bufferCreateInfo.pNext = &bufferUsageFlags2;
462 bufferCreateInfo.usage = 0;
463 }
464
465 m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
466 m_bufferAllocs.push_back(
467 AllocationSp(m_allocator
468 .allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]),
469 MemoryRequirement::HostVisible)
470 .release()));
471 VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(),
472 m_bufferAllocs[bufIdx]->getOffset()));
473
474 deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx],
475 static_cast<size_t>(kSizeofVec4));
476 flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
477 }
478 }
479
480 // Create shaders
481 {
482 m_vertexShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
483 m_fragmentShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
484 }
485
486 // Create pipeline
487 {
488 const VkVertexInputBindingDescription vertexInputBindingDescription = {
489 0u, // uint32_t binding;
490 sizeof(Vertex4RGBA), // uint32_t strideInBytes;
491 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
492 };
493
494 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
495 {
496 0u, // uint32_t location;
497 0u, // uint32_t binding;
498 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
499 0u // uint32_t offsetInBytes;
500 },
501 {
502 1u, // uint32_t location;
503 0u, // uint32_t binding;
504 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
505 offsetof(Vertex4RGBA, color), // uint32_t offset;
506 }};
507
508 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
509 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
510 nullptr, // const void* pNext;
511 0u, // vkPipelineVertexInputStateCreateFlags flags;
512 1u, // uint32_t bindingCount;
513 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
514 2u, // uint32_t attributeCount;
515 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
516 };
517
518 const VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
519
520 const vector<VkViewport> viewports{makeViewport(m_renderSize)};
521 const vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
522
523 m_graphicsPipeline.setDefaultRasterizationState()
524 .setDefaultDepthStencilState()
525 .setDefaultMultisampleState()
526 .setDefaultColorBlendState()
527 .setDefaultTopology(topology)
528 .setupVertexInputState(&vertexInputStateParams)
529 .setupPreRasterizationShaderState(viewports, scissors, m_preRasterizationStatePipelineLayout, *m_renderPass,
530 0u, m_vertexShaderModule)
531 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule)
532 .setupFragmentOutputState(*m_renderPass)
533 .setMonolithicPipelineLayout(m_preRasterizationStatePipelineLayout)
534 .buildPipeline();
535 }
536
537 // Create vertex buffer
538 {
539 const VkBufferCreateInfo vertexBufferParams = {
540 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
541 nullptr, // const void* pNext;
542 0u, // VkBufferCreateFlags flags;
543 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size;
544 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
545 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
546 1u, // uint32_t queueFamilyCount;
547 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
548 };
549
550 m_vertexBuffer = createBuffer(m_vkd, *m_device, &vertexBufferParams);
551 m_vertexBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer),
552 MemoryRequirement::HostVisible);
553
554 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
555 m_vertexBufferAlloc->getOffset()));
556
557 // Load vertices into vertex buffer
558 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
559 flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
560 }
561
562 // Create command pool
563 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
564
565 // Create command buffer
566 {
567 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
568 const VkDeviceSize vertexBufferOffset = 0;
569
570 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
571 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
572 m_renderPass.begin(m_vkd, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
573 attachmentClearValue);
574 m_graphicsPipeline.bind(*m_cmdBuffer);
575 m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
576
577 // Draw quads. Switch input buffer which contains the quad color for each draw call.
578 for (uint32_t quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
579 {
580 VkDescriptorBufferInfo descriptorBufferInfo = {
581 **m_buffers[quadNdx], // VkBuffer buffer;
582 0u, // VkDeviceSize offset;
583 kSizeofVec4, // VkDeviceSize range;
584 };
585
586 VkWriteDescriptorSet writeDescriptorSet = {
587 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
588 nullptr, // const void* pNext;
589 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
590 m_params.binding, // uint32_t dstBinding;
591 0u, // uint32_t dstArrayElement;
592 1u, // uint32_t descriptorCount;
593 m_params.descriptorType, // VkDescriptorType descriptorType;
594 nullptr, // const VkDescriptorImageInfo* pImageInfo;
595 &descriptorBufferInfo, // const VkDescriptorBufferInfo* pBufferInfo;
596 nullptr // const VkBufferView* pTexelBufferView;
597 };
598
599 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
600 *m_preRasterizationStatePipelineLayout, 0, 1, &writeDescriptorSet);
601 m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
602 }
603
604 m_renderPass.end(m_vkd, *m_cmdBuffer);
605 endCommandBuffer(m_vkd, *m_cmdBuffer);
606 }
607 }
608
~PushDescriptorBufferGraphicsTestInstance(void)609 PushDescriptorBufferGraphicsTestInstance::~PushDescriptorBufferGraphicsTestInstance(void)
610 {
611 }
612
iterate(void)613 tcu::TestStatus PushDescriptorBufferGraphicsTestInstance::iterate(void)
614 {
615 init();
616
617 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
618
619 return verifyImage();
620 }
621
verifyImage(void)622 tcu::TestStatus PushDescriptorBufferGraphicsTestInstance::verifyImage(void)
623 {
624 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
625 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
626 const ColorVertexShader vertexShader;
627 const ColorFragmentShader fragmentShader(tcuColorFormat, tcuDepthFormat);
628 const rr::Program program(&vertexShader, &fragmentShader);
629 ReferenceRenderer refRenderer(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
630 bool compareOk = false;
631
632 // Render reference image
633 {
634 for (uint32_t quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
635 for (uint32_t vertexIdx = 0; vertexIdx < 6; vertexIdx++)
636 m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];
637
638 refRenderer.draw(rr::RenderState(refRenderer.getViewportState(),
639 m_context.getDeviceProperties().limits.subPixelPrecisionBits),
640 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
641 }
642
643 // Compare result with reference image
644 {
645 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(
646 m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
647
648 compareOk = tcu::intThresholdPositionDeviationCompare(
649 m_context.getTestContext().getLog(), "IntImageCompare", "Image comparison", refRenderer.getAccess(),
650 result->getAccess(), tcu::UVec4(2, 2, 2, 2), tcu::IVec3(1, 1, 0), true, tcu::COMPARE_LOG_RESULT);
651 }
652
653 if (compareOk)
654 return tcu::TestStatus::pass("Result image matches reference");
655 else
656 return tcu::TestStatus::fail("Image mismatch");
657 }
658
659 class PushDescriptorBufferGraphicsTest : public vkt::TestCase
660 {
661 public:
662 PushDescriptorBufferGraphicsTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
663 ~PushDescriptorBufferGraphicsTest(void);
664 void checkSupport(Context &context) const;
665 void initPrograms(SourceCollections &sourceCollections) const;
666 TestInstance *createInstance(Context &context) const;
667
668 protected:
669 const TestParams m_params;
670 };
671
PushDescriptorBufferGraphicsTest(tcu::TestContext & testContext,const string & name,const TestParams & params)672 PushDescriptorBufferGraphicsTest::PushDescriptorBufferGraphicsTest(tcu::TestContext &testContext, const string &name,
673 const TestParams ¶ms)
674 : vkt::TestCase(testContext, name)
675 , m_params(params)
676 {
677 }
678
~PushDescriptorBufferGraphicsTest(void)679 PushDescriptorBufferGraphicsTest::~PushDescriptorBufferGraphicsTest(void)
680 {
681 }
682
createInstance(Context & context) const683 TestInstance *PushDescriptorBufferGraphicsTest::createInstance(Context &context) const
684 {
685 return new PushDescriptorBufferGraphicsTestInstance(context, m_params);
686 }
687
checkSupport(Context & context) const688 void PushDescriptorBufferGraphicsTest::checkSupport(Context &context) const
689 {
690 if (m_params.useMaintenance5)
691 context.requireDeviceFunctionality("VK_KHR_maintenance5");
692
693 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
694 m_params.pipelineConstructionType);
695 }
696
initPrograms(SourceCollections & sourceCollections) const697 void PushDescriptorBufferGraphicsTest::initPrograms(SourceCollections &sourceCollections) const
698 {
699 const string bufferType =
700 m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "readonly buffer";
701 const string vertexSrc = "#version 450\n"
702 "layout(location = 0) in highp vec4 position;\n"
703 "layout(location = 1) in highp vec4 color;\n"
704 "layout(location = 0) out highp vec4 vtxColor;\n"
705 "layout(set = 0, binding = " +
706 de::toString(m_params.binding) + ") " + bufferType +
707 " Block\n"
708 "{\n"
709 " vec4 color;\n"
710 "} inputData;\n"
711 "\n"
712 "out gl_PerVertex { vec4 gl_Position; };\n"
713 "\n"
714 "void main()\n"
715 "{\n"
716 " gl_Position = position;\n"
717 " vtxColor = inputData.color;\n"
718 "}\n";
719
720 const string fragmentSrc = "#version 450\n"
721 "layout(location = 0) in highp vec4 vtxColor;\n"
722 "layout(location = 0) out highp vec4 fragColor;\n"
723 "\n"
724 "void main (void)\n"
725 "{\n"
726 " fragColor = vtxColor;\n"
727 "}\n";
728
729 sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
730 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
731 }
732
733 class PushDescriptorBufferComputeTestInstance : public vkt::TestInstance
734 {
735 public:
736 PushDescriptorBufferComputeTestInstance(Context &context, const TestParams ¶ms);
737 virtual ~PushDescriptorBufferComputeTestInstance(void);
738 void init(void);
739 virtual tcu::TestStatus iterate(void);
740 tcu::TestStatus verifyOutput(void);
741
742 private:
743 const TestParams m_params;
744 const PlatformInterface &m_vkp;
745 const Extensions m_instanceExtensions;
746 const CustomInstance m_instance;
747 const InstanceDriver &m_vki;
748 const VkPhysicalDevice m_physicalDevice;
749 const uint32_t m_queueFamilyIndex;
750 const Extensions m_deviceExtensions;
751 std::vector<std::string> m_deviceEnabledExtensions;
752 const Unique<VkDevice> m_device;
753 const DeviceDriver m_vkd;
754 const VkQueue m_queue;
755 const VkDeviceSize m_itemSize;
756 SimpleAllocator m_allocator;
757 Move<VkShaderModule> m_computeShaderModule;
758 vector<VkBufferSp> m_buffers;
759 vector<AllocationSp> m_bufferAllocs;
760 Move<VkBuffer> m_outputBuffer;
761 de::MovePtr<Allocation> m_outputBufferAlloc;
762 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
763 Move<VkPipelineLayout> m_pipelineLayout;
764 Move<VkPipeline> m_computePipeline;
765 Move<VkCommandPool> m_cmdPool;
766 Move<VkCommandBuffer> m_cmdBuffer;
767 std::vector<tcu::Vec4> m_testColors;
768 };
769
PushDescriptorBufferComputeTestInstance(Context & context,const TestParams & params)770 PushDescriptorBufferComputeTestInstance::PushDescriptorBufferComputeTestInstance(Context &context,
771 const TestParams ¶ms)
772 : vkt::TestInstance(context)
773 , m_params(params)
774 , m_vkp(context.getPlatformInterface())
775 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
776 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
777 , m_vki(m_instance.getDriver())
778 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
779 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
780 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
781 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
782 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
783 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
784 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
785 , m_itemSize(calcItemSize(m_vki, m_physicalDevice))
786 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
787 {
788 }
789
init(void)790 void PushDescriptorBufferComputeTestInstance::init(void)
791 {
792 // Create pipeline layout
793 {
794 // Create descriptor set layout
795 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[] = {
796 {
797 m_params.binding, // uint32_t binding;
798 m_params.descriptorType, // VkDescriptorType descriptorType;
799 1u, // uint32_t descriptorCount;
800 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
801 nullptr // const VkSampler* pImmutableSamplers;
802 },
803 {
804 m_params.binding + 1, // uint32_t binding;
805 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
806 1u, // uint32_t descriptorCount;
807 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
808 nullptr // const VkSampler* pImmutableSamplers;
809 }};
810
811 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
812 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
813 nullptr, // const void* pNext;
814 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
815 2u, // uint32_t bindingCount;
816 descriptorSetLayoutBindings // const VkDescriptorSetLayoutBinding* pBindings;
817 };
818
819 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
820
821 // Create pipeline layout
822 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
823 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
824 nullptr, // const void* pNext;
825 0u, // VkPipelineLayoutCreateFlags flags;
826 1u, // uint32_t descriptorSetCount;
827 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
828 0u, // uint32_t pushConstantRangeCount;
829 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
830 };
831
832 m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
833 }
834
835 // Fill the test colors table
836 m_testColors.resize(m_params.numCalls);
837 for (uint32_t colorIdx = 0; colorIdx < m_params.numCalls; colorIdx++)
838 {
839 if (colorIdx < DE_LENGTH_OF_ARRAY(defaultTestColors))
840 m_testColors[colorIdx] = defaultTestColors[colorIdx];
841 else
842 {
843 const float mix = static_cast<float>(colorIdx) / static_cast<float>(m_params.numCalls - 1);
844
845 // interpolate between first and last color, require these colors to be different
846 DE_ASSERT(defaultTestColors[0] != defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1]);
847 m_testColors[colorIdx] = defaultTestColors[0] * mix +
848 defaultTestColors[DE_LENGTH_OF_ARRAY(defaultTestColors) - 1] * (1.0f - mix);
849 }
850 }
851
852 // Create buffers. One color value in each buffer.
853 {
854 for (uint32_t bufIdx = 0; bufIdx < m_params.numCalls; bufIdx++)
855 {
856 const VkBufferUsageFlags usageFlags = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ?
857 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT :
858 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
859
860 const VkBufferCreateInfo bufferCreateInfo = {
861 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
862 nullptr, // const void* pNext;
863 0u, // VkBufferCreateFlags flags
864 kSizeofVec4, // VkDeviceSize size;
865 usageFlags, // VkBufferUsageFlags usage;
866 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
867 1u, // uint32_t queueFamilyCount;
868 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
869 };
870
871 m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
872 m_bufferAllocs.push_back(
873 AllocationSp(m_allocator
874 .allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]),
875 MemoryRequirement::HostVisible)
876 .release()));
877 VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(),
878 m_bufferAllocs[bufIdx]->getOffset()));
879
880 deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &m_testColors[bufIdx], static_cast<size_t>(kSizeofVec4));
881 flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
882 }
883 }
884
885 // Create output buffer
886 {
887 const VkBufferCreateInfo bufferCreateInfo = {
888 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
889 nullptr, // const void* pNext;
890 0u, // VkBufferCreateFlags flags
891 m_itemSize * m_params.numCalls, // VkDeviceSize size;
892 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
893 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
894 1u, // uint32_t queueFamilyCount;
895 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
896 };
897
898 m_outputBuffer = createBuffer(m_vkd, *m_device, &bufferCreateInfo);
899 m_outputBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer),
900 MemoryRequirement::HostVisible);
901 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(),
902 m_outputBufferAlloc->getOffset()));
903 }
904
905 // Create shader
906 {
907 m_computeShaderModule =
908 createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
909 }
910
911 // Create pipeline
912 {
913 const VkPipelineShaderStageCreateInfo stageCreateInfo = {
914 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
915 nullptr, // const void* pNext;
916 0u, // VkPipelineShaderStageCreateFlags flags;
917 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
918 *m_computeShaderModule, // VkShaderModule module;
919 "main", // const char* pName;
920 nullptr // const VkSpecializationInfo* pSpecializationInfo;
921 };
922
923 const VkComputePipelineCreateInfo createInfo = {
924 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
925 nullptr, // const void* pNext;
926 0u, // VkPipelineCreateFlags flags;
927 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
928 *m_pipelineLayout, // VkPipelineLayout layout;
929 VK_NULL_HANDLE, // VkPipeline basePipelineHandle;
930 0u, // int32_t basePipelineIndex;
931 };
932
933 m_computePipeline = createComputePipeline(m_vkd, *m_device, VK_NULL_HANDLE, &createInfo);
934 }
935
936 // Create command pool
937 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
938
939 // Create command buffer
940 {
941 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
942 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
943 m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
944
945 // Dispatch: Each dispatch switches the input buffer.
946 // Output buffer is exposed as a vec4 sized window.
947 for (uint32_t dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
948 {
949 VkDescriptorBufferInfo descriptorBufferInfoUbo = {
950 **m_buffers[dispatchNdx], // VkBuffer buffer;
951 0u, // VkDeviceSize offset;
952 kSizeofVec4, // VkDeviceSize range;
953 };
954
955 VkDescriptorBufferInfo descriptorBufferInfoOutput = {
956 *m_outputBuffer, // VkBuffer buffer;
957 m_itemSize * dispatchNdx, // VkDeviceSize offset;
958 kSizeofVec4, // VkDeviceSize range;
959 };
960
961 VkWriteDescriptorSet writeDescriptorSets[] = {
962 {
963 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
964 nullptr, // const void* pNext;
965 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
966 m_params.binding, // uint32_t dstBinding;
967 0u, // uint32_t dstArrayElement;
968 1u, // uint32_t descriptorCount;
969 m_params.descriptorType, // VkDescriptorType descriptorType;
970 nullptr, // const VkDescriptorImageInfo* pImageInfo;
971 &descriptorBufferInfoUbo, // const VkDescriptorBufferInfo* pBufferInfo;
972 nullptr // const VkBufferView* pTexelBufferView;
973 },
974 {
975 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
976 nullptr, // const void* pNext;
977 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
978 m_params.binding + 1, // uint32_t dstBinding;
979 0u, // uint32_t dstArrayElement;
980 1u, // uint32_t descriptorCount;
981 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
982 nullptr, // const VkDescriptorImageInfo* pImageInfo;
983 &descriptorBufferInfoOutput, // const VkDescriptorBufferInfo* pBufferInfo;
984 nullptr // const VkBufferView* pTexelBufferView;
985 }};
986
987 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 2,
988 writeDescriptorSets);
989 m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
990
991 const VkMemoryBarrier barrier = {
992 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
993 nullptr, // pNext
994 VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
995 VK_ACCESS_HOST_READ_BIT, // dstAccessMask
996 };
997 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
998 (VkDependencyFlags)0, 1, &barrier, 0, nullptr, 0, nullptr);
999 }
1000
1001 endCommandBuffer(m_vkd, *m_cmdBuffer);
1002 }
1003 }
1004
~PushDescriptorBufferComputeTestInstance(void)1005 PushDescriptorBufferComputeTestInstance::~PushDescriptorBufferComputeTestInstance(void)
1006 {
1007 }
1008
iterate(void)1009 tcu::TestStatus PushDescriptorBufferComputeTestInstance::iterate(void)
1010 {
1011 init();
1012
1013 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
1014
1015 return verifyOutput();
1016 }
1017
verifyOutput(void)1018 tcu::TestStatus PushDescriptorBufferComputeTestInstance::verifyOutput(void)
1019 {
1020 invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
1021
1022 // Verify result
1023 auto bufferPtr = reinterpret_cast<const char *>(m_outputBufferAlloc->getHostPtr());
1024 for (uint32_t i = 0; i < m_params.numCalls; ++i)
1025 {
1026 if (deMemCmp(&m_testColors[i], bufferPtr + (i * m_itemSize), static_cast<size_t>(kSizeofVec4)) != 0)
1027 TCU_FAIL("Output mismatch at output item " + de::toString(i));
1028 }
1029
1030 return tcu::TestStatus::pass("Output matches expected values");
1031 }
1032
1033 class PushDescriptorBufferComputeTest : public vkt::TestCase
1034 {
1035 public:
1036 PushDescriptorBufferComputeTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
1037 ~PushDescriptorBufferComputeTest(void);
1038 void initPrograms(SourceCollections &sourceCollections) const;
1039 TestInstance *createInstance(Context &context) const;
1040
1041 protected:
1042 const TestParams m_params;
1043 };
1044
PushDescriptorBufferComputeTest(tcu::TestContext & testContext,const string & name,const TestParams & params)1045 PushDescriptorBufferComputeTest::PushDescriptorBufferComputeTest(tcu::TestContext &testContext, const string &name,
1046 const TestParams ¶ms)
1047 : vkt::TestCase(testContext, name)
1048 , m_params(params)
1049 {
1050 }
1051
~PushDescriptorBufferComputeTest(void)1052 PushDescriptorBufferComputeTest::~PushDescriptorBufferComputeTest(void)
1053 {
1054 }
1055
createInstance(Context & context) const1056 TestInstance *PushDescriptorBufferComputeTest::createInstance(Context &context) const
1057 {
1058 return new PushDescriptorBufferComputeTestInstance(context, m_params);
1059 }
1060
initPrograms(SourceCollections & sourceCollections) const1061 void PushDescriptorBufferComputeTest::initPrograms(SourceCollections &sourceCollections) const
1062 {
1063 const string bufferType = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ? "uniform" : "buffer";
1064 const string computeSrc = "#version 450\n"
1065 "layout(set = 0, binding = " +
1066 de::toString(m_params.binding) + ") " + bufferType +
1067 " Block\n"
1068 "{\n"
1069 " vec4 color;\n"
1070 "} inputData;\n"
1071 "\n"
1072 "layout(set = 0, binding = " +
1073 de::toString(m_params.binding + 1) +
1074 ") writeonly buffer Output\n"
1075 "{\n"
1076 " vec4 color;\n"
1077 "} outData;\n"
1078 "\n"
1079 "void main()\n"
1080 "{\n"
1081 " outData.color = inputData.color;\n"
1082 "}\n";
1083
1084 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
1085 }
1086
1087 class PushDescriptorImageGraphicsTestInstance : public vkt::TestInstance
1088 {
1089 public:
1090 PushDescriptorImageGraphicsTestInstance(Context &context, const TestParams ¶ms);
1091 virtual ~PushDescriptorImageGraphicsTestInstance(void);
1092 void init(void);
1093 virtual tcu::TestStatus iterate(void);
1094 tcu::TestStatus verifyImage(void);
1095
1096 private:
1097 const TestParams m_params;
1098 const PlatformInterface &m_vkp;
1099 const Extensions m_instanceExtensions;
1100 const CustomInstance m_instance;
1101 const InstanceDriver &m_vki;
1102 const VkPhysicalDevice m_physicalDevice;
1103 const uint32_t m_queueFamilyIndex;
1104 const Extensions m_deviceExtensions;
1105 std::vector<std::string> m_deviceEnabledExtensions;
1106 const Unique<VkDevice> m_device;
1107 const DeviceDriver m_vkd;
1108 const VkQueue m_queue;
1109 SimpleAllocator m_allocator;
1110 const tcu::UVec2 m_renderSize;
1111 const tcu::UVec2 m_textureSize;
1112 const VkFormat m_colorFormat;
1113 Move<VkImage> m_colorImage;
1114 de::MovePtr<Allocation> m_colorImageAlloc;
1115 Move<VkImageView> m_colorAttachmentView;
1116 vector<VkImageSp> m_textureImages;
1117 vector<AllocationSp> m_textureImageAllocs;
1118 vector<VkImageViewSp> m_textureViews;
1119 Move<VkSampler> m_whiteBorderSampler;
1120 Move<VkSampler> m_blackBorderSampler;
1121 RenderPassWrapper m_renderPass;
1122 Move<VkFramebuffer> m_framebuffer;
1123 ShaderWrapper m_vertexShaderModule;
1124 ShaderWrapper m_fragmentShaderModule;
1125 Move<VkBuffer> m_vertexBuffer;
1126 de::MovePtr<Allocation> m_vertexBufferAlloc;
1127 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1128 PipelineLayoutWrapper m_preRasterizationStatePipelineLayout;
1129 PipelineLayoutWrapper m_fragmentStatePipelineLayout;
1130 GraphicsPipelineWrapper m_graphicsPipeline;
1131 Move<VkCommandPool> m_cmdPool;
1132 Move<VkCommandBuffer> m_cmdBuffer;
1133 vector<Vertex4Tex4> m_vertices;
1134 };
1135
PushDescriptorImageGraphicsTestInstance(Context & context,const TestParams & params)1136 PushDescriptorImageGraphicsTestInstance::PushDescriptorImageGraphicsTestInstance(Context &context,
1137 const TestParams ¶ms)
1138 : vkt::TestInstance(context)
1139 , m_params(params)
1140 , m_vkp(context.getPlatformInterface())
1141 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
1142 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
1143 , m_vki(m_instance.getDriver())
1144 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
1145 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
1146 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
1147 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
1148 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
1149 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
1150 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
1151 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
1152 , m_renderSize(32, 32)
1153 , m_textureSize(32, 32)
1154 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
1155 , m_graphicsPipeline(m_vki, m_vkd, m_physicalDevice, *m_device, m_deviceEnabledExtensions,
1156 params.pipelineConstructionType)
1157 , m_vertices(createTexQuads(params.numCalls, 0.25f))
1158 {
1159 }
1160
init(void)1161 void PushDescriptorImageGraphicsTestInstance::init(void)
1162 {
1163 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
1164 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
1165
1166 // Create color image
1167 {
1168
1169 const VkImageCreateInfo colorImageParams = {
1170 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1171 nullptr, // const void* pNext;
1172 0u, // VkImageCreateFlags flags;
1173 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1174 m_colorFormat, // VkFormat format;
1175 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
1176 1u, // uint32_t mipLevels;
1177 1u, // uint32_t arrayLayers;
1178 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1179 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1180 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1181 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1182 1u, // uint32_t queueFamilyIndexCount;
1183 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
1184 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1185 };
1186
1187 m_colorImage = createImage(m_vkd, *m_device, &colorImageParams);
1188
1189 // Allocate and bind color image memory
1190 m_colorImageAlloc =
1191 m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
1192 VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(),
1193 m_colorImageAlloc->getOffset()));
1194 }
1195
1196 // Create color attachment view
1197 {
1198 const VkImageViewCreateInfo colorAttachmentViewParams = {
1199 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1200 nullptr, // const void* pNext;
1201 0u, // VkImageViewCreateFlags flags;
1202 *m_colorImage, // VkImage image;
1203 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1204 m_colorFormat, // VkFormat format;
1205 componentMappingRGBA, // VkChannelMapping channels;
1206 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
1207 };
1208
1209 m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
1210 }
1211
1212 // Create texture images
1213 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
1214 {
1215 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1216 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
1217 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
1218 m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1219 usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
1220 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1221 usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
1222
1223 const VkImageCreateInfo textureImageParams = {
1224 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1225 nullptr, // const void* pNext;
1226 0u, // VkImageCreateFlags flags;
1227 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1228 m_colorFormat, // VkFormat format;
1229 {m_textureSize.x(), m_textureSize.y(), 1u}, // VkExtent3D extent;
1230 1u, // uint32_t mipLevels;
1231 1u, // uint32_t arrayLayers;
1232 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1233 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1234 usageFlags, // VkImageUsageFlags usage;
1235 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1236 1u, // uint32_t queueFamilyIndexCount;
1237 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
1238 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1239 };
1240
1241 m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
1242
1243 // Allocate and bind texture image memory
1244 m_textureImageAllocs.push_back(
1245 AllocationSp(m_allocator
1246 .allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()),
1247 MemoryRequirement::Any)
1248 .release()));
1249 VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(),
1250 m_textureImageAllocs.back()->getOffset()));
1251 }
1252
1253 // Create texture image views
1254 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
1255 {
1256 const VkImageViewCreateInfo textureViewParams = {
1257 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1258 nullptr, // const void* pNext;
1259 0u, // VkImageViewCreateFlags flags;
1260 **m_textureImages[texIdx], // VkImage image;
1261 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1262 m_colorFormat, // VkFormat format;
1263 componentMappingRGBA, // VkChannelMapping channels;
1264 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
1265 };
1266
1267 m_textureViews.push_back(
1268 VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
1269 }
1270
1271 VkClearValue clearValues[2];
1272 clearValues[0].color.float32[0] = 0.0f;
1273 clearValues[0].color.float32[1] = 1.0f;
1274 clearValues[0].color.float32[2] = 0.0f;
1275 clearValues[0].color.float32[3] = 1.0f;
1276 clearValues[1].color.float32[0] = 1.0f;
1277 clearValues[1].color.float32[1] = 0.0f;
1278 clearValues[1].color.float32[2] = 0.0f;
1279 clearValues[1].color.float32[3] = 1.0f;
1280
1281 const VkImageLayout textureImageLayout = (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
1282 VK_IMAGE_LAYOUT_GENERAL :
1283 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1284
1285 // Clear textures
1286 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
1287 {
1288 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1289 Move<VkCommandPool> cmdPool;
1290 Move<VkCommandBuffer> cmdBuffer;
1291
1292 cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
1293 cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1294
1295 const VkImageMemoryBarrier preImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1296 nullptr, // const void* pNext;
1297 0u, // VkAccessFlags srcAccessMask;
1298 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1299 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1300 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1301 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1302 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1303 **m_textureImages[texIdx], // VkImage image;
1304 {
1305 // VkImageSubresourceRange subresourceRange;
1306 aspectMask, // VkImageAspect aspect;
1307 0u, // uint32_t baseMipLevel;
1308 1u, // uint32_t mipLevels;
1309 0u, // uint32_t baseArraySlice;
1310 1u // uint32_t arraySize;
1311 }};
1312
1313 const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1314 nullptr, // const void* pNext;
1315 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1316 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
1317 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1318 textureImageLayout, // VkImageLayout newLayout;
1319 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1320 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1321 **m_textureImages[texIdx], // VkImage image;
1322 {
1323 // VkImageSubresourceRange subresourceRange;
1324 aspectMask, // VkImageAspect aspect;
1325 0u, // uint32_t baseMipLevel;
1326 1u, // uint32_t mipLevels;
1327 0u, // uint32_t baseArraySlice;
1328 1u // uint32_t arraySize;
1329 }};
1330
1331 const VkImageSubresourceRange clearRange = {
1332 aspectMask, // VkImageAspectFlags aspectMask;
1333 0u, // uint32_t baseMipLevel;
1334 1u, // uint32_t levelCount;
1335 0u, // uint32_t baseArrayLayer;
1336 1u // uint32_t layerCount;
1337 };
1338
1339 beginCommandBuffer(m_vkd, *cmdBuffer);
1340 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1341 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &preImageBarrier);
1342 m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1343 &clearValues[texIdx].color, 1, &clearRange);
1344 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
1345 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &postImageBarrier);
1346 endCommandBuffer(m_vkd, *cmdBuffer);
1347
1348 submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
1349 }
1350
1351 // Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
1352 {
1353 VkSamplerCreateInfo samplerParams = {
1354 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1355 nullptr, // const void* pNext;
1356 0u, // VkSamplerCreateFlags flags;
1357 VK_FILTER_NEAREST, // VkFilter magFilter;
1358 VK_FILTER_NEAREST, // VkFilter minFilter;
1359 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
1360 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeU;
1361 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeV;
1362 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeW;
1363 0.0f, // float mipLodBias;
1364 VK_FALSE, // VkBool32 anisotropyEnable;
1365 0.0f, // float maxAnisotropy;
1366 VK_FALSE, // VkBool32 compareEnable;
1367 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
1368 0.0f, // float minLod;
1369 0.0f, // float maxLod;
1370 VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, // VkBorderColor borderColor;
1371 VK_FALSE // VkBool32 unnormalizedCoordinates;
1372 };
1373
1374 m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
1375 samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
1376 m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
1377 }
1378
1379 // Create render pass
1380 {
1381 const VkAttachmentDescription attachmentDescription = {
1382 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
1383 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
1384 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1385 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
1386 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
1387 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
1388 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
1389 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
1390 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
1391 };
1392
1393 const VkAttachmentReference resultAttachmentRef = {
1394 0u, // uint32_t attachment
1395 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
1396 };
1397
1398 const VkSubpassDescription subpassDescription = {
1399 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
1400 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
1401 0u, // uint32_t inputAttachmentCount
1402 nullptr, // const VkAttachmentReference* pInputAttachments
1403 1u, // uint32_t colorAttachmentCount
1404 &resultAttachmentRef, // const VkAttachmentReference* pColorAttachments
1405 nullptr, // const VkAttachmentReference* pResolveAttachments
1406 nullptr, // const VkAttachmentReference* pDepthStencilAttachment
1407 0u, // uint32_t preserveAttachmentCount
1408 nullptr // const uint32_t* pPreserveAttachments
1409 };
1410
1411 const VkRenderPassCreateInfo renderPassInfo = {
1412 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureTypei sType
1413 nullptr, // const void* pNext
1414 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
1415 1u, // uint32_t attachmentCount
1416 &attachmentDescription, // const VkAttachmentDescription* pAttachments
1417 1u, // uint32_t subpassCount
1418 &subpassDescription, // const VkSubpassDescription* pSubpasses
1419 0u, // uint32_t dependencyCount
1420 nullptr // const VkSubpassDependency* pDependencies
1421 };
1422
1423 m_renderPass = RenderPassWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &renderPassInfo);
1424 }
1425
1426 // Create framebuffer
1427 {
1428 const VkImageView attachmentBindInfos[] = {*m_colorAttachmentView};
1429
1430 const VkFramebufferCreateInfo framebufferParams = {
1431 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1432 nullptr, // const void* pNext;
1433 0u, // VkFramebufferCreateFlags flags;
1434 *m_renderPass, // VkRenderPass renderPass;
1435 1u, // uint32_t attachmentCount;
1436 attachmentBindInfos, // const VkImageView* pAttachments;
1437 (uint32_t)m_renderSize.x(), // uint32_t width;
1438 (uint32_t)m_renderSize.y(), // uint32_t height;
1439 1u // uint32_t layers;
1440 };
1441
1442 m_renderPass.createFramebuffer(m_vkd, *m_device, &framebufferParams, *m_colorImage);
1443 }
1444
1445 // Create pipeline layout
1446 {
1447 // Create descriptor set layout
1448 vector<VkDescriptorSetLayoutBinding> layoutBindings;
1449
1450 switch (m_params.descriptorType)
1451 {
1452 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1453 {
1454 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
1455 m_params.binding, // uint32_t binding;
1456 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType;
1457 1u, // uint32_t descriptorCount;
1458 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1459 nullptr // const VkSampler* pImmutableSamplers;
1460 };
1461 layoutBindings.push_back(descriptorSetLayoutBinding);
1462 }
1463 break;
1464
1465 case VK_DESCRIPTOR_TYPE_SAMPLER:
1466 {
1467 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingSampler = {
1468 m_params.binding, // uint32_t binding;
1469 VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType descriptorType;
1470 1u, // uint32_t descriptorCount;
1471 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1472 nullptr // const VkSampler* pImmutableSamplers;
1473 };
1474 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingTex = {
1475 m_params.binding + 1, // uint32_t binding;
1476 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType descriptorType;
1477 1u, // uint32_t descriptorCount;
1478 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1479 nullptr // const VkSampler* pImmutableSamplers;
1480 };
1481 layoutBindings.push_back(descriptorSetLayoutBindingSampler);
1482 layoutBindings.push_back(descriptorSetLayoutBindingTex);
1483 }
1484 break;
1485
1486 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1487 {
1488 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingSampler = {
1489 m_params.binding + 1, // uint32_t binding;
1490 VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType descriptorType;
1491 1u, // uint32_t descriptorCount;
1492 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1493 nullptr // const VkSampler* pImmutableSamplers;
1494 };
1495 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingTex = {
1496 m_params.binding, // uint32_t binding;
1497 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType descriptorType;
1498 1u, // uint32_t descriptorCount;
1499 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1500 nullptr // const VkSampler* pImmutableSamplers;
1501 };
1502 layoutBindings.push_back(descriptorSetLayoutBindingSampler);
1503 layoutBindings.push_back(descriptorSetLayoutBindingTex);
1504 }
1505 break;
1506
1507 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1508 {
1509 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
1510 m_params.binding, // uint32_t binding;
1511 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType descriptorType;
1512 1u, // uint32_t descriptorCount;
1513 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
1514 nullptr // const VkSampler* pImmutableSamplers;
1515 };
1516 layoutBindings.push_back(descriptorSetLayoutBinding);
1517 }
1518 break;
1519
1520 default:
1521 DE_FATAL("unexpected descriptor type");
1522 break;
1523 }
1524
1525 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
1526 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
1527 nullptr, // const void* pNext;
1528 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
1529 (uint32_t)layoutBindings.size(), // uint32_t bindingCount;
1530 layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings;
1531 };
1532
1533 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
1534
1535 // Create pipeline layout
1536 VkPipelineLayoutCreateFlags pipelineLayoutFlags =
1537 (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ?
1538 0u :
1539 uint32_t(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
1540 VkPipelineLayoutCreateInfo pipelineLayoutParams{
1541 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1542 nullptr, // const void* pNext;
1543 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags;
1544 0u, // uint32_t setLayoutCount;
1545 nullptr, // const VkDescriptorSetLayout* pSetLayouts;
1546 0u, // uint32_t pushConstantRangeCount;
1547 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
1548 };
1549
1550 m_preRasterizationStatePipelineLayout =
1551 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
1552 pipelineLayoutParams.setLayoutCount = 1u;
1553 pipelineLayoutParams.pSetLayouts = &(*m_descriptorSetLayout);
1554 m_fragmentStatePipelineLayout =
1555 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
1556 }
1557
1558 // Create shaders
1559 {
1560 m_vertexShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
1561 m_fragmentShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
1562 }
1563
1564 // Create pipeline
1565 {
1566 const VkVertexInputBindingDescription vertexInputBindingDescription = {
1567 0u, // uint32_t binding;
1568 sizeof(Vertex4Tex4), // uint32_t strideInBytes;
1569 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1570 };
1571
1572 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
1573 {
1574 0u, // uint32_t location;
1575 0u, // uint32_t binding;
1576 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1577 0u // uint32_t offsetInBytes;
1578 },
1579 {
1580 1u, // uint32_t location;
1581 0u, // uint32_t binding;
1582 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1583 offsetof(Vertex4Tex4, texCoord), // uint32_t offset;
1584 }};
1585
1586 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1587 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1588 nullptr, // const void* pNext;
1589 0u, // vkPipelineVertexInputStateCreateFlags flags;
1590 1u, // uint32_t bindingCount;
1591 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1592 2u, // uint32_t attributeCount;
1593 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1594 };
1595
1596 const vector<VkViewport> viewports{makeViewport(m_renderSize)};
1597 const vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
1598
1599 m_graphicsPipeline.setMonolithicPipelineLayout(m_fragmentStatePipelineLayout)
1600 .setDefaultRasterizationState()
1601 .setDefaultDepthStencilState()
1602 .setDefaultMultisampleState()
1603 .setDefaultColorBlendState()
1604 .setupVertexInputState(&vertexInputStateParams)
1605 .setupPreRasterizationShaderState(viewports, scissors, m_preRasterizationStatePipelineLayout, *m_renderPass,
1606 0u, m_vertexShaderModule)
1607 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule)
1608 .setupFragmentOutputState(*m_renderPass)
1609 .buildPipeline();
1610 }
1611
1612 // Create vertex buffer
1613 {
1614 const VkBufferCreateInfo vertexBufferParams = {
1615 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1616 nullptr, // const void* pNext;
1617 0u, // VkBufferCreateFlags flags;
1618 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size;
1619 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1620 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1621 1u, // uint32_t queueFamilyCount;
1622 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
1623 };
1624
1625 m_vertexBuffer = createBuffer(m_vkd, *m_device, &vertexBufferParams);
1626 m_vertexBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer),
1627 MemoryRequirement::HostVisible);
1628
1629 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
1630 m_vertexBufferAlloc->getOffset()));
1631
1632 // Load vertices into vertex buffer
1633 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
1634 flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
1635 }
1636
1637 // Create command pool
1638 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
1639
1640 // Create command buffer
1641 {
1642 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
1643 const VkDeviceSize vertexBufferOffset = 0;
1644
1645 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1646 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
1647 m_renderPass.begin(m_vkd, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
1648 attachmentClearValue);
1649 m_graphicsPipeline.bind(*m_cmdBuffer);
1650 m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1651
1652 // Draw quads. Switch sampler or image view depending on the test.
1653 vector<VkSampler> samplers;
1654 vector<VkImageView> imageViews;
1655
1656 samplers.push_back(*m_whiteBorderSampler);
1657 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
1658 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1659 {
1660 // Vary sampler between draws
1661 samplers.push_back(*m_blackBorderSampler);
1662 }
1663 else
1664 {
1665 // Usa a single sampler
1666 samplers.push_back(*m_whiteBorderSampler);
1667 }
1668
1669 imageViews.push_back(**m_textureViews[0]);
1670 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
1671 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
1672 m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1673 {
1674 // Vary image view between draws
1675 imageViews.push_back(**m_textureViews[1]);
1676 }
1677 else
1678 {
1679 // Usa a single image view
1680 imageViews.push_back(**m_textureViews[0]);
1681 }
1682
1683 for (uint32_t quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
1684 {
1685 VkDescriptorImageInfo descriptorImageInfo = {
1686 samplers[quadNdx], // VkSampler sampler;
1687 imageViews[quadNdx], // VkImageView imageView;
1688 textureImageLayout // VkImageLayout imageLayout;
1689 };
1690
1691 VkWriteDescriptorSet writeDescriptorSet = {
1692 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
1693 nullptr, // const void* pNext;
1694 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
1695 m_params.binding, // uint32_t dstBinding;
1696 0u, // uint32_t dstArrayElement;
1697 1u, // uint32_t descriptorCount;
1698 m_params.descriptorType, // VkDescriptorType descriptorType;
1699 &descriptorImageInfo, // const VkDescriptorImageInfo* pImageInfo;
1700 nullptr, // const VkDescriptorBufferInfo* pBufferInfo;
1701 nullptr // const VkBufferView* pTexelBufferView;
1702 };
1703
1704 vector<VkWriteDescriptorSet> writeDescriptorSets;
1705 writeDescriptorSets.push_back(writeDescriptorSet);
1706
1707 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1708 {
1709 // Sampler also needs an image.
1710 writeDescriptorSet.dstBinding++;
1711 writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
1712 writeDescriptorSets.push_back(writeDescriptorSet);
1713 }
1714 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1715 {
1716 // Image also needs a sampler.
1717 writeDescriptorSet.dstBinding++;
1718 writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1719 writeDescriptorSets.push_back(writeDescriptorSet);
1720 }
1721
1722 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0,
1723 (uint32_t)writeDescriptorSets.size(), writeDescriptorSets.data());
1724 m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
1725 }
1726
1727 m_renderPass.end(m_vkd, *m_cmdBuffer);
1728 endCommandBuffer(m_vkd, *m_cmdBuffer);
1729 }
1730 }
1731
~PushDescriptorImageGraphicsTestInstance(void)1732 PushDescriptorImageGraphicsTestInstance::~PushDescriptorImageGraphicsTestInstance(void)
1733 {
1734 }
1735
iterate(void)1736 tcu::TestStatus PushDescriptorImageGraphicsTestInstance::iterate(void)
1737 {
1738 init();
1739
1740 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
1741
1742 return verifyImage();
1743 }
1744
verifyImage(void)1745 tcu::TestStatus PushDescriptorImageGraphicsTestInstance::verifyImage(void)
1746 {
1747 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1748 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
1749 const ColorVertexShader vertexShader;
1750 const ColorFragmentShader fragmentShader(tcuColorFormat, tcuDepthFormat);
1751 const rr::Program program(&vertexShader, &fragmentShader);
1752 ReferenceRenderer refRenderer(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1753 bool compareOk = false;
1754
1755 // Render reference image
1756 {
1757 vector<Vertex4RGBA> refQuadsOuter = createQuads(m_params.numCalls, 0.25f);
1758 vector<Vertex4RGBA> refQuadsInner = createQuads(m_params.numCalls, 0.25f * 0.8f);
1759 tcu::Vec4 outerColor[2];
1760 tcu::Vec4 innerColor[2];
1761 const bool hasBorder = m_params.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1762
1763 if (hasBorder)
1764 {
1765 outerColor[0] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1766 innerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1767 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1768 outerColor[1] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1769 else
1770 outerColor[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1771 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1772 innerColor[1] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1773 else
1774 innerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1775 }
1776 else
1777 {
1778 outerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1779 outerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
1780 }
1781
1782 for (uint32_t quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
1783 for (uint32_t vertexIdx = 0; vertexIdx < 6; vertexIdx++)
1784 {
1785 const uint32_t idx = quadIdx * 6 + vertexIdx;
1786 refQuadsOuter[idx].color.xyzw() = outerColor[quadIdx];
1787 refQuadsInner[idx].color.xyzw() = innerColor[quadIdx];
1788 }
1789
1790 if (hasBorder)
1791 refQuadsOuter.insert(refQuadsOuter.end(), refQuadsInner.begin(), refQuadsInner.end());
1792
1793 refRenderer.draw(rr::RenderState(refRenderer.getViewportState(),
1794 m_context.getDeviceProperties().limits.subPixelPrecisionBits),
1795 rr::PRIMITIVETYPE_TRIANGLES, refQuadsOuter);
1796 }
1797
1798 // Compare result with reference image
1799 {
1800 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(
1801 m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
1802
1803 compareOk = tcu::intThresholdPositionDeviationCompare(
1804 m_context.getTestContext().getLog(), "IntImageCompare", "Image comparison", refRenderer.getAccess(),
1805 result->getAccess(), tcu::UVec4(2, 2, 2, 2), tcu::IVec3(1, 1, 0), true, tcu::COMPARE_LOG_RESULT);
1806 }
1807
1808 if (compareOk)
1809 return tcu::TestStatus::pass("Result image matches reference");
1810 else
1811 return tcu::TestStatus::fail("Image mismatch");
1812 }
1813
1814 class PushDescriptorImageGraphicsTest : public vkt::TestCase
1815 {
1816 public:
1817 PushDescriptorImageGraphicsTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
1818 ~PushDescriptorImageGraphicsTest(void);
1819
1820 void checkSupport(Context &context) const;
1821 void initPrograms(SourceCollections &sourceCollections) const;
1822 TestInstance *createInstance(Context &context) const;
1823
1824 protected:
1825 const TestParams m_params;
1826 };
1827
PushDescriptorImageGraphicsTest(tcu::TestContext & testContext,const string & name,const TestParams & params)1828 PushDescriptorImageGraphicsTest::PushDescriptorImageGraphicsTest(tcu::TestContext &testContext, const string &name,
1829 const TestParams ¶ms)
1830 : vkt::TestCase(testContext, name)
1831 , m_params(params)
1832 {
1833 }
1834
~PushDescriptorImageGraphicsTest(void)1835 PushDescriptorImageGraphicsTest::~PushDescriptorImageGraphicsTest(void)
1836 {
1837 }
1838
createInstance(Context & context) const1839 TestInstance *PushDescriptorImageGraphicsTest::createInstance(Context &context) const
1840 {
1841 return new PushDescriptorImageGraphicsTestInstance(context, m_params);
1842 }
1843
checkSupport(Context & context) const1844 void PushDescriptorImageGraphicsTest::checkSupport(Context &context) const
1845 {
1846 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
1847 m_params.pipelineConstructionType);
1848 }
1849
initPrograms(SourceCollections & sourceCollections) const1850 void PushDescriptorImageGraphicsTest::initPrograms(SourceCollections &sourceCollections) const
1851 {
1852 const string vertexSrc = "#version 450\n"
1853 "layout(location = 0) in highp vec4 position;\n"
1854 "layout(location = 1) in highp vec4 texcoordVtx;\n"
1855 "layout(location = 0) out highp vec2 texcoordFrag;\n"
1856 "\n"
1857 "out gl_PerVertex { vec4 gl_Position; };\n"
1858 "\n"
1859 "void main()\n"
1860 "{\n"
1861 " gl_Position = position;\n"
1862 " texcoordFrag = texcoordVtx.xy;\n"
1863 "}\n";
1864
1865 sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
1866
1867 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
1868 {
1869 const string fragmentSrc = "#version 450\n"
1870 "layout(location = 0) in highp vec2 texcoordFrag;\n"
1871 "layout(location = 0) out highp vec4 fragColor;\n"
1872 "layout(set = 0, binding = " +
1873 de::toString(m_params.binding) +
1874 ") uniform sampler2D combinedSampler;\n"
1875 "\n"
1876 "void main (void)\n"
1877 "{\n"
1878 " fragColor = texture(combinedSampler, texcoordFrag);\n"
1879 "}\n";
1880
1881 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1882 }
1883 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
1884 {
1885 const string fragmentSrc = "#version 450\n"
1886 "layout(location = 0) in highp vec2 texcoordFrag;\n"
1887 "layout(location = 0) out highp vec4 fragColor;\n"
1888 "layout(set = 0, binding = " +
1889 de::toString(m_params.binding) +
1890 ") uniform sampler texSampler;\n"
1891 "layout(set = 0, binding = " +
1892 de::toString(m_params.binding + 1) +
1893 ") uniform texture2D texImage;\n"
1894 "\n"
1895 "void main (void)\n"
1896 "{\n"
1897 " fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
1898 "}\n";
1899
1900 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1901 }
1902 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1903 {
1904 const string fragmentSrc = "#version 450\n"
1905 "layout(location = 0) in highp vec2 texcoordFrag;\n"
1906 "layout(location = 0) out highp vec4 fragColor;\n"
1907 "layout(set = 0, binding = " +
1908 de::toString(m_params.binding + 1) +
1909 ") uniform sampler texSampler;\n"
1910 "layout(set = 0, binding = " +
1911 de::toString(m_params.binding) +
1912 ") uniform texture2D texImage;\n"
1913 "\n"
1914 "void main (void)\n"
1915 "{\n"
1916 " fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
1917 "}\n";
1918
1919 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1920 }
1921 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1922 {
1923 const string fragmentSrc = "#version 450\n"
1924 "layout(location = 0) in highp vec2 texcoordFrag;\n"
1925 "layout(location = 0) out highp vec4 fragColor;\n"
1926 "layout(set = 0, binding = " +
1927 de::toString(m_params.binding) +
1928 ", rgba8) uniform readonly image2D storageImage;\n"
1929 "\n"
1930 "void main (void)\n"
1931 "{\n"
1932 " fragColor = imageLoad(storageImage, ivec2(0));\n"
1933 "}\n";
1934
1935 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
1936 }
1937 else
1938 {
1939 DE_FATAL("Unexpected descriptor type");
1940 }
1941 }
1942
1943 class PushDescriptorImageComputeTestInstance : public vkt::TestInstance
1944 {
1945 public:
1946 PushDescriptorImageComputeTestInstance(Context &context, const TestParams ¶ms);
1947 virtual ~PushDescriptorImageComputeTestInstance(void);
1948 void init(void);
1949 virtual tcu::TestStatus iterate(void);
1950 tcu::TestStatus verifyOutput(void);
1951
1952 private:
1953 const TestParams m_params;
1954 const PlatformInterface &m_vkp;
1955 const Extensions m_instanceExtensions;
1956 const CustomInstance m_instance;
1957 const InstanceDriver &m_vki;
1958 const VkPhysicalDevice m_physicalDevice;
1959 const uint32_t m_queueFamilyIndex;
1960 const Extensions m_deviceExtensions;
1961 std::vector<std::string> m_deviceEnabledExtensions;
1962 const Unique<VkDevice> m_device;
1963 const DeviceDriver m_vkd;
1964 const VkQueue m_queue;
1965 const VkDeviceSize m_itemSize;
1966 const VkDeviceSize m_blockSize;
1967 SimpleAllocator m_allocator;
1968 const tcu::UVec2 m_textureSize;
1969 const VkFormat m_colorFormat;
1970 Move<VkShaderModule> m_computeShaderModule;
1971 vector<VkImageSp> m_textureImages;
1972 vector<AllocationSp> m_textureImageAllocs;
1973 vector<VkImageViewSp> m_textureViews;
1974 Move<VkSampler> m_whiteBorderSampler;
1975 Move<VkSampler> m_blackBorderSampler;
1976 Move<VkBuffer> m_outputBuffer;
1977 de::MovePtr<Allocation> m_outputBufferAlloc;
1978 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1979 Move<VkPipelineLayout> m_pipelineLayout;
1980 Move<VkPipeline> m_computePipeline;
1981 Move<VkCommandPool> m_cmdPool;
1982 Move<VkCommandBuffer> m_cmdBuffer;
1983 uint32_t m_outputBufferBinding;
1984 };
1985
PushDescriptorImageComputeTestInstance(Context & context,const TestParams & params)1986 PushDescriptorImageComputeTestInstance::PushDescriptorImageComputeTestInstance(Context &context,
1987 const TestParams ¶ms)
1988 : vkt::TestInstance(context)
1989 , m_params(params)
1990 , m_vkp(context.getPlatformInterface())
1991 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
1992 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
1993 , m_vki(m_instance.getDriver())
1994 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
1995 , m_queueFamilyIndex(
1996 findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT))
1997 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
1998 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
1999 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
2000 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
2001 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
2002 , m_itemSize(calcItemSize(m_vki, m_physicalDevice, 2u))
2003 , m_blockSize(kSizeofVec4 * 2u)
2004 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
2005 , m_textureSize(32, 32)
2006 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
2007 , m_outputBufferBinding(0)
2008 {
2009 }
2010
init(void)2011 void PushDescriptorImageComputeTestInstance::init(void)
2012 {
2013 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
2014 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
2015
2016 // Create texture images
2017 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
2018 {
2019 VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2020 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
2021 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
2022 m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
2023 usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
2024 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2025 usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
2026
2027 const VkImageCreateInfo textureImageParams = {
2028 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2029 nullptr, // const void* pNext;
2030 0u, // VkImageCreateFlags flags;
2031 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2032 m_colorFormat, // VkFormat format;
2033 {m_textureSize.x(), m_textureSize.y(), 1u}, // VkExtent3D extent;
2034 1u, // uint32_t mipLevels;
2035 1u, // uint32_t arrayLayers;
2036 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2037 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2038 usageFlags, // VkImageUsageFlags usage;
2039 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2040 1u, // uint32_t queueFamilyIndexCount;
2041 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
2042 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2043 };
2044
2045 m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
2046
2047 // Allocate and bind texture image memory
2048 m_textureImageAllocs.push_back(
2049 AllocationSp(m_allocator
2050 .allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()),
2051 MemoryRequirement::Any)
2052 .release()));
2053 VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(),
2054 m_textureImageAllocs.back()->getOffset()));
2055 }
2056
2057 // Create texture image views
2058 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
2059 {
2060 const VkImageViewCreateInfo textureViewParams = {
2061 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2062 nullptr, // const void* pNext;
2063 0u, // VkImageViewCreateFlags flags;
2064 **m_textureImages[texIdx], // VkImage image;
2065 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2066 m_colorFormat, // VkFormat format;
2067 componentMappingRGBA, // VkChannelMapping channels;
2068 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
2069 };
2070
2071 m_textureViews.push_back(
2072 VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
2073 }
2074
2075 VkClearValue clearValues[2];
2076 clearValues[0].color.float32[0] = 0.0f;
2077 clearValues[0].color.float32[1] = 1.0f;
2078 clearValues[0].color.float32[2] = 0.0f;
2079 clearValues[0].color.float32[3] = 1.0f;
2080 clearValues[1].color.float32[0] = 1.0f;
2081 clearValues[1].color.float32[1] = 0.0f;
2082 clearValues[1].color.float32[2] = 0.0f;
2083 clearValues[1].color.float32[3] = 1.0f;
2084
2085 const VkImageLayout textureImageLayout = (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ?
2086 VK_IMAGE_LAYOUT_GENERAL :
2087 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2088
2089 // Clear textures
2090 for (uint32_t texIdx = 0; texIdx < 2; texIdx++)
2091 {
2092 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2093 Move<VkCommandPool> cmdPool;
2094 Move<VkCommandBuffer> cmdBuffer;
2095
2096 cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
2097 cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2098
2099 const VkImageMemoryBarrier preImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2100 nullptr, // const void* pNext;
2101 0u, // VkAccessFlags srcAccessMask;
2102 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2103 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2104 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2105 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2106 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2107 **m_textureImages[texIdx], // VkImage image;
2108 {
2109 // VkImageSubresourceRange subresourceRange;
2110 aspectMask, // VkImageAspect aspect;
2111 0u, // uint32_t baseMipLevel;
2112 1u, // uint32_t mipLevels;
2113 0u, // uint32_t baseArraySlice;
2114 1u // uint32_t arraySize;
2115 }};
2116
2117 const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2118 nullptr, // const void* pNext;
2119 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2120 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
2121 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2122 textureImageLayout, // VkImageLayout newLayout;
2123 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
2124 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
2125 **m_textureImages[texIdx], // VkImage image;
2126 {
2127 // VkImageSubresourceRange subresourceRange;
2128 aspectMask, // VkImageAspect aspect;
2129 0u, // uint32_t baseMipLevel;
2130 1u, // uint32_t mipLevels;
2131 0u, // uint32_t baseArraySlice;
2132 1u // uint32_t arraySize;
2133 }};
2134
2135 const VkImageSubresourceRange clearRange = {
2136 aspectMask, // VkImageAspectFlags aspectMask;
2137 0u, // uint32_t baseMipLevel;
2138 1u, // uint32_t levelCount;
2139 0u, // uint32_t baseArrayLayer;
2140 1u // uint32_t layerCount;
2141 };
2142
2143 beginCommandBuffer(m_vkd, *cmdBuffer);
2144 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2145 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &preImageBarrier);
2146 m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2147 &clearValues[texIdx].color, 1, &clearRange);
2148 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
2149 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &postImageBarrier);
2150 endCommandBuffer(m_vkd, *cmdBuffer);
2151
2152 submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
2153 }
2154
2155 // Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
2156 {
2157 VkSamplerCreateInfo samplerParams = {
2158 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
2159 nullptr, // const void* pNext;
2160 0u, // VkSamplerCreateFlags flags;
2161 VK_FILTER_NEAREST, // VkFilter magFilter;
2162 VK_FILTER_NEAREST, // VkFilter minFilter;
2163 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
2164 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeU;
2165 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeV;
2166 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeW;
2167 0.0f, // float mipLodBias;
2168 VK_FALSE, // VkBool32 anisotropyEnable;
2169 0.0f, // float maxAnisotropy;
2170 VK_FALSE, // VkBool32 compareEnable;
2171 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
2172 0.0f, // float minLod;
2173 0.0f, // float maxLod;
2174 VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, // VkBorderColor borderColor;
2175 VK_FALSE // VkBool32 unnormalizedCoordinates;
2176 };
2177
2178 m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
2179 samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
2180 m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
2181 }
2182
2183 // Create pipeline layout
2184 {
2185 // Create descriptor set layout
2186 vector<VkDescriptorSetLayoutBinding> layoutBindings;
2187
2188 switch (m_params.descriptorType)
2189 {
2190 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2191 {
2192 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
2193 m_params.binding, // uint32_t binding;
2194 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType descriptorType;
2195 1u, // uint32_t descriptorCount;
2196 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2197 nullptr // const VkSampler* pImmutableSamplers;
2198 };
2199 layoutBindings.push_back(descriptorSetLayoutBinding);
2200 m_outputBufferBinding = m_params.binding + 1;
2201 }
2202 break;
2203
2204 case VK_DESCRIPTOR_TYPE_SAMPLER:
2205 {
2206 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingSampler = {
2207 m_params.binding, // uint32_t binding;
2208 VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType descriptorType;
2209 1u, // uint32_t descriptorCount;
2210 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2211 nullptr // const VkSampler* pImmutableSamplers;
2212 };
2213 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingTex = {
2214 m_params.binding + 1, // uint32_t binding;
2215 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType descriptorType;
2216 1u, // uint32_t descriptorCount;
2217 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2218 nullptr // const VkSampler* pImmutableSamplers;
2219 };
2220 layoutBindings.push_back(descriptorSetLayoutBindingSampler);
2221 layoutBindings.push_back(descriptorSetLayoutBindingTex);
2222 m_outputBufferBinding = m_params.binding + 2;
2223 }
2224 break;
2225
2226 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2227 {
2228 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingSampler = {
2229 m_params.binding + 1, // uint32_t binding;
2230 VK_DESCRIPTOR_TYPE_SAMPLER, // VkDescriptorType descriptorType;
2231 1u, // uint32_t descriptorCount;
2232 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2233 nullptr // const VkSampler* pImmutableSamplers;
2234 };
2235 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingTex = {
2236 m_params.binding, // uint32_t binding;
2237 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType descriptorType;
2238 1u, // uint32_t descriptorCount;
2239 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2240 nullptr // const VkSampler* pImmutableSamplers;
2241 };
2242 layoutBindings.push_back(descriptorSetLayoutBindingSampler);
2243 layoutBindings.push_back(descriptorSetLayoutBindingTex);
2244 m_outputBufferBinding = m_params.binding + 2;
2245 }
2246 break;
2247
2248 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2249 {
2250 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
2251 m_params.binding, // uint32_t binding;
2252 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType descriptorType;
2253 1u, // uint32_t descriptorCount;
2254 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2255 nullptr // const VkSampler* pImmutableSamplers;
2256 };
2257 layoutBindings.push_back(descriptorSetLayoutBinding);
2258 m_outputBufferBinding = m_params.binding + 1;
2259 }
2260 break;
2261
2262 default:
2263 DE_FATAL("unexpected descriptor type");
2264 break;
2265 }
2266
2267 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindingOutputBuffer = {
2268 m_outputBufferBinding, // uint32_t binding;
2269 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
2270 1u, // uint32_t descriptorCount;
2271 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
2272 nullptr // const VkSampler* pImmutableSamplers;
2273 };
2274
2275 layoutBindings.push_back(descriptorSetLayoutBindingOutputBuffer);
2276
2277 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
2278 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
2279 nullptr, // const void* pNext;
2280 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
2281 (uint32_t)layoutBindings.size(), // uint32_t bindingCount;
2282 layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings;
2283 };
2284
2285 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
2286
2287 // Create pipeline layout
2288 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
2289 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2290 nullptr, // const void* pNext;
2291 0u, // VkPipelineLayoutCreateFlags flags;
2292 1u, // uint32_t descriptorSetCount;
2293 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
2294 0u, // uint32_t pushConstantRangeCount;
2295 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
2296 };
2297
2298 m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
2299 }
2300
2301 // Create output buffer
2302 {
2303 DE_ASSERT(m_params.numCalls <= 2u);
2304
2305 const VkBufferCreateInfo bufferCreateInfo = {
2306 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2307 nullptr, // const void* pNext;
2308 0u, // VkBufferCreateFlags flags
2309 m_itemSize * 2u, // VkDeviceSize size;
2310 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
2311 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2312 1u, // uint32_t queueFamilyCount;
2313 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
2314 };
2315
2316 m_outputBuffer = createBuffer(m_vkd, *m_device, &bufferCreateInfo);
2317 m_outputBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer),
2318 MemoryRequirement::HostVisible);
2319 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(),
2320 m_outputBufferAlloc->getOffset()));
2321 }
2322
2323 // Create shader
2324 {
2325 m_computeShaderModule =
2326 createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
2327 }
2328
2329 // Create pipeline
2330 {
2331 const VkPipelineShaderStageCreateInfo stageCreateInfo = {
2332 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
2333 nullptr, // const void* pNext;
2334 0u, // VkPipelineShaderStageCreateFlags flags;
2335 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
2336 *m_computeShaderModule, // VkShaderModule module;
2337 "main", // const char* pName;
2338 nullptr // const VkSpecializationInfo* pSpecializationInfo;
2339 };
2340
2341 const VkComputePipelineCreateInfo createInfo = {
2342 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
2343 nullptr, // const void* pNext;
2344 0u, // VkPipelineCreateFlags flags;
2345 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
2346 *m_pipelineLayout, // VkPipelineLayout layout;
2347 VK_NULL_HANDLE, // VkPipeline basePipelineHandle;
2348 0u, // int32_t basePipelineIndex;
2349 };
2350
2351 m_computePipeline = createComputePipeline(m_vkd, *m_device, VK_NULL_HANDLE, &createInfo);
2352 }
2353
2354 // Create command pool
2355 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
2356
2357 // Create command buffer
2358 {
2359 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2360 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
2361 m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
2362
2363 // Dispatch: Each dispatch switches the input image.
2364 // Output buffer is exposed as a 2 x vec4 sized window.
2365 for (uint32_t dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
2366 {
2367 vector<VkSampler> samplers;
2368 vector<VkImageView> imageViews;
2369
2370 samplers.push_back(*m_whiteBorderSampler);
2371 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||
2372 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2373 {
2374 // Vary sampler between draws
2375 samplers.push_back(*m_blackBorderSampler);
2376 }
2377 else
2378 {
2379 // Usa a single sampler
2380 samplers.push_back(*m_whiteBorderSampler);
2381 }
2382
2383 imageViews.push_back(**m_textureViews[0]);
2384 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
2385 m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
2386 m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2387 {
2388 // Vary image view between draws
2389 imageViews.push_back(**m_textureViews[1]);
2390 }
2391 else
2392 {
2393 // Usa a single image view
2394 imageViews.push_back(**m_textureViews[0]);
2395 }
2396
2397 const VkDescriptorImageInfo descriptorImageInfo = {
2398 samplers[dispatchNdx], // VkSampler sampler;
2399 imageViews[dispatchNdx], // VkImageView imageView;
2400 textureImageLayout // VkImageLayout imageLayout;
2401 };
2402
2403 VkWriteDescriptorSet writeDescriptorSet = {
2404 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
2405 nullptr, // const void* pNext;
2406 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
2407 m_params.binding, // uint32_t dstBinding;
2408 0u, // uint32_t dstArrayElement;
2409 1u, // uint32_t descriptorCount;
2410 m_params.descriptorType, // VkDescriptorType descriptorType;
2411 &descriptorImageInfo, // const VkDescriptorImageInfo* pImageInfo;
2412 nullptr, // const VkDescriptorBufferInfo* pBufferInfo;
2413 nullptr // const VkBufferView* pTexelBufferView;
2414 };
2415
2416 vector<VkWriteDescriptorSet> writeDescriptorSets;
2417 writeDescriptorSets.push_back(writeDescriptorSet);
2418
2419 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2420 {
2421 // Sampler also needs an image.
2422 writeDescriptorSet.dstBinding++;
2423 writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
2424 writeDescriptorSets.push_back(writeDescriptorSet);
2425 }
2426 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
2427 {
2428 // Image also needs a sampler.
2429 writeDescriptorSet.dstBinding++;
2430 writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
2431 writeDescriptorSets.push_back(writeDescriptorSet);
2432 }
2433
2434 const VkDescriptorBufferInfo descriptorBufferInfoOutput = {
2435 *m_outputBuffer, // VkBuffer buffer;
2436 m_itemSize * dispatchNdx, // VkDeviceSize offset;
2437 m_blockSize, // VkDeviceSize range;
2438 };
2439
2440 // Write output buffer descriptor set
2441 const VkWriteDescriptorSet writeDescriptorSetOutput = {
2442 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
2443 nullptr, // const void* pNext;
2444 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
2445 m_outputBufferBinding, // uint32_t dstBinding;
2446 0u, // uint32_t dstArrayElement;
2447 1u, // uint32_t descriptorCount;
2448 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
2449 nullptr, // const VkDescriptorImageInfo* pImageInfo;
2450 &descriptorBufferInfoOutput, // const VkDescriptorBufferInfo* pBufferInfo;
2451 nullptr // const VkBufferView* pTexelBufferView;
2452 };
2453
2454 writeDescriptorSets.push_back(writeDescriptorSetOutput);
2455
2456 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0,
2457 (uint32_t)writeDescriptorSets.size(), writeDescriptorSets.data());
2458 m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
2459
2460 const VkMemoryBarrier barrier = {
2461 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
2462 nullptr, // pNext
2463 VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
2464 VK_ACCESS_HOST_READ_BIT, // dstAccessMask
2465 };
2466 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2467 (VkDependencyFlags)0, 1, &barrier, 0, nullptr, 0, nullptr);
2468 }
2469
2470 endCommandBuffer(m_vkd, *m_cmdBuffer);
2471 }
2472 }
2473
~PushDescriptorImageComputeTestInstance(void)2474 PushDescriptorImageComputeTestInstance::~PushDescriptorImageComputeTestInstance(void)
2475 {
2476 }
2477
iterate(void)2478 tcu::TestStatus PushDescriptorImageComputeTestInstance::iterate(void)
2479 {
2480 init();
2481
2482 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
2483
2484 return verifyOutput();
2485 }
2486
verifyOutput(void)2487 tcu::TestStatus PushDescriptorImageComputeTestInstance::verifyOutput(void)
2488 {
2489 const auto floatsPerDispatch = 8u; // 8 floats (2 vec4s) per dispatch.
2490 std::vector<float> ref(floatsPerDispatch * 2u);
2491
2492 invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
2493
2494 switch (m_params.descriptorType)
2495 {
2496 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2497 // Dispatch 1: inner & outer = green
2498 ref[0] = ref[4] = 0.0f;
2499 ref[1] = ref[5] = 1.0f;
2500 ref[2] = ref[6] = 0.0f;
2501 ref[3] = ref[7] = 1.0f;
2502
2503 // Dispatch 2: inner & outer = red
2504 ref[8] = ref[12] = 1.0f;
2505 ref[9] = ref[13] = 0.0f;
2506 ref[10] = ref[14] = 0.0f;
2507 ref[11] = ref[15] = 1.0f;
2508 break;
2509
2510 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2511 // Dispatch 1: inner = green, outer = white
2512 ref[0] = 0.0f;
2513 ref[1] = 1.0f;
2514 ref[2] = 0.0f;
2515 ref[3] = 1.0f;
2516
2517 ref[4] = 1.0f;
2518 ref[5] = 1.0f;
2519 ref[6] = 1.0f;
2520 ref[7] = 1.0f;
2521
2522 // Dispatch 2: inner = red, outer = black
2523 ref[8] = 1.0f;
2524 ref[9] = 0.0f;
2525 ref[10] = 0.0f;
2526 ref[11] = 1.0f;
2527
2528 ref[12] = 0.0f;
2529 ref[13] = 0.0f;
2530 ref[14] = 0.0f;
2531 ref[15] = 1.0f;
2532 break;
2533
2534 case VK_DESCRIPTOR_TYPE_SAMPLER:
2535 // Dispatch 1: inner = green, outer = white
2536 ref[0] = 0.0f;
2537 ref[1] = 1.0f;
2538 ref[2] = 0.0f;
2539 ref[3] = 1.0f;
2540
2541 ref[4] = 1.0f;
2542 ref[5] = 1.0f;
2543 ref[6] = 1.0f;
2544 ref[7] = 1.0f;
2545
2546 // Dispatch 2: inner = green, outer = black
2547 ref[8] = 0.0f;
2548 ref[9] = 1.0f;
2549 ref[10] = 0.0f;
2550 ref[11] = 1.0f;
2551
2552 ref[12] = 0.0f;
2553 ref[13] = 0.0f;
2554 ref[14] = 0.0f;
2555 ref[15] = 1.0f;
2556 break;
2557
2558 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2559 // Dispatch 1: inner = green, outer = white
2560 ref[0] = 0.0f;
2561 ref[1] = 1.0f;
2562 ref[2] = 0.0f;
2563 ref[3] = 1.0f;
2564
2565 ref[4] = 1.0f;
2566 ref[5] = 1.0f;
2567 ref[6] = 1.0f;
2568 ref[7] = 1.0f;
2569
2570 // Dispatch 2: inner = red, outer = white
2571 ref[8] = 1.0f;
2572 ref[9] = 0.0f;
2573 ref[10] = 0.0f;
2574 ref[11] = 1.0f;
2575
2576 ref[12] = 1.0f;
2577 ref[13] = 1.0f;
2578 ref[14] = 1.0f;
2579 ref[15] = 1.0f;
2580 break;
2581
2582 default:
2583 DE_FATAL("unexpected descriptor type");
2584 break;
2585 }
2586
2587 // Verify result
2588 const auto bufferDataPtr = reinterpret_cast<const char *>(m_outputBufferAlloc->getHostPtr());
2589 const auto blockSize = static_cast<size_t>(m_blockSize);
2590
2591 for (uint32_t dispatchNdx = 0u; dispatchNdx < m_params.numCalls; ++dispatchNdx)
2592 {
2593 const auto refIdx = floatsPerDispatch * dispatchNdx;
2594 const auto bufferOffset =
2595 m_itemSize * dispatchNdx; // Each dispatch uses m_itemSize bytes in the buffer to meet alignment reqs.
2596
2597 if (deMemCmp(&ref[refIdx], bufferDataPtr + bufferOffset, blockSize) != 0)
2598 {
2599 std::vector<float> buffferValues(floatsPerDispatch);
2600 std::vector<float> refValues(floatsPerDispatch);
2601
2602 deMemcpy(refValues.data(), &ref[refIdx], blockSize);
2603 deMemcpy(buffferValues.data(), bufferDataPtr + bufferOffset, blockSize);
2604
2605 std::ostringstream msg;
2606 msg << "Output mismatch at dispatch " << dispatchNdx << ": Reference ";
2607 for (uint32_t i = 0; i < floatsPerDispatch; ++i)
2608 msg << ((i == 0) ? "[" : ", ") << refValues[i];
2609 msg << "]; Buffer ";
2610 for (uint32_t i = 0; i < floatsPerDispatch; ++i)
2611 msg << ((i == 0) ? "[" : ", ") << buffferValues[i];
2612 msg << "]";
2613
2614 m_context.getTestContext().getLog() << tcu::TestLog::Message << msg.str() << tcu::TestLog::EndMessage;
2615 return tcu::TestStatus::fail("Output mismatch");
2616 }
2617 }
2618
2619 return tcu::TestStatus::pass("Output matches expected values");
2620 }
2621
2622 class PushDescriptorImageComputeTest : public vkt::TestCase
2623 {
2624 public:
2625 PushDescriptorImageComputeTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
2626 ~PushDescriptorImageComputeTest(void);
2627 void initPrograms(SourceCollections &sourceCollections) const;
2628 TestInstance *createInstance(Context &context) const;
2629
2630 protected:
2631 const TestParams m_params;
2632 };
2633
PushDescriptorImageComputeTest(tcu::TestContext & testContext,const string & name,const TestParams & params)2634 PushDescriptorImageComputeTest::PushDescriptorImageComputeTest(tcu::TestContext &testContext, const string &name,
2635 const TestParams ¶ms)
2636 : vkt::TestCase(testContext, name)
2637 , m_params(params)
2638 {
2639 }
2640
~PushDescriptorImageComputeTest(void)2641 PushDescriptorImageComputeTest::~PushDescriptorImageComputeTest(void)
2642 {
2643 }
2644
createInstance(Context & context) const2645 TestInstance *PushDescriptorImageComputeTest::createInstance(Context &context) const
2646 {
2647 return new PushDescriptorImageComputeTestInstance(context, m_params);
2648 }
2649
initPrograms(SourceCollections & sourceCollections) const2650 void PushDescriptorImageComputeTest::initPrograms(SourceCollections &sourceCollections) const
2651 {
2652 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
2653 {
2654 const string computeSrc = "#version 450\n"
2655 "layout(set = 0, binding = " +
2656 de::toString(m_params.binding) +
2657 ") uniform sampler2D combinedSampler;\n"
2658 "layout(set = 0, binding = " +
2659 de::toString(m_params.binding + 1) +
2660 ") writeonly buffer Output\n"
2661 "{\n"
2662 " vec4 innerColor;\n"
2663 " vec4 outerColor;\n"
2664 "} outData;\n"
2665 "\n"
2666 "void main()\n"
2667 "{\n"
2668 " outData.innerColor = texture(combinedSampler, vec2(0.5));\n"
2669 " outData.outerColor = texture(combinedSampler, vec2(-0.1));\n"
2670 "}\n";
2671
2672 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2673 }
2674 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2675 {
2676 const string computeSrc = "#version 450\n"
2677 "layout(set = 0, binding = " +
2678 de::toString(m_params.binding) +
2679 ") uniform sampler texSampler;\n"
2680 "layout(set = 0, binding = " +
2681 de::toString(m_params.binding + 1) +
2682 ") uniform texture2D texImage;\n"
2683 "layout(set = 0, binding = " +
2684 de::toString(m_params.binding + 2) +
2685 ") writeonly buffer Output\n"
2686 "{\n"
2687 " vec4 innerColor;\n"
2688 " vec4 outerColor;\n"
2689 "} outData;\n"
2690 "\n"
2691 "void main()\n"
2692 "{\n"
2693 " outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
2694 " outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
2695 "}\n";
2696
2697 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2698 }
2699 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
2700 {
2701 const string computeSrc = "#version 450\n"
2702 "layout(set = 0, binding = " +
2703 de::toString(m_params.binding + 1) +
2704 ") uniform sampler texSampler;\n"
2705 "layout(set = 0, binding = " +
2706 de::toString(m_params.binding) +
2707 ") uniform texture2D texImage;\n"
2708 "layout(set = 0, binding = " +
2709 de::toString(m_params.binding + 2) +
2710 ") writeonly buffer Output\n"
2711 "{\n"
2712 " vec4 innerColor;\n"
2713 " vec4 outerColor;\n"
2714 "} outData;\n"
2715 "\n"
2716 "void main()\n"
2717 "{\n"
2718 " outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
2719 " outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
2720 "}\n";
2721
2722 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2723 }
2724 else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
2725 {
2726 const string computeSrc = "#version 450\n"
2727 "layout(set = 0, binding = " +
2728 de::toString(m_params.binding) +
2729 ", rgba8) uniform readonly image2D storageImage;\n"
2730 "layout(set = 0, binding = " +
2731 de::toString(m_params.binding + 1) +
2732 ") writeonly buffer Output\n"
2733 "{\n"
2734 " vec4 innerColor;\n"
2735 " vec4 outerColor;\n"
2736 "} outData;\n"
2737 "\n"
2738 "void main()\n"
2739 "{\n"
2740 " outData.innerColor = imageLoad(storageImage, ivec2(0));\n"
2741 " outData.outerColor = imageLoad(storageImage, ivec2(0));\n"
2742 "}\n";
2743
2744 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
2745 }
2746 else
2747 {
2748 DE_FATAL("Unexpected descriptor type");
2749 }
2750 }
2751
2752 class PushDescriptorTexelBufferGraphicsTestInstance : public vkt::TestInstance
2753 {
2754 public:
2755 PushDescriptorTexelBufferGraphicsTestInstance(Context &context, const TestParams ¶ms);
2756 virtual ~PushDescriptorTexelBufferGraphicsTestInstance(void);
2757 void init(void);
2758 virtual tcu::TestStatus iterate(void);
2759 tcu::TestStatus verifyImage(void);
2760
2761 private:
2762 const TestParams m_params;
2763 const PlatformInterface &m_vkp;
2764 const Extensions m_instanceExtensions;
2765 const CustomInstance m_instance;
2766 const InstanceDriver &m_vki;
2767 const VkPhysicalDevice m_physicalDevice;
2768 const uint32_t m_queueFamilyIndex;
2769 const Extensions m_deviceExtensions;
2770 std::vector<std::string> m_deviceEnabledExtensions;
2771 const Unique<VkDevice> m_device;
2772 const DeviceDriver m_vkd;
2773 const VkQueue m_queue;
2774 SimpleAllocator m_allocator;
2775 const tcu::UVec2 m_renderSize;
2776 const VkFormat m_colorFormat;
2777 Move<VkImage> m_colorImage;
2778 de::MovePtr<Allocation> m_colorImageAlloc;
2779 Move<VkImageView> m_colorAttachmentView;
2780 vector<VkBufferSp> m_buffers;
2781 vector<AllocationSp> m_bufferAllocs;
2782 vector<VkBufferViewSp> m_bufferViews;
2783 const VkFormat m_bufferFormat;
2784 RenderPassWrapper m_renderPass;
2785 Move<VkFramebuffer> m_framebuffer;
2786 ShaderWrapper m_vertexShaderModule;
2787 ShaderWrapper m_fragmentShaderModule;
2788 Move<VkBuffer> m_vertexBuffer;
2789 de::MovePtr<Allocation> m_vertexBufferAlloc;
2790 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2791 PipelineLayoutWrapper m_preRasterizationStatePipelineLayout;
2792 PipelineLayoutWrapper m_fragmentStatePipelineLayout;
2793 GraphicsPipelineWrapper m_graphicsPipeline;
2794 Move<VkCommandPool> m_cmdPool;
2795 Move<VkCommandBuffer> m_cmdBuffer;
2796 vector<Vertex4RGBA> m_vertices;
2797 };
2798
PushDescriptorTexelBufferGraphicsTestInstance(Context & context,const TestParams & params)2799 PushDescriptorTexelBufferGraphicsTestInstance::PushDescriptorTexelBufferGraphicsTestInstance(Context &context,
2800 const TestParams ¶ms)
2801 : vkt::TestInstance(context)
2802 , m_params(params)
2803 , m_vkp(context.getPlatformInterface())
2804 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
2805 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
2806 , m_vki(m_instance.getDriver())
2807 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
2808 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
2809 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
2810 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
2811 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
2812 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
2813 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
2814 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
2815 , m_renderSize(32, 32)
2816 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
2817 , m_bufferFormat(VK_FORMAT_R32G32B32A32_SFLOAT)
2818 , m_graphicsPipeline(m_vki, m_vkd, m_physicalDevice, *m_device, m_deviceEnabledExtensions,
2819 params.pipelineConstructionType)
2820 , m_vertices(createQuads(params.numCalls, 0.25f))
2821 {
2822 }
2823
init(void)2824 void PushDescriptorTexelBufferGraphicsTestInstance::init(void)
2825 {
2826 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
2827 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
2828
2829 // Create color image
2830 {
2831
2832 const VkImageCreateInfo colorImageParams = {
2833 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2834 nullptr, // const void* pNext;
2835 0u, // VkImageCreateFlags flags;
2836 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2837 m_colorFormat, // VkFormat format;
2838 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
2839 1u, // uint32_t mipLevels;
2840 1u, // uint32_t arrayLayers;
2841 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2842 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2843 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2844 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2845 1u, // uint32_t queueFamilyIndexCount;
2846 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
2847 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2848 };
2849
2850 m_colorImage = createImage(m_vkd, *m_device, &colorImageParams);
2851
2852 // Allocate and bind color image memory
2853 m_colorImageAlloc =
2854 m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
2855 VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(),
2856 m_colorImageAlloc->getOffset()));
2857 }
2858
2859 // Create color attachment view
2860 {
2861 const VkImageViewCreateInfo colorAttachmentViewParams = {
2862 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2863 nullptr, // const void* pNext;
2864 0u, // VkImageViewCreateFlags flags;
2865 *m_colorImage, // VkImage image;
2866 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2867 m_colorFormat, // VkFormat format;
2868 componentMappingRGBA, // VkChannelMapping channels;
2869 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
2870 };
2871
2872 m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
2873 }
2874
2875 // Create buffers
2876 VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = vk::initVulkanStructure();
2877 for (uint32_t bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
2878 {
2879 const VkBufferUsageFlags usageFlags = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ?
2880 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT :
2881 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
2882
2883 VkBufferCreateInfo bufferCreateInfo{
2884 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2885 nullptr, // const void* pNext;
2886 0u, // VkBufferCreateFlags flags
2887 kSizeofVec4, // VkDeviceSize size;
2888 usageFlags, // VkBufferUsageFlags usage;
2889 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2890 1u, // uint32_t queueFamilyCount;
2891 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
2892 };
2893
2894 if (m_params.useMaintenance5)
2895 {
2896 bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)usageFlags;
2897 bufferCreateInfo.pNext = &bufferUsageFlags2;
2898 bufferCreateInfo.usage = 0;
2899 }
2900
2901 m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
2902 m_bufferAllocs.push_back(
2903 AllocationSp(m_allocator
2904 .allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]),
2905 MemoryRequirement::HostVisible)
2906 .release()));
2907 VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(),
2908 m_bufferAllocs[bufIdx]->getOffset()));
2909
2910 deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], static_cast<size_t>(kSizeofVec4));
2911 flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
2912 }
2913
2914 // Create buffer views
2915 for (uint32_t bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
2916 {
2917 const VkBufferViewCreateInfo bufferViewParams = {
2918 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
2919 nullptr, // const void* pNext;
2920 0u, // VkBufferViewCreateFlags flags;
2921 **m_buffers[bufIdx], // VkBuffer buffer;
2922 m_bufferFormat, // VkFormat format;
2923 0u, // VkDeviceSize offset;
2924 VK_WHOLE_SIZE // VkDeviceSize range;
2925 };
2926
2927 m_bufferViews.push_back(
2928 VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
2929 }
2930
2931 // Create render pass
2932 m_renderPass = RenderPassWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, m_colorFormat);
2933
2934 // Create framebuffer
2935 {
2936 const VkImageView attachmentBindInfos[] = {*m_colorAttachmentView};
2937
2938 const VkFramebufferCreateInfo framebufferParams = {
2939 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2940 nullptr, // const void* pNext;
2941 0u, // VkFramebufferCreateFlags flags;
2942 *m_renderPass, // VkRenderPass renderPass;
2943 1u, // uint32_t attachmentCount;
2944 attachmentBindInfos, // const VkImageView* pAttachments;
2945 (uint32_t)m_renderSize.x(), // uint32_t width;
2946 (uint32_t)m_renderSize.y(), // uint32_t height;
2947 1u // uint32_t layers;
2948 };
2949
2950 m_renderPass.createFramebuffer(m_vkd, *m_device, &framebufferParams, *m_colorImage);
2951 }
2952
2953 // Create pipeline layout
2954 {
2955 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
2956 m_params.binding, // uint32_t binding;
2957 m_params.descriptorType, // VkDescriptorType descriptorType;
2958 1u, // uint32_t descriptorCount;
2959 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
2960 nullptr // const VkSampler* pImmutableSamplers;
2961 };
2962
2963 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
2964 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
2965 nullptr, // const void* pNext;
2966 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
2967 1u, // uint32_t bindingCount;
2968 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
2969 };
2970
2971 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
2972
2973 VkPipelineLayoutCreateFlags pipelineLayoutFlags =
2974 (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ?
2975 0u :
2976 uint32_t(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
2977 VkPipelineLayoutCreateInfo pipelineLayoutParams{
2978 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2979 nullptr, // const void* pNext;
2980 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags;
2981 0u, // uint32_t setLayoutCount;
2982 nullptr, // const VkDescriptorSetLayout* pSetLayouts;
2983 0u, // uint32_t pushConstantRangeCount;
2984 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
2985 };
2986
2987 m_preRasterizationStatePipelineLayout =
2988 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
2989 pipelineLayoutParams.setLayoutCount = 1u;
2990 pipelineLayoutParams.pSetLayouts = &(*m_descriptorSetLayout);
2991 m_fragmentStatePipelineLayout =
2992 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
2993 }
2994
2995 // Create shaders
2996 {
2997 m_vertexShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
2998 m_fragmentShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
2999 }
3000
3001 // Create pipeline
3002 {
3003 const VkVertexInputBindingDescription vertexInputBindingDescription = {
3004 0u, // uint32_t binding;
3005 sizeof(Vertex4RGBA), // uint32_t strideInBytes;
3006 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
3007 };
3008
3009 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
3010 {
3011 0u, // uint32_t location;
3012 0u, // uint32_t binding;
3013 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3014 0u // uint32_t offsetInBytes;
3015 },
3016 {
3017 1u, // uint32_t location;
3018 0u, // uint32_t binding;
3019 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3020 offsetof(Vertex4RGBA, color) // uint32_t offset;
3021 }};
3022
3023 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
3024 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3025 nullptr, // const void* pNext;
3026 0u, // vkPipelineVertexInputStateCreateFlags flags;
3027 1u, // uint32_t bindingCount;
3028 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3029 2u, // uint32_t attributeCount;
3030 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3031 };
3032
3033 const vector<VkViewport> viewports{makeViewport(m_renderSize)};
3034 const vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
3035
3036 m_graphicsPipeline.setMonolithicPipelineLayout(m_fragmentStatePipelineLayout)
3037 .setDefaultRasterizationState()
3038 .setDefaultDepthStencilState()
3039 .setDefaultMultisampleState()
3040 .setDefaultColorBlendState()
3041 .setupVertexInputState(&vertexInputStateParams)
3042 .setupPreRasterizationShaderState(viewports, scissors, m_preRasterizationStatePipelineLayout, *m_renderPass,
3043 0u, m_vertexShaderModule)
3044 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule)
3045 .setupFragmentOutputState(*m_renderPass)
3046 .buildPipeline();
3047 }
3048
3049 // Create vertex buffer
3050 {
3051 const VkBufferCreateInfo vertexBufferParams = {
3052 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3053 nullptr, // const void* pNext;
3054 0u, // VkBufferCreateFlags flags;
3055 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size;
3056 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
3057 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3058 1u, // uint32_t queueFamilyCount;
3059 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
3060 };
3061
3062 m_vertexBuffer = createBuffer(m_vkd, *m_device, &vertexBufferParams);
3063 m_vertexBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer),
3064 MemoryRequirement::HostVisible);
3065
3066 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
3067 m_vertexBufferAlloc->getOffset()));
3068
3069 // Load vertices into vertex buffer
3070 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
3071 flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
3072 }
3073
3074 // Create command pool
3075 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3076
3077 // Create command buffer
3078 {
3079 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
3080 const VkDeviceSize vertexBufferOffset = 0;
3081
3082 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3083 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
3084 m_renderPass.begin(m_vkd, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()),
3085 attachmentClearValue);
3086 m_graphicsPipeline.bind(*m_cmdBuffer);
3087 m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3088
3089 // Draw quads. Switch buffer view between draws.
3090 for (uint32_t quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
3091 {
3092 VkWriteDescriptorSet writeDescriptorSet = {
3093 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
3094 nullptr, // const void* pNext;
3095 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
3096 m_params.binding, // uint32_t dstBinding;
3097 0u, // uint32_t dstArrayElement;
3098 1u, // uint32_t descriptorCount;
3099 m_params.descriptorType, // VkDescriptorType descriptorType;
3100 nullptr, // const VkDescriptorImageInfo* pImageInfo;
3101 nullptr, // const VkDescriptorBufferInfo* pBufferInfo;
3102 &m_bufferViews[quadNdx]->get() // const VkBufferView* pTexelBufferView;
3103 };
3104
3105 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0,
3106 1u, &writeDescriptorSet);
3107 m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
3108 }
3109
3110 m_renderPass.end(m_vkd, *m_cmdBuffer);
3111 endCommandBuffer(m_vkd, *m_cmdBuffer);
3112 }
3113 }
3114
~PushDescriptorTexelBufferGraphicsTestInstance(void)3115 PushDescriptorTexelBufferGraphicsTestInstance::~PushDescriptorTexelBufferGraphicsTestInstance(void)
3116 {
3117 }
3118
iterate(void)3119 tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::iterate(void)
3120 {
3121 init();
3122
3123 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
3124
3125 return verifyImage();
3126 }
3127
verifyImage(void)3128 tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::verifyImage(void)
3129 {
3130 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
3131 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
3132 const ColorVertexShader vertexShader;
3133 const ColorFragmentShader fragmentShader(tcuColorFormat, tcuDepthFormat);
3134 const rr::Program program(&vertexShader, &fragmentShader);
3135 ReferenceRenderer refRenderer(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
3136 bool compareOk = false;
3137
3138 // Render reference image
3139 {
3140 for (uint32_t quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
3141 for (uint32_t vertexIdx = 0; vertexIdx < 6; vertexIdx++)
3142 m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = defaultTestColors[quadIdx];
3143
3144 refRenderer.draw(rr::RenderState(refRenderer.getViewportState(),
3145 m_context.getDeviceProperties().limits.subPixelPrecisionBits),
3146 rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
3147 }
3148
3149 // Compare result with reference image
3150 {
3151 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(
3152 m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
3153
3154 compareOk = tcu::intThresholdPositionDeviationCompare(
3155 m_context.getTestContext().getLog(), "IntImageCompare", "Image comparison", refRenderer.getAccess(),
3156 result->getAccess(), tcu::UVec4(2, 2, 2, 2), tcu::IVec3(1, 1, 0), true, tcu::COMPARE_LOG_RESULT);
3157 }
3158
3159 if (compareOk)
3160 return tcu::TestStatus::pass("Result image matches reference");
3161 else
3162 return tcu::TestStatus::fail("Image mismatch");
3163 }
3164
3165 class PushDescriptorTexelBufferGraphicsTest : public vkt::TestCase
3166 {
3167 public:
3168 PushDescriptorTexelBufferGraphicsTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
3169 ~PushDescriptorTexelBufferGraphicsTest(void);
3170
3171 void checkSupport(Context &context) const;
3172 void initPrograms(SourceCollections &sourceCollections) const;
3173 TestInstance *createInstance(Context &context) const;
3174
3175 protected:
3176 const TestParams m_params;
3177 };
3178
PushDescriptorTexelBufferGraphicsTest(tcu::TestContext & testContext,const string & name,const TestParams & params)3179 PushDescriptorTexelBufferGraphicsTest::PushDescriptorTexelBufferGraphicsTest(tcu::TestContext &testContext,
3180 const string &name,
3181 const TestParams ¶ms)
3182 : vkt::TestCase(testContext, name)
3183 , m_params(params)
3184 {
3185 }
3186
~PushDescriptorTexelBufferGraphicsTest(void)3187 PushDescriptorTexelBufferGraphicsTest::~PushDescriptorTexelBufferGraphicsTest(void)
3188 {
3189 }
3190
createInstance(Context & context) const3191 TestInstance *PushDescriptorTexelBufferGraphicsTest::createInstance(Context &context) const
3192 {
3193 return new PushDescriptorTexelBufferGraphicsTestInstance(context, m_params);
3194 }
3195
checkSupport(Context & context) const3196 void PushDescriptorTexelBufferGraphicsTest::checkSupport(Context &context) const
3197 {
3198 if (m_params.useMaintenance5)
3199 context.requireDeviceFunctionality("VK_KHR_maintenance5");
3200
3201 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
3202 m_params.pipelineConstructionType);
3203 }
3204
initPrograms(SourceCollections & sourceCollections) const3205 void PushDescriptorTexelBufferGraphicsTest::initPrograms(SourceCollections &sourceCollections) const
3206 {
3207 const string vertexSrc = "#version 450\n"
3208 "layout(location = 0) in highp vec4 position;\n"
3209 "layout(location = 1) in highp vec4 texcoordVtx;\n"
3210 "layout(location = 0) out highp vec2 texcoordFrag;\n"
3211 "\n"
3212 "out gl_PerVertex { vec4 gl_Position; };\n"
3213 "\n"
3214 "void main()\n"
3215 "{\n"
3216 " gl_Position = position;\n"
3217 " texcoordFrag = texcoordVtx.xy;\n"
3218 "}\n";
3219
3220 sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
3221
3222 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
3223 {
3224 const string fragmentSrc = "#version 450\n"
3225 "layout(location = 0) in highp vec2 texcoordFrag;\n"
3226 "layout(location = 0) out highp vec4 fragColor;\n"
3227 "layout(set = 0, binding = " +
3228 de::toString(m_params.binding) +
3229 ") uniform textureBuffer texelBuffer;\n"
3230 "\n"
3231 "void main (void)\n"
3232 "{\n"
3233 " fragColor = texelFetch(texelBuffer, 0);\n"
3234 "}\n";
3235
3236 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
3237 }
3238 else
3239 {
3240 DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
3241 const string fragmentSrc = "#version 450\n"
3242 "layout(location = 0) in highp vec2 texcoordFrag;\n"
3243 "layout(location = 0) out highp vec4 fragColor;\n"
3244 "layout(set = 0, binding = " +
3245 de::toString(m_params.binding) +
3246 ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
3247 "\n"
3248 "void main (void)\n"
3249 "{\n"
3250 " fragColor = imageLoad(texelBuffer, 0);\n"
3251 "}\n";
3252
3253 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
3254 }
3255 }
3256
3257 class PushDescriptorTexelBufferComputeTestInstance : public vkt::TestInstance
3258 {
3259 public:
3260 PushDescriptorTexelBufferComputeTestInstance(Context &context, const TestParams ¶ms);
3261 virtual ~PushDescriptorTexelBufferComputeTestInstance(void);
3262 void init(void);
3263 virtual tcu::TestStatus iterate(void);
3264 tcu::TestStatus verifyOutput(void);
3265
3266 private:
3267 const TestParams m_params;
3268 const PlatformInterface &m_vkp;
3269 const Extensions m_instanceExtensions;
3270 const CustomInstance m_instance;
3271 const InstanceDriver &m_vki;
3272 const VkPhysicalDevice m_physicalDevice;
3273 const uint32_t m_queueFamilyIndex;
3274 const Extensions m_deviceExtensions;
3275 std::vector<std::string> m_deviceEnabledExtensions;
3276 const Unique<VkDevice> m_device;
3277 const DeviceDriver m_vkd;
3278 const VkQueue m_queue;
3279 const VkDeviceSize m_itemSize;
3280 SimpleAllocator m_allocator;
3281 vector<VkBufferSp> m_buffers;
3282 vector<AllocationSp> m_bufferAllocs;
3283 vector<VkBufferViewSp> m_bufferViews;
3284 const VkFormat m_bufferFormat;
3285 Move<VkShaderModule> m_computeShaderModule;
3286 Move<VkBuffer> m_outputBuffer;
3287 de::MovePtr<Allocation> m_outputBufferAlloc;
3288 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
3289 Move<VkPipelineLayout> m_pipelineLayout;
3290 Move<VkPipeline> m_computePipeline;
3291 Move<VkCommandPool> m_cmdPool;
3292 Move<VkCommandBuffer> m_cmdBuffer;
3293 };
3294
PushDescriptorTexelBufferComputeTestInstance(Context & context,const TestParams & params)3295 PushDescriptorTexelBufferComputeTestInstance::PushDescriptorTexelBufferComputeTestInstance(Context &context,
3296 const TestParams ¶ms)
3297 : vkt::TestInstance(context)
3298 , m_params(params)
3299 , m_vkp(context.getPlatformInterface())
3300 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
3301 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
3302 , m_vki(m_instance.getDriver())
3303 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
3304 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
3305 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
3306 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
3307 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
3308 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
3309 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
3310 , m_itemSize(calcItemSize(m_vki, m_physicalDevice))
3311 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
3312 , m_bufferFormat(VK_FORMAT_R32G32B32A32_SFLOAT)
3313 {
3314 }
3315
init(void)3316 void PushDescriptorTexelBufferComputeTestInstance::init(void)
3317 {
3318 // Create buffers
3319 for (uint32_t bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
3320 {
3321 const VkBufferUsageFlags usageFlags = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ?
3322 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT :
3323 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
3324
3325 const VkBufferCreateInfo bufferCreateInfo = {
3326 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3327 nullptr, // const void* pNext;
3328 0u, // VkBufferCreateFlags flags
3329 kSizeofVec4, // VkDeviceSize size;
3330 usageFlags, // VkBufferUsageFlags usage;
3331 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3332 1u, // uint32_t queueFamilyCount;
3333 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
3334 };
3335
3336 m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
3337 m_bufferAllocs.push_back(
3338 AllocationSp(m_allocator
3339 .allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]),
3340 MemoryRequirement::HostVisible)
3341 .release()));
3342 VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(),
3343 m_bufferAllocs[bufIdx]->getOffset()));
3344
3345 deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &defaultTestColors[bufIdx], static_cast<size_t>(kSizeofVec4));
3346 flushAlloc(m_vkd, *m_device, *m_bufferAllocs[bufIdx]);
3347 }
3348
3349 // Create buffer views
3350 for (uint32_t bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(defaultTestColors); bufIdx++)
3351 {
3352 const VkBufferViewCreateInfo bufferViewParams = {
3353 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
3354 nullptr, // const void* pNext;
3355 0u, // VkBufferViewCreateFlags flags;
3356 **m_buffers[bufIdx], // VkBuffer buffer;
3357 m_bufferFormat, // VkFormat format;
3358 0u, // VkDeviceSize offset;
3359 VK_WHOLE_SIZE // VkDeviceSize range;
3360 };
3361
3362 m_bufferViews.push_back(
3363 VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
3364 }
3365
3366 // Create pipeline layout
3367 {
3368 vector<VkDescriptorSetLayoutBinding> layoutBindings;
3369
3370 const VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[] = {
3371 {
3372 m_params.binding, // uint32_t binding;
3373 m_params.descriptorType, // VkDescriptorType descriptorType;
3374 1u, // uint32_t descriptorCount;
3375 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
3376 nullptr // const VkSampler* pImmutableSamplers;
3377 },
3378 {
3379 m_params.binding + 1, // uint32_t binding;
3380 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
3381 1u, // uint32_t descriptorCount;
3382 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
3383 nullptr // const VkSampler* pImmutableSamplers;
3384 }};
3385
3386 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
3387 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
3388 nullptr, // const void* pNext;
3389 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
3390 2u, // uint32_t bindingCount;
3391 descriptorSetLayoutBindings // const VkDescriptorSetLayoutBinding* pBindings;
3392 };
3393
3394 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
3395
3396 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
3397 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3398 nullptr, // const void* pNext;
3399 0u, // VkPipelineLayoutCreateFlags flags;
3400 1u, // uint32_t descriptorSetCount;
3401 &(*m_descriptorSetLayout), // const VkDescriptorSetLayout* pSetLayouts;
3402 0u, // uint32_t pushConstantRangeCount;
3403 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
3404 };
3405
3406 m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
3407 }
3408
3409 // Create output buffer
3410 {
3411 DE_ASSERT(m_params.numCalls <= 2u);
3412
3413 const VkBufferCreateInfo bufferCreateInfo = {
3414 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3415 nullptr, // const void* pNext;
3416 0u, // VkBufferCreateFlags flags
3417 m_itemSize * m_params.numCalls, // VkDeviceSize size;
3418 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage;
3419 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3420 1u, // uint32_t queueFamilyCount;
3421 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
3422 };
3423
3424 m_outputBuffer = createBuffer(m_vkd, *m_device, &bufferCreateInfo);
3425 m_outputBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer),
3426 MemoryRequirement::HostVisible);
3427 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(),
3428 m_outputBufferAlloc->getOffset()));
3429 }
3430
3431 // Create shader
3432 {
3433 m_computeShaderModule =
3434 createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
3435 }
3436
3437 // Create pipeline
3438 {
3439 const VkPipelineShaderStageCreateInfo stageCreateInfo = {
3440 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
3441 nullptr, // const void* pNext;
3442 0u, // VkPipelineShaderStageCreateFlags flags;
3443 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
3444 *m_computeShaderModule, // VkShaderModule module;
3445 "main", // const char* pName;
3446 nullptr // const VkSpecializationInfo* pSpecializationInfo;
3447 };
3448
3449 const VkComputePipelineCreateInfo createInfo = {
3450 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
3451 nullptr, // const void* pNext;
3452 0u, // VkPipelineCreateFlags flags;
3453 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
3454 *m_pipelineLayout, // VkPipelineLayout layout;
3455 VK_NULL_HANDLE, // VkPipeline basePipelineHandle;
3456 0u, // int32_t basePipelineIndex;
3457 };
3458
3459 m_computePipeline = createComputePipeline(m_vkd, *m_device, VK_NULL_HANDLE, &createInfo);
3460 }
3461
3462 // Create command pool
3463 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3464
3465 // Create command buffer
3466 {
3467 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3468 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
3469 m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
3470
3471 // Dispatch: Each dispatch switches the input image.
3472 // Output buffer is exposed as a vec4 sized window.
3473 for (uint32_t dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
3474 {
3475 VkWriteDescriptorSet writeDescriptorSet = {
3476 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
3477 nullptr, // const void* pNext;
3478 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
3479 m_params.binding, // uint32_t dstBinding;
3480 0u, // uint32_t dstArrayElement;
3481 1u, // uint32_t descriptorCount;
3482 m_params.descriptorType, // VkDescriptorType descriptorType;
3483 nullptr, // const VkDescriptorImageInfo* pImageInfo;
3484 nullptr, // const VkDescriptorBufferInfo* pBufferInfo;
3485 &m_bufferViews[dispatchNdx]->get() // const VkBufferView* pTexelBufferView;
3486 };
3487
3488 vector<VkWriteDescriptorSet> writeDescriptorSets;
3489 writeDescriptorSets.push_back(writeDescriptorSet);
3490
3491 const VkDescriptorBufferInfo descriptorBufferInfoOutput = {
3492 *m_outputBuffer, // VkBuffer buffer;
3493 m_itemSize * dispatchNdx, // VkDeviceSize offset;
3494 kSizeofVec4, // VkDeviceSize range;
3495 };
3496
3497 // Write output buffer descriptor set
3498 const VkWriteDescriptorSet writeDescriptorSetOutput = {
3499 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
3500 nullptr, // const void* pNext;
3501 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
3502 m_params.binding + 1, // uint32_t dstBinding;
3503 0u, // uint32_t dstArrayElement;
3504 1u, // uint32_t descriptorCount;
3505 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
3506 nullptr, // const VkDescriptorImageInfo* pImageInfo;
3507 &descriptorBufferInfoOutput, // const VkDescriptorBufferInfo* pBufferInfo;
3508 nullptr // const VkBufferView* pTexelBufferView;
3509 };
3510
3511 writeDescriptorSets.push_back(writeDescriptorSetOutput);
3512
3513 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0,
3514 (uint32_t)writeDescriptorSets.size(), writeDescriptorSets.data());
3515 m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
3516
3517 const VkMemoryBarrier barrier = {
3518 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
3519 nullptr, // pNext
3520 VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
3521 VK_ACCESS_HOST_READ_BIT, // dstAccessMask
3522 };
3523 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
3524 (VkDependencyFlags)0, 1, &barrier, 0, nullptr, 0, nullptr);
3525 }
3526
3527 endCommandBuffer(m_vkd, *m_cmdBuffer);
3528 }
3529 }
3530
~PushDescriptorTexelBufferComputeTestInstance(void)3531 PushDescriptorTexelBufferComputeTestInstance::~PushDescriptorTexelBufferComputeTestInstance(void)
3532 {
3533 }
3534
iterate(void)3535 tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::iterate(void)
3536 {
3537 init();
3538
3539 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
3540
3541 return verifyOutput();
3542 }
3543
verifyOutput(void)3544 tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::verifyOutput(void)
3545 {
3546 const tcu::Vec4 ref[2] = {{1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}};
3547 invalidateAlloc(m_vkd, *m_device, *m_outputBufferAlloc);
3548
3549 // Verify result
3550 DE_ASSERT(m_params.numCalls <= 2u);
3551
3552 auto bufferPtr = reinterpret_cast<const char *>(m_outputBufferAlloc->getHostPtr());
3553 for (uint32_t i = 0; i < m_params.numCalls; ++i)
3554 {
3555 tcu::Vec4 bufferColor;
3556 deMemcpy(&bufferColor, bufferPtr + (i * m_itemSize), static_cast<size_t>(kSizeofVec4));
3557
3558 if (bufferColor != ref[i])
3559 {
3560 std::ostringstream msg;
3561 msg << "Output mismatch at item " << i << ": expected " << ref[i] << " but found " << bufferColor;
3562 TCU_FAIL(msg.str());
3563 }
3564 }
3565
3566 return tcu::TestStatus::pass("Output matches expected values");
3567 }
3568
3569 class PushDescriptorTexelBufferComputeTest : public vkt::TestCase
3570 {
3571 public:
3572 PushDescriptorTexelBufferComputeTest(tcu::TestContext &testContext, const string &name, const TestParams ¶ms);
3573 ~PushDescriptorTexelBufferComputeTest(void);
3574 void initPrograms(SourceCollections &sourceCollections) const;
3575 TestInstance *createInstance(Context &context) const;
3576
3577 protected:
3578 const TestParams m_params;
3579 };
3580
PushDescriptorTexelBufferComputeTest(tcu::TestContext & testContext,const string & name,const TestParams & params)3581 PushDescriptorTexelBufferComputeTest::PushDescriptorTexelBufferComputeTest(tcu::TestContext &testContext,
3582 const string &name, const TestParams ¶ms)
3583 : vkt::TestCase(testContext, name)
3584 , m_params(params)
3585 {
3586 }
3587
~PushDescriptorTexelBufferComputeTest(void)3588 PushDescriptorTexelBufferComputeTest::~PushDescriptorTexelBufferComputeTest(void)
3589 {
3590 }
3591
createInstance(Context & context) const3592 TestInstance *PushDescriptorTexelBufferComputeTest::createInstance(Context &context) const
3593 {
3594 return new PushDescriptorTexelBufferComputeTestInstance(context, m_params);
3595 }
3596
initPrograms(SourceCollections & sourceCollections) const3597 void PushDescriptorTexelBufferComputeTest::initPrograms(SourceCollections &sourceCollections) const
3598 {
3599 if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
3600 {
3601 const string computeSrc = "#version 450\n"
3602 "layout(set = 0, binding = " +
3603 de::toString(m_params.binding) +
3604 ") uniform textureBuffer texelBuffer;\n"
3605 "layout(set = 0, binding = " +
3606 de::toString(m_params.binding + 1) +
3607 ") writeonly buffer Output\n"
3608 "{\n"
3609 " vec4 color;\n"
3610 "} outData;\n"
3611 "\n"
3612 "void main()\n"
3613 "{\n"
3614 " outData.color = texelFetch(texelBuffer, 0);\n"
3615 "}\n";
3616
3617 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
3618 }
3619 else
3620 {
3621 DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
3622
3623 const string computeSrc = "#version 450\n"
3624 "layout(set = 0, binding = " +
3625 de::toString(m_params.binding) +
3626 ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
3627 "layout(set = 0, binding = " +
3628 de::toString(m_params.binding + 1) +
3629 ") writeonly buffer Output\n"
3630 "{\n"
3631 " vec4 color;\n"
3632 "} outData;\n"
3633 "\n"
3634 "void main()\n"
3635 "{\n"
3636 " outData.color = imageLoad(texelBuffer, 0);\n"
3637 "}\n";
3638
3639 sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
3640 }
3641 }
3642
3643 class PushDescriptorInputAttachmentGraphicsTestInstance : public vkt::TestInstance
3644 {
3645 public:
3646 PushDescriptorInputAttachmentGraphicsTestInstance(Context &context, const TestParams ¶ms);
3647 virtual ~PushDescriptorInputAttachmentGraphicsTestInstance(void);
3648 void init(void);
3649 virtual tcu::TestStatus iterate(void);
3650 tcu::TestStatus verifyImage(void);
3651
3652 private:
3653 const TestParams m_params;
3654 const PlatformInterface &m_vkp;
3655 const Extensions m_instanceExtensions;
3656 const CustomInstance m_instance;
3657 const InstanceDriver &m_vki;
3658 const VkPhysicalDevice m_physicalDevice;
3659 const uint32_t m_queueFamilyIndex;
3660 const Extensions m_deviceExtensions;
3661 std::vector<std::string> m_deviceEnabledExtensions;
3662 const Unique<VkDevice> m_device;
3663 const DeviceDriver m_vkd;
3664 const VkQueue m_queue;
3665 SimpleAllocator m_allocator;
3666 const tcu::UVec2 m_renderSize;
3667 const tcu::UVec2 m_textureSize;
3668 const VkFormat m_colorFormat;
3669 Move<VkImage> m_colorImage;
3670 de::MovePtr<Allocation> m_colorImageAlloc;
3671 Move<VkImageView> m_colorAttachmentView;
3672 vector<VkImageSp> m_inputImages;
3673 vector<AllocationSp> m_inputImageAllocs;
3674 vector<VkImageViewSp> m_inputImageViews;
3675 vector<VkRenderPassSp> m_renderPasses;
3676 ShaderWrapper m_vertexShaderModule;
3677 ShaderWrapper m_fragmentShaderModule;
3678 Move<VkBuffer> m_vertexBuffer;
3679 de::MovePtr<Allocation> m_vertexBufferAlloc;
3680 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
3681 PipelineLayoutWrapper m_preRasterizationStatePipelineLayout;
3682 PipelineLayoutWrapper m_fragmentStatePipelineLayout;
3683 vector<GraphicsPipelineWrapper> m_graphicsPipelines;
3684 Move<VkCommandPool> m_cmdPool;
3685 Move<VkCommandBuffer> m_cmdBuffer;
3686 vector<Vertex4Tex4> m_vertices;
3687 };
3688
PushDescriptorInputAttachmentGraphicsTestInstance(Context & context,const TestParams & params)3689 PushDescriptorInputAttachmentGraphicsTestInstance::PushDescriptorInputAttachmentGraphicsTestInstance(
3690 Context &context, const TestParams ¶ms)
3691 : vkt::TestInstance(context)
3692 , m_params(params)
3693 , m_vkp(context.getPlatformInterface())
3694 , m_instanceExtensions(enumerateInstanceExtensionProperties(m_vkp, nullptr))
3695 , m_instance(createInstanceWithGetPhysicalDeviceProperties2(context, m_instanceExtensions))
3696 , m_vki(m_instance.getDriver())
3697 , m_physicalDevice(chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
3698 , m_queueFamilyIndex(findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
3699 , m_deviceExtensions(enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, nullptr))
3700 , m_device(createDeviceWithPushDescriptor(context, m_vkp, m_instance, m_vki, m_physicalDevice, m_deviceExtensions,
3701 m_queueFamilyIndex, params, m_deviceEnabledExtensions))
3702 , m_vkd(m_vkp, m_instance, *m_device, context.getUsedApiVersion(), context.getTestContext().getCommandLine())
3703 , m_queue(getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
3704 , m_allocator(m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
3705 , m_renderSize(32, 32)
3706 , m_textureSize(32, 32)
3707 , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM)
3708 , m_vertices(createTexQuads(params.numCalls, 0.25f))
3709 {
3710 }
3711
init(void)3712 void PushDescriptorInputAttachmentGraphicsTestInstance::init(void)
3713 {
3714 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
3715 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
3716
3717 // Create color image
3718 {
3719
3720 const VkImageCreateInfo colorImageParams = {
3721 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3722 nullptr, // const void* pNext;
3723 0u, // VkImageCreateFlags flags;
3724 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3725 m_colorFormat, // VkFormat format;
3726 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
3727 1u, // uint32_t mipLevels;
3728 1u, // uint32_t arrayLayers;
3729 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3730 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3731 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
3732 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3733 1u, // uint32_t queueFamilyIndexCount;
3734 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
3735 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3736 };
3737
3738 m_colorImage = createImage(m_vkd, *m_device, &colorImageParams);
3739
3740 // Allocate and bind color image memory
3741 m_colorImageAlloc =
3742 m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
3743 VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(),
3744 m_colorImageAlloc->getOffset()));
3745 }
3746
3747 // Create color attachment view
3748 {
3749 const VkImageViewCreateInfo colorAttachmentViewParams = {
3750 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3751 nullptr, // const void* pNext;
3752 0u, // VkImageViewCreateFlags flags;
3753 *m_colorImage, // VkImage image;
3754 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3755 m_colorFormat, // VkFormat format;
3756 componentMappingRGBA, // VkChannelMapping channels;
3757 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
3758 };
3759
3760 m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
3761 }
3762
3763 // Create input images
3764 for (uint32_t imageIdx = 0; imageIdx < 2; imageIdx++)
3765 {
3766 const VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3767
3768 const VkImageCreateInfo inputImageParams = {
3769 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3770 nullptr, // const void* pNext;
3771 0u, // VkImageCreateFlags flags;
3772 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3773 m_colorFormat, // VkFormat format;
3774 {m_textureSize.x(), m_textureSize.y(), 1u}, // VkExtent3D extent;
3775 1u, // uint32_t mipLevels;
3776 1u, // uint32_t arrayLayers;
3777 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3778 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3779 usageFlags, // VkImageUsageFlags usage;
3780 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3781 1u, // uint32_t queueFamilyIndexCount;
3782 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
3783 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3784 };
3785
3786 m_inputImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &inputImageParams))));
3787
3788 // Allocate and bind image memory
3789 m_inputImageAllocs.push_back(AllocationSp(
3790 m_allocator
3791 .allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_inputImages.back()), MemoryRequirement::Any)
3792 .release()));
3793 VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_inputImages.back(), m_inputImageAllocs.back()->getMemory(),
3794 m_inputImageAllocs.back()->getOffset()));
3795 }
3796
3797 // Create texture image views
3798 for (uint32_t imageIdx = 0; imageIdx < 2; imageIdx++)
3799 {
3800 const VkImageViewCreateInfo textureViewParams = {
3801 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3802 nullptr, // const void* pNext;
3803 0u, // VkImageViewCreateFlags flags;
3804 **m_inputImages[imageIdx], // VkImage image;
3805 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3806 m_colorFormat, // VkFormat format;
3807 componentMappingRGBA, // VkChannelMapping channels;
3808 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
3809 };
3810
3811 m_inputImageViews.push_back(
3812 VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
3813 }
3814
3815 VkClearValue clearValues[2];
3816 clearValues[0].color.float32[0] = 0.0f;
3817 clearValues[0].color.float32[1] = 1.0f;
3818 clearValues[0].color.float32[2] = 0.0f;
3819 clearValues[0].color.float32[3] = 1.0f;
3820 clearValues[1].color.float32[0] = 1.0f;
3821 clearValues[1].color.float32[1] = 0.0f;
3822 clearValues[1].color.float32[2] = 0.0f;
3823 clearValues[1].color.float32[3] = 1.0f;
3824
3825 // Clear input images
3826 for (uint32_t imageIdx = 0; imageIdx < 2; imageIdx++)
3827 {
3828 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3829 Move<VkCommandPool> cmdPool;
3830 Move<VkCommandBuffer> cmdBuffer;
3831 const VkAccessFlags accessFlags = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
3832
3833 cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
3834 cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3835
3836 const VkImageMemoryBarrier preImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3837 nullptr, // const void* pNext;
3838 0u, // VkAccessFlags srcAccessMask;
3839 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3840 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3841 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
3842 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3843 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3844 **m_inputImages[imageIdx], // VkImage image;
3845 {
3846 // VkImageSubresourceRange subresourceRange;
3847 aspectMask, // VkImageAspect aspect;
3848 0u, // uint32_t baseMipLevel;
3849 1u, // uint32_t mipLevels;
3850 0u, // uint32_t baseArraySlice;
3851 1u // uint32_t arraySize;
3852 }};
3853
3854 const VkImageMemoryBarrier postImageBarrier = {
3855 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3856 nullptr, // const void* pNext;
3857 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3858 accessFlags, // VkAccessFlags dstAccessMask;
3859 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3860 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
3861 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
3862 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
3863 **m_inputImages[imageIdx], // VkImage image;
3864 {
3865 // VkImageSubresourceRange subresourceRange;
3866 aspectMask, // VkImageAspect aspect;
3867 0u, // uint32_t baseMipLevel;
3868 1u, // uint32_t mipLevels;
3869 0u, // uint32_t baseArraySlice;
3870 1u // uint32_t arraySize;
3871 }};
3872
3873 const VkImageSubresourceRange clearRange = {
3874 aspectMask, // VkImageAspectFlags aspectMask;
3875 0u, // uint32_t baseMipLevel;
3876 1u, // uint32_t levelCount;
3877 0u, // uint32_t baseArrayLayer;
3878 1u // uint32_t layerCount;
3879 };
3880
3881 beginCommandBuffer(m_vkd, *cmdBuffer);
3882 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3883 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &preImageBarrier);
3884 m_vkd.cmdClearColorImage(*cmdBuffer, **m_inputImages[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3885 &clearValues[imageIdx].color, 1, &clearRange);
3886 m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
3887 (VkDependencyFlags)0, 0, nullptr, 0, nullptr, 1, &postImageBarrier);
3888 endCommandBuffer(m_vkd, *cmdBuffer);
3889
3890 submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
3891 }
3892
3893 // Create render passes
3894 for (uint32_t renderPassIdx = 0; renderPassIdx < 2; renderPassIdx++)
3895 {
3896 // The first pass clears the output image, and the second one draws on top of the first pass.
3897 const VkAttachmentLoadOp loadOps[] = {VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_LOAD};
3898
3899 const VkImageLayout initialLayouts[] = {VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3900
3901 const VkAttachmentDescription attachmentDescriptions[] = {
3902 // Result attachment
3903 {
3904 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
3905 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
3906 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
3907 loadOps[renderPassIdx], // VkAttachmentLoadOp loadOp
3908 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
3909 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
3910 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
3911 initialLayouts[renderPassIdx], // VkImageLayout initialLayout
3912 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
3913 },
3914 // Input attachment
3915 {
3916 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
3917 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
3918 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
3919 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
3920 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
3921 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
3922 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
3923 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout initialLayout
3924 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout
3925 }};
3926
3927 const VkAttachmentReference resultAttachmentRef = {
3928 0u, // uint32_t attachment
3929 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
3930 };
3931
3932 const VkAttachmentReference inputAttachmentRef = {
3933 1u, // uint32_t attachment
3934 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout
3935 };
3936
3937 const VkSubpassDescription subpassDescription = {
3938 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
3939 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
3940 1u, // uint32_t inputAttachmentCount
3941 &inputAttachmentRef, // const VkAttachmentReference* pInputAttachments
3942 1u, // uint32_t colorAttachmentCount
3943 &resultAttachmentRef, // const VkAttachmentReference* pColorAttachments
3944 nullptr, // const VkAttachmentReference* pResolveAttachments
3945 nullptr, // const VkAttachmentReference* pDepthStencilAttachment
3946 0u, // uint32_t preserveAttachmentCount
3947 nullptr // const uint32_t* pPreserveAttachments
3948 };
3949
3950 const VkSubpassDependency subpassDependency = {
3951 VK_SUBPASS_EXTERNAL, // uint32_t srcSubpass
3952 0, // uint32_t dstSubpass
3953 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
3954 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
3955 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3956 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT, // dstAccessMask
3957 VK_DEPENDENCY_BY_REGION_BIT // VkDependencyFlags dependencyFlags
3958 };
3959
3960 const VkRenderPassCreateInfo renderPassInfo = {
3961 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureTypei sType
3962 nullptr, // const void* pNext
3963 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
3964 2u, // uint32_t attachmentCount
3965 attachmentDescriptions, // const VkAttachmentDescription* pAttachments
3966 1u, // uint32_t subpassCount
3967 &subpassDescription, // const VkSubpassDescription* pSubpasses
3968 1u, // uint32_t dependencyCount
3969 &subpassDependency // const VkSubpassDependency* pDependencies
3970 };
3971
3972 m_renderPasses.push_back(VkRenderPassSp(
3973 new RenderPassWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &renderPassInfo)));
3974
3975 std::vector<VkImage> images = {
3976 *m_colorImage,
3977 **m_inputImages[renderPassIdx],
3978 };
3979
3980 const VkImageView attachmentBindInfos[] = {
3981 *m_colorAttachmentView,
3982 **m_inputImageViews[renderPassIdx],
3983 };
3984
3985 const VkFramebufferCreateInfo framebufferParams = {
3986 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3987 nullptr, // const void* pNext;
3988 0u, // VkFramebufferCreateFlags flags;
3989 **m_renderPasses[renderPassIdx], // VkRenderPass renderPass;
3990 2u, // uint32_t attachmentCount;
3991 attachmentBindInfos, // const VkImageView* pAttachments;
3992 (uint32_t)m_renderSize.x(), // uint32_t width;
3993 (uint32_t)m_renderSize.y(), // uint32_t height;
3994 1u // uint32_t layers;
3995 };
3996
3997 m_renderPasses[renderPassIdx]->createFramebuffer(m_vkd, *m_device, &framebufferParams, images);
3998 }
3999
4000 // Create pipeline layout
4001 {
4002 // Create descriptor set layout
4003 const VkDescriptorSetLayoutBinding descriptorSetLayoutBinding = {
4004 m_params.binding, // uint32_t binding;
4005 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
4006 1u, // uint32_t descriptorCount;
4007 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
4008 nullptr // const VkSampler* pImmutableSamplers;
4009 };
4010
4011 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
4012 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
4013 nullptr, // const void* pNext;
4014 VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, // VkDescriptorSetLayoutCreateFlags flags;
4015 1u, // uint32_t bindingCount;
4016 &descriptorSetLayoutBinding // const VkDescriptorSetLayoutBinding* pBindings;
4017 };
4018
4019 m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, nullptr);
4020
4021 // Create pipeline layout
4022 VkPipelineLayoutCreateFlags pipelineLayoutFlags =
4023 (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ?
4024 0u :
4025 uint32_t(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
4026 VkPipelineLayoutCreateInfo pipelineLayoutParams{
4027 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
4028 nullptr, // const void* pNext;
4029 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags;
4030 0u, // uint32_t setLayoutCount;
4031 nullptr, // const VkDescriptorSetLayout* pSetLayouts;
4032 0u, // uint32_t pushConstantRangeCount;
4033 nullptr // const VkPushDescriptorRange* pPushDescriptorRanges;
4034 };
4035
4036 m_preRasterizationStatePipelineLayout =
4037 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
4038 pipelineLayoutParams.setLayoutCount = 1u;
4039 pipelineLayoutParams.pSetLayouts = &(*m_descriptorSetLayout);
4040 m_fragmentStatePipelineLayout =
4041 PipelineLayoutWrapper(m_params.pipelineConstructionType, m_vkd, *m_device, &pipelineLayoutParams);
4042 }
4043
4044 // Create shaders
4045 {
4046 m_vertexShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
4047 m_fragmentShaderModule = ShaderWrapper(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
4048 }
4049
4050 m_graphicsPipelines.reserve(2);
4051
4052 // Create pipelines
4053 for (uint32_t pipelineIdx = 0; pipelineIdx < 2; pipelineIdx++)
4054 {
4055 const VkVertexInputBindingDescription vertexInputBindingDescription = {
4056 0u, // uint32_t binding;
4057 sizeof(Vertex4Tex4), // uint32_t strideInBytes;
4058 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
4059 };
4060
4061 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = {
4062 {
4063 0u, // uint32_t location;
4064 0u, // uint32_t binding;
4065 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4066 0u // uint32_t offsetInBytes;
4067 },
4068 {
4069 1u, // uint32_t location;
4070 0u, // uint32_t binding;
4071 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4072 offsetof(Vertex4Tex4, texCoord), // uint32_t offset;
4073 }};
4074
4075 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
4076 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
4077 nullptr, // const void* pNext;
4078 0u, // vkPipelineVertexInputStateCreateFlags flags;
4079 1u, // uint32_t bindingCount;
4080 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
4081 2u, // uint32_t attributeCount;
4082 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
4083 };
4084
4085 const vector<VkViewport> viewports{makeViewport(m_renderSize)};
4086 const vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
4087
4088 m_graphicsPipelines.emplace_back(m_vki, m_vkd, m_physicalDevice, *m_device, m_deviceEnabledExtensions,
4089 m_params.pipelineConstructionType);
4090 m_graphicsPipelines.back()
4091 .setMonolithicPipelineLayout(m_fragmentStatePipelineLayout)
4092 .setDefaultRasterizationState()
4093 .setDefaultDepthStencilState()
4094 .setDefaultMultisampleState()
4095 .setDefaultColorBlendState()
4096 .setupVertexInputState(&vertexInputStateParams)
4097 .setupPreRasterizationShaderState(viewports, scissors, m_preRasterizationStatePipelineLayout,
4098 **m_renderPasses[pipelineIdx], 0u, m_vertexShaderModule)
4099 .setupFragmentShaderState(m_fragmentStatePipelineLayout, **m_renderPasses[pipelineIdx], 0u,
4100 m_fragmentShaderModule)
4101 .setupFragmentOutputState(**m_renderPasses[pipelineIdx])
4102 .buildPipeline();
4103 }
4104
4105 // Create vertex buffer
4106 {
4107 const VkBufferCreateInfo vertexBufferParams = {
4108 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
4109 nullptr, // const void* pNext;
4110 0u, // VkBufferCreateFlags flags;
4111 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size;
4112 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
4113 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4114 1u, // uint32_t queueFamilyCount;
4115 &m_queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
4116 };
4117
4118 m_vertexBuffer = createBuffer(m_vkd, *m_device, &vertexBufferParams);
4119 m_vertexBufferAlloc = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer),
4120 MemoryRequirement::HostVisible);
4121
4122 VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
4123 m_vertexBufferAlloc->getOffset()));
4124
4125 // Load vertices into vertex buffer
4126 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
4127 flushAlloc(m_vkd, *m_device, *m_vertexBufferAlloc);
4128 }
4129
4130 // Create command pool
4131 m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
4132
4133 // Create command buffer
4134 {
4135 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
4136 const VkDeviceSize vertexBufferOffset = 0;
4137
4138 m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4139 beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
4140 for (uint32_t quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
4141 {
4142 (*m_renderPasses[quadNdx])
4143 .begin(m_vkd, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
4144 m_graphicsPipelines[quadNdx].bind(*m_cmdBuffer);
4145 m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4146
4147 VkDescriptorImageInfo descriptorImageInfo = {
4148 VK_NULL_HANDLE, // VkSampler sampler;
4149 **m_inputImageViews[quadNdx], // VkImageView imageView;
4150 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
4151 };
4152
4153 VkWriteDescriptorSet writeDescriptorSet = {
4154 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
4155 nullptr, // const void* pNext;
4156 VK_NULL_HANDLE, // VkDescriptorSet dstSet;
4157 m_params.binding, // uint32_t dstBinding;
4158 0u, // uint32_t dstArrayElement;
4159 1u, // uint32_t descriptorCount;
4160 m_params.descriptorType, // VkDescriptorType descriptorType;
4161 &descriptorImageInfo, // const VkDescriptorImageInfo* pImageInfo;
4162 nullptr, // const VkDescriptorBufferInfo* pBufferInfo;
4163 nullptr // const VkBufferView* pTexelBufferView;
4164 };
4165
4166 m_vkd.cmdPushDescriptorSet(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0,
4167 1, &writeDescriptorSet);
4168 m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
4169
4170 (*m_renderPasses[quadNdx]).end(m_vkd, *m_cmdBuffer);
4171 }
4172
4173 endCommandBuffer(m_vkd, *m_cmdBuffer);
4174 }
4175 }
4176
~PushDescriptorInputAttachmentGraphicsTestInstance(void)4177 PushDescriptorInputAttachmentGraphicsTestInstance::~PushDescriptorInputAttachmentGraphicsTestInstance(void)
4178 {
4179 }
4180
iterate(void)4181 tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::iterate(void)
4182 {
4183 init();
4184
4185 submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
4186
4187 return verifyImage();
4188 }
4189
verifyImage(void)4190 tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::verifyImage(void)
4191 {
4192 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
4193 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
4194 const ColorVertexShader vertexShader;
4195 const ColorFragmentShader fragmentShader(tcuColorFormat, tcuDepthFormat);
4196 const rr::Program program(&vertexShader, &fragmentShader);
4197 ReferenceRenderer refRenderer(m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
4198 bool compareOk = false;
4199
4200 // Render reference image
4201 {
4202 vector<Vertex4RGBA> refQuads = createQuads(m_params.numCalls, 0.25f);
4203 tcu::Vec4 colors[2];
4204
4205 colors[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
4206 colors[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
4207
4208 for (uint32_t quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
4209 for (uint32_t vertexIdx = 0; vertexIdx < 6; vertexIdx++)
4210 {
4211 const uint32_t idx = quadIdx * 6 + vertexIdx;
4212 refQuads[idx].color.xyzw() = colors[quadIdx];
4213 }
4214
4215 refRenderer.draw(rr::RenderState(refRenderer.getViewportState(),
4216 m_context.getDeviceProperties().limits.subPixelPrecisionBits),
4217 rr::PRIMITIVETYPE_TRIANGLES, refQuads);
4218 }
4219
4220 // Compare result with reference image
4221 {
4222 de::MovePtr<tcu::TextureLevel> result = readColorAttachment(
4223 m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
4224
4225 compareOk = tcu::intThresholdPositionDeviationCompare(
4226 m_context.getTestContext().getLog(), "IntImageCompare", "Image comparison", refRenderer.getAccess(),
4227 result->getAccess(), tcu::UVec4(2, 2, 2, 2), tcu::IVec3(1, 1, 0), true, tcu::COMPARE_LOG_RESULT);
4228 }
4229
4230 if (compareOk)
4231 return tcu::TestStatus::pass("Result image matches reference");
4232 else
4233 return tcu::TestStatus::fail("Image mismatch");
4234 }
4235
4236 class PushDescriptorInputAttachmentGraphicsTest : public vkt::TestCase
4237 {
4238 public:
4239 PushDescriptorInputAttachmentGraphicsTest(tcu::TestContext &testContext, const string &name,
4240 const TestParams ¶ms);
4241 ~PushDescriptorInputAttachmentGraphicsTest(void);
4242
4243 void checkSupport(Context &context) const;
4244 void initPrograms(SourceCollections &sourceCollections) const;
4245 TestInstance *createInstance(Context &context) const;
4246
4247 protected:
4248 const TestParams m_params;
4249 };
4250
PushDescriptorInputAttachmentGraphicsTest(tcu::TestContext & testContext,const string & name,const TestParams & params)4251 PushDescriptorInputAttachmentGraphicsTest::PushDescriptorInputAttachmentGraphicsTest(tcu::TestContext &testContext,
4252 const string &name,
4253 const TestParams ¶ms)
4254 : vkt::TestCase(testContext, name)
4255 , m_params(params)
4256 {
4257 }
4258
~PushDescriptorInputAttachmentGraphicsTest(void)4259 PushDescriptorInputAttachmentGraphicsTest::~PushDescriptorInputAttachmentGraphicsTest(void)
4260 {
4261 }
4262
createInstance(Context & context) const4263 TestInstance *PushDescriptorInputAttachmentGraphicsTest::createInstance(Context &context) const
4264 {
4265 return new PushDescriptorInputAttachmentGraphicsTestInstance(context, m_params);
4266 }
4267
checkSupport(Context & context) const4268 void PushDescriptorInputAttachmentGraphicsTest::checkSupport(Context &context) const
4269 {
4270 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
4271 m_params.pipelineConstructionType);
4272 }
4273
initPrograms(SourceCollections & sourceCollections) const4274 void PushDescriptorInputAttachmentGraphicsTest::initPrograms(SourceCollections &sourceCollections) const
4275 {
4276 const string vertexSrc = "#version 450\n"
4277 "layout(location = 0) in highp vec4 position;\n"
4278 "layout(location = 1) in highp vec4 texcoordVtx;\n"
4279 "layout(location = 0) out highp vec2 texcoordFrag;\n"
4280 "\n"
4281 "out gl_PerVertex { vec4 gl_Position; };\n"
4282 "\n"
4283 "void main()\n"
4284 "{\n"
4285 " gl_Position = position;\n"
4286 " texcoordFrag = texcoordVtx.xy;\n"
4287 "}\n";
4288
4289 sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
4290
4291 const string fragmentSrc = "#version 450\n"
4292 "layout(location = 0) in highp vec2 texcoordFrag;\n"
4293 "layout(location = 0) out highp vec4 fragColor;\n"
4294 "layout(input_attachment_index = 0, set = 0, binding = " +
4295 de::toString(m_params.binding) +
4296 ") uniform subpassInput inputColor;\n"
4297 "\n"
4298 "void main (void)\n"
4299 "{\n"
4300 " fragColor = subpassLoad(inputColor);\n"
4301 "}\n";
4302
4303 sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
4304 }
4305
4306 } // namespace
4307
createPushDescriptorTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineType)4308 tcu::TestCaseGroup *createPushDescriptorTests(tcu::TestContext &testCtx, PipelineConstructionType pipelineType)
4309 {
4310 const TestParams params[]{{pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0u, 1u, false},
4311 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0u, 2u, false},
4312 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, 2u, false},
4313 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u, 2u, false},
4314 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0u, 1u, false},
4315 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0u, 2u, false},
4316 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, 2u, false},
4317 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3u, 2u, false},
4318 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, 128u, false},
4319 {pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0u, 1u, false},
4320 {pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0u, 2u, false},
4321 {pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, 2u, false},
4322 {pipelineType, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 3u, 2u, false},
4323 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER, 0u, 1u, false},
4324 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER, 0u, 2u, false},
4325 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER, 1u, 2u, false},
4326 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLER, 3u, 2u, false},
4327 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0u, 1u, false},
4328 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0u, 2u, false},
4329 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1u, 2u, false},
4330 {pipelineType, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3u, 2u, false},
4331 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0u, 1u, false},
4332 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0u, 2u, false},
4333 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u, 2u, false},
4334 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 3u, 2u, false},
4335 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0u, 1u, false},
4336 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0u, 2u, false},
4337 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1u, 2u, false},
4338 {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 3u, 2u, false},
4339 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0u, 1u, false},
4340 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0u, 2u, false},
4341 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1u, 2u, false},
4342 {pipelineType, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 3u, 2u, false},
4343 {pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0u, 1u, false},
4344 {pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0u, 2u, false},
4345 {pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u, 2u, false},
4346 {pipelineType, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 3u, 2u, false}};
4347
4348 de::MovePtr<tcu::TestCaseGroup> pushDescriptorTests(new tcu::TestCaseGroup(testCtx, "push_descriptor"));
4349
4350 de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "graphics"));
4351 de::MovePtr<tcu::TestCaseGroup> computeTests(new tcu::TestCaseGroup(testCtx, "compute"));
4352
4353 for (uint32_t testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(params); testIdx++)
4354 {
4355 string testName;
4356 testName +=
4357 "binding" + de::toString(params[testIdx].binding) + "_numcalls" + de::toString(params[testIdx].numCalls);
4358 switch (params[testIdx].descriptorType)
4359 {
4360 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
4361 testName += "_uniform_buffer";
4362 if (params[testIdx].numCalls <= 2)
4363 graphicsTests->addChild(
4364 new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4365 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4366 computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), params[testIdx]));
4367 break;
4368
4369 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
4370 testName += "_storage_buffer";
4371 if (params[testIdx].numCalls <= 2)
4372 graphicsTests->addChild(
4373 new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4374 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4375 computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), params[testIdx]));
4376 break;
4377
4378 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
4379 testName += "_combined_image_sampler";
4380 graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4381 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4382 computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), params[testIdx]));
4383 break;
4384
4385 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
4386 testName += "_sampled_image";
4387 graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4388 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4389 computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), params[testIdx]));
4390 break;
4391
4392 case VK_DESCRIPTOR_TYPE_SAMPLER:
4393 testName += "_sampler";
4394 graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4395 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4396 computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), params[testIdx]));
4397 break;
4398
4399 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
4400 testName += "_storage_image";
4401 graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4402 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4403 computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), params[testIdx]));
4404 break;
4405
4406 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
4407 testName += "_uniform_texel_buffer";
4408 graphicsTests->addChild(
4409 new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4410 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4411 computeTests->addChild(
4412 new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), params[testIdx]));
4413 break;
4414
4415 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
4416 testName += "_storage_texel_buffer";
4417 graphicsTests->addChild(
4418 new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4419 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4420 computeTests->addChild(
4421 new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), params[testIdx]));
4422 break;
4423
4424 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
4425 // Input attachments are not supported with dynamic rendering
4426 if (!vk::isConstructionTypeShaderObject(pipelineType))
4427 {
4428 testName += "_input_attachment";
4429 graphicsTests->addChild(
4430 new PushDescriptorInputAttachmentGraphicsTest(testCtx, testName.c_str(), params[testIdx]));
4431 }
4432 break;
4433
4434 default:
4435 DE_FATAL("Unexpected descriptor type");
4436 break;
4437 }
4438 }
4439
4440 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4441 {
4442 TestParams testParams = {pipelineType, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0u, 1u, true};
4443 graphicsTests->addChild(
4444 new PushDescriptorTexelBufferGraphicsTest(testCtx, "maintenance5_uniform_texel_buffer", testParams));
4445 testParams.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
4446 graphicsTests->addChild(
4447 new PushDescriptorTexelBufferGraphicsTest(testCtx, "maintenance5_storage_texel_buffer", testParams));
4448 testParams.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
4449 graphicsTests->addChild(
4450 new PushDescriptorBufferGraphicsTest(testCtx, "maintenance5_uniform_buffer", testParams));
4451 }
4452
4453 pushDescriptorTests->addChild(graphicsTests.release());
4454 if (pipelineType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
4455 pushDescriptorTests->addChild(computeTests.release());
4456
4457 return pushDescriptorTests.release();
4458 }
4459
4460 } // namespace pipeline
4461 } // namespace vkt
4462