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