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