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