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