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