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