1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Valve Corporation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Tests vkCmdClearAttachments with unused attachments.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRenderPassMultipleSubpassesMultipleCommandBuffersTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include <sstream>
35 #include <functional>
36 #include <vector>
37 #include <string>
38 #include <memory>
39
40 namespace vkt
41 {
42 namespace renderpass
43 {
44
45 namespace
46 {
47
48 struct Vertex
49 {
50 tcu::Vec4 position;
51 tcu::Vec4 color;
52 };
53
54 template<typename T>
sizeInBytes(const std::vector<T> & vec)55 inline VkDeviceSize sizeInBytes(const std::vector<T>& vec)
56 {
57 return vec.size() * sizeof(vec[0]);
58 }
59
genVertices(void)60 std::vector<Vertex> genVertices (void)
61 {
62 std::vector<Vertex> vectorData;
63 const tcu::Vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
64 const tcu::Vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
65 const tcu::Vec4 blue = {0.0f, 0.0f, 1.0f, 1.0f};
66 const tcu::Vec4 yellow = {1.0f, 1.0f, 0.0f, 1.0f};
67
68 vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , red});
69 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , red});
70 vectorData.push_back({tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f) , red});
71 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , red});
72
73 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , green});
74 vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , green});
75 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , green});
76 vectorData.push_back({tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f) , green});
77
78 vectorData.push_back({tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f) , blue});
79 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , blue});
80 vectorData.push_back({tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f) , blue});
81 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , blue});
82
83 vectorData.push_back({tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f) , yellow});
84 vectorData.push_back({tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f) , yellow});
85 vectorData.push_back({tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f) , yellow});
86 vectorData.push_back({tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f) , yellow});
87
88 return vectorData;
89 }
90
91 class MultipleSubpassesMultipleCommandBuffersTestInstance : public TestInstance
92 {
93 public:
94 MultipleSubpassesMultipleCommandBuffersTestInstance (Context& context);
~MultipleSubpassesMultipleCommandBuffersTestInstance(void)95 virtual ~MultipleSubpassesMultipleCommandBuffersTestInstance (void) {}
96 virtual tcu::TestStatus iterate (void);
97 void createCommandBuffer (const DeviceInterface& vk,
98 VkDevice vkDevice);
99 private:
100 static constexpr deUint32 kImageWidth = 32;
101 static constexpr deUint32 kImageHeight = 32;
102 const tcu::UVec2 m_renderSize = { kImageWidth, kImageHeight };
103
104 VkClearValue m_initialColor;
105 VkClearValue m_clearColor;
106
107 Move<VkImage> m_colorImageA;
108 de::MovePtr<Allocation> m_colorImageAllocA;
109 Move<VkImageView> m_colorAttachmentViewA;
110
111 Move<VkImage> m_colorImageB;
112 de::MovePtr<Allocation> m_colorImageAllocB;
113 Move<VkImageView> m_colorAttachmentViewB;
114
115 Move<VkRenderPass> m_renderPass;
116 Move<VkFramebuffer> m_framebufferA;
117 Move<VkFramebuffer> m_framebufferB;
118 Move<VkShaderModule> m_vertexShaderModule;
119 Move<VkShaderModule> m_fragmentShaderModule;
120 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
121 Move<VkPipelineLayout> m_pipelineLayout;
122 Move<VkPipeline> m_graphicsPipeline0;
123 Move<VkPipeline> m_graphicsPipeline1;
124 Move<VkPipeline> m_graphicsPipeline2;
125 Move<VkCommandPool> m_cmdPool;
126 Move<VkCommandBuffer> m_cmdBufferA;
127 Move<VkCommandBuffer> m_cmdBufferB;
128
129 Move<VkBuffer> m_vertexBuffer;
130 de::MovePtr<Allocation> m_vertexBufferAlloc;
131 };
132
133 class MultipleSubpassesMultipleCommandBuffersTest : public vkt::TestCase
134 {
135 public:
MultipleSubpassesMultipleCommandBuffersTest(tcu::TestContext & testContext,const std::string & name,const std::string & description)136 MultipleSubpassesMultipleCommandBuffersTest (tcu::TestContext& testContext,
137 const std::string& name,
138 const std::string& description)
139 : vkt::TestCase(testContext, name, description)
140 {}
~MultipleSubpassesMultipleCommandBuffersTest(void)141 virtual ~MultipleSubpassesMultipleCommandBuffersTest (void) {}
142 virtual void initPrograms (SourceCollections& sourceCollections) const;
143 virtual TestInstance* createInstance (Context& context) const;
144 };
145
createInstance(Context & context) const146 TestInstance* MultipleSubpassesMultipleCommandBuffersTest::createInstance (Context& context) const
147 {
148 return new MultipleSubpassesMultipleCommandBuffersTestInstance(context);
149 }
150
initPrograms(SourceCollections & sourceCollections) const151 void MultipleSubpassesMultipleCommandBuffersTest::initPrograms (SourceCollections& sourceCollections) const
152 {
153 // Vertex shader.
154 sourceCollections.glslSources.add("vert_shader") << glu::VertexSource(
155 "#version 450\n"
156 "layout(location = 0) in vec4 position;\n"
157 "layout(location = 1) in vec4 color;\n"
158 "layout(location = 0) out vec4 vtxColor;\n"
159 "void main (void)\n"
160 "{\n"
161 "\tgl_Position = position;\n"
162 "\tvtxColor = color;\n"
163 "}\n");
164
165 // Fragment shader.
166 std::ostringstream fragmentSource;
167
168 fragmentSource << "#version 450\n"
169 << "layout(location = 0) in vec4 vtxColor;\n"
170 << "layout(location = 0) out vec4 fragColor;\n"
171 << "void main (void)\n"
172 << "{\n"
173 << "\tfragColor = vtxColor;\n"
174 << "}\n";
175
176 sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
177 }
178
179 // Create a render pass for this use case.
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice)180 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk, VkDevice vkDevice)
181 {
182 // Create attachment descriptions.
183 const VkAttachmentDescription attachmentDescription =
184 {
185 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
186 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
187 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
188 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
189 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
190 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
191 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
192 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
193 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
194 };
195
196 // Mark attachments as used or not depending on the test parameters.
197 const VkAttachmentReference attachmentReference
198 {
199 0u, // deUint32 attachment
200 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
201 };
202
203 // Create subpass description with the previous color attachment references.
204 std::vector<vk::VkSubpassDescription> subpassDescriptions;
205 {
206 const vk::VkSubpassDescription subpassDescription =
207 {
208 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
209 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
210 0u, // deUint32 inputAttachmentCount
211 DE_NULL, // const VkAttachmentReference* pInputAttachments
212 1u, // deUint32 colorAttachmentCount
213 &attachmentReference, // const VkAttachmentReference* pColorAttachments
214 DE_NULL, // const VkAttachmentReference* pResolveAttachments
215 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
216 0u, // deUint32 preserveAttachmentCount
217 DE_NULL // const deUint32* pPreserveAttachments
218 };
219 subpassDescriptions.emplace_back(subpassDescription);
220 subpassDescriptions.emplace_back(subpassDescription);
221 subpassDescriptions.emplace_back(subpassDescription);
222 }
223
224 std::vector<vk::VkSubpassDependency> subpassDependencies;
225 {
226 vk::VkSubpassDependency subpassDependency =
227 {
228 0u, // deUint32 srcSubpass
229 1u, // deUint32 dstSubpass
230 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
231 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask
232 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
233 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
234 0u // VkDependencyFlags dependencyFlags
235 };
236 subpassDependencies.emplace_back(subpassDependency);
237 subpassDependency.srcSubpass = 1u;
238 subpassDependency.dstSubpass = 2u;
239 subpassDependencies.emplace_back(subpassDependency);
240 }
241
242
243 const vk::VkRenderPassCreateInfo renderPassInfo =
244 {
245 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
246 DE_NULL, // const void* pNext
247 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
248 1u, // deUint32 attachmentCount
249 &attachmentDescription, // const VkAttachmentDescription* pAttachments
250 static_cast<deUint32>(subpassDescriptions.size()), // deUint32 subpassCount
251 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
252 static_cast<deUint32>(subpassDependencies.size()), // deUint32 dependencyCount
253 subpassDependencies.data(), // const VkSubpassDependency* pDependencies
254 };
255
256 return createRenderPass(vk, vkDevice, &renderPassInfo);
257 }
258
MultipleSubpassesMultipleCommandBuffersTestInstance(Context & context)259 MultipleSubpassesMultipleCommandBuffersTestInstance::MultipleSubpassesMultipleCommandBuffersTestInstance(Context& context)
260 : vkt::TestInstance(context)
261 {
262 // Initial color for all images.
263 m_initialColor.color.float32[0] = 0.0f;
264 m_initialColor.color.float32[1] = 0.0f;
265 m_initialColor.color.float32[2] = 0.0f;
266 m_initialColor.color.float32[3] = 1.0f;
267
268 // Clear color for used attachments.
269 m_clearColor.color.float32[0] = 1.0f;
270 m_clearColor.color.float32[1] = 1.0f;
271 m_clearColor.color.float32[2] = 1.0f;
272 m_clearColor.color.float32[3] = 1.0f;
273
274 const DeviceInterface& vk = m_context.getDeviceInterface();
275 const VkDevice vkDevice = m_context.getDevice();
276 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
277 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
278 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
279
280 // Create color images.
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 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
289 { kImageWidth, kImageHeight, 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
295 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
296 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
297 1u, // deUint32 queueFamilyIndexCount;
298 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
299 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
300 };
301 // Create, allocate and bind image memory.
302 m_colorImageA = createImage(vk, vkDevice, &colorImageParams);
303 m_colorImageAllocA = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageA), MemoryRequirement::Any);
304 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageA, m_colorImageAllocA->getMemory(), m_colorImageAllocA->getOffset()));
305
306 m_colorImageB = createImage(vk, vkDevice, &colorImageParams);
307 m_colorImageAllocB = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImageB), MemoryRequirement::Any);
308 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImageB, m_colorImageAllocB->getMemory(), m_colorImageAllocB->getOffset()));
309
310 // Create image view.
311 {
312 const VkImageViewCreateInfo colorAttachmentViewParamsA =
313 {
314 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
315 DE_NULL, // const void* pNext;
316 0u, // VkImageViewCreateFlags flags;
317 *m_colorImageA, // VkImage image;
318 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
319 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
320 componentMapping, // VkChannelMapping channels;
321 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
322 };
323 m_colorAttachmentViewA = createImageView(vk, vkDevice, &colorAttachmentViewParamsA);
324
325 const VkImageViewCreateInfo colorAttachmentViewParamsB =
326 {
327 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
328 DE_NULL, // const void* pNext;
329 0u, // VkImageViewCreateFlags flags;
330 *m_colorImageB, // VkImage image;
331 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
332 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
333 componentMapping, // VkChannelMapping channels;
334 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
335 };
336 m_colorAttachmentViewB = createImageView(vk, vkDevice, &colorAttachmentViewParamsB);
337 }
338
339 // Clear image and leave it prepared to be used as a color attachment.
340 {
341 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
342 Move<VkCommandPool> cmdPool;
343 Move<VkCommandBuffer> cmdBuffer;
344 std::vector<VkImageMemoryBarrier> preImageBarriers;
345 std::vector<VkImageMemoryBarrier> postImageBarriers;
346
347 // Create command pool and buffer
348 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
349 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
350
351 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
352 const VkImageMemoryBarrier preImageBarrierA =
353 {
354 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
355 DE_NULL, // const void* pNext;
356 0u, // VkAccessFlags srcAccessMask;
357 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
358 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
359 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
360 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
361 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
362 *m_colorImageA, // VkImage image;
363 { // VkImageSubresourceRange subresourceRange;
364 aspectMask, // VkImageAspect aspect;
365 0u, // deUint32 baseMipLevel;
366 1u, // deUint32 mipLevels;
367 0u, // deUint32 baseArraySlice;
368 1u // deUint32 arraySize;
369 }
370 };
371
372 preImageBarriers.emplace_back(preImageBarrierA);
373
374 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
375 const VkImageMemoryBarrier postImageBarrierA =
376 {
377 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
378 DE_NULL, // const void* pNext;
379 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
380 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
381 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
382 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
383 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
384 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
385 *m_colorImageA, // VkImage image;
386 { // VkImageSubresourceRange subresourceRange;
387 aspectMask, // VkImageAspect aspect;
388 0u, // deUint32 baseMipLevel;
389 1u, // deUint32 mipLevels;
390 0u, // deUint32 baseArraySlice;
391 1u // deUint32 arraySize;
392 }
393 };
394
395 postImageBarriers.emplace_back(postImageBarrierA);
396
397 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
398 const VkImageMemoryBarrier preImageBarrierB =
399 {
400 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
401 DE_NULL, // const void* pNext;
402 0u, // VkAccessFlags srcAccessMask;
403 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
404 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
405 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
406 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
407 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
408 *m_colorImageB, // VkImage image;
409 { // VkImageSubresourceRange subresourceRange;
410 aspectMask, // VkImageAspect aspect;
411 0u, // deUint32 baseMipLevel;
412 1u, // deUint32 mipLevels;
413 0u, // deUint32 baseArraySlice;
414 1u // deUint32 arraySize;
415 }
416 };
417
418 preImageBarriers.emplace_back(preImageBarrierB);
419
420 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
421 const VkImageMemoryBarrier postImageBarrierB =
422 {
423 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
424 DE_NULL, // const void* pNext;
425 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
426 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
427 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
428 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
429 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
430 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
431 *m_colorImageB, // VkImage image;
432 { // VkImageSubresourceRange subresourceRange;
433 aspectMask, // VkImageAspect aspect;
434 0u, // deUint32 baseMipLevel;
435 1u, // deUint32 mipLevels;
436 0u, // deUint32 baseArraySlice;
437 1u // deUint32 arraySize;
438 }
439 };
440
441 postImageBarriers.emplace_back(postImageBarrierB);
442
443 const VkImageSubresourceRange clearRange =
444 {
445 aspectMask, // VkImageAspectFlags aspectMask;
446 0u, // deUint32 baseMipLevel;
447 1u, // deUint32 levelCount;
448 0u, // deUint32 baseArrayLayer;
449 1u // deUint32 layerCount;
450 };
451
452 // Clear image and transfer layout.
453 beginCommandBuffer(vk, *cmdBuffer);
454 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, static_cast<deUint32>(preImageBarriers.size()), preImageBarriers.data());
455 vk.cmdClearColorImage(*cmdBuffer, *m_colorImageA, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
456 vk.cmdClearColorImage(*cmdBuffer, *m_colorImageB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
457 vk.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, static_cast<deUint32>(postImageBarriers.size()), postImageBarriers.data());
458 endCommandBuffer(vk, *cmdBuffer);
459
460 submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
461 }
462 }
463
464 // Create render pass.
465 m_renderPass = createRenderPass(vk, vkDevice);
466
467 // Create framebuffer
468 {
469 const VkImageView attachmentBindInfosA[1] =
470 {
471 *m_colorAttachmentViewA,
472 };
473 const VkFramebufferCreateInfo framebufferParamsA =
474 {
475 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
476 DE_NULL, // const void* pNext;
477 0u, // VkFramebufferCreateFlags flags;
478 *m_renderPass, // VkRenderPass renderPass;
479 1u, // deUint32 attachmentCount;
480 attachmentBindInfosA, // const VkImageView* pAttachments;
481 kImageWidth, // deUint32 width;
482 kImageHeight, // deUint32 height;
483 1u // deUint32 layers;
484 };
485
486 m_framebufferA = createFramebuffer(vk, vkDevice, &framebufferParamsA);
487
488 const VkImageView attachmentBindInfosB[1] =
489 {
490 *m_colorAttachmentViewB,
491 };
492 const VkFramebufferCreateInfo framebufferParamsB =
493 {
494 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
495 DE_NULL, // const void* pNext;
496 0u, // VkFramebufferCreateFlags flags;
497 *m_renderPass, // VkRenderPass renderPass;
498 1u, // deUint32 attachmentCount;
499 attachmentBindInfosB, // const VkImageView* pAttachments;
500 kImageWidth, // deUint32 width;
501 kImageHeight, // deUint32 height;
502 1u // deUint32 layers;
503 };
504
505 m_framebufferB = createFramebuffer(vk, vkDevice, &framebufferParamsB);
506 }
507
508 // Create pipeline layout.
509 {
510 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
511 {
512 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
513 DE_NULL, // const void* pNext
514 0u, // VkDescriptorSetLayoutCreateFlags flags
515 0u, // deUint32 bindingCount
516 DE_NULL // const VkDescriptorSetLayoutBinding* pBindings
517 };
518 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
519
520 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
521 {
522 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
523 DE_NULL, // const void* pNext;
524 0u, // VkPipelineLayoutCreateFlags flags;
525 1u, // deUint32 setLayoutCount;
526 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
527 0u, // deUint32 pushConstantRangeCount;
528 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
529 };
530
531 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
532 }
533
534 // Create Vertex buffer
535 {
536 const std::vector<Vertex> vertexValues = genVertices();
537 const VkDeviceSize vertexBufferSize = sizeInBytes(vertexValues);
538
539 const vk::VkBufferCreateInfo bufferCreateInfo =
540 {
541 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
542 DE_NULL, // const void* pNext
543 0u, // VkBufferCreateFlags flags
544 vertexBufferSize, // VkDeviceSize size
545 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
546 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
547 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
548 1u, // deUint32 queueFamilyIndexCount
549 &queueFamilyIndex // const deUint32* pQueueFamilyIndices
550 };
551
552 m_vertexBuffer = createBuffer(vk, vkDevice, &bufferCreateInfo);
553 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
554 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
555 // Load vertices into vertex buffer
556 deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertexValues.data(), static_cast<size_t>(vertexBufferSize));
557 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
558 }
559
560 // Vertex buffer description
561 const vk::VkVertexInputBindingDescription bindingDescription =
562 {
563 0u, // deUint32 binding
564 sizeof(Vertex), // deUint32 stride
565 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate
566 };
567
568 std::vector<vk::VkVertexInputAttributeDescription> attributeDescriptions;
569 {
570 vk::VkVertexInputAttributeDescription attributeDescriptionVertex =
571 {
572 0u, // deUint32 location
573 0u, // deUint32 binding
574 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
575 offsetof(Vertex, position) // deUint32 offset
576 };
577
578 vk::VkVertexInputAttributeDescription attributeDescriptionColor =
579 {
580 1u, // deUint32 location
581 0u, // deUint32 binding
582 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
583 offsetof(Vertex, color) // deUint32 offset
584 };
585 attributeDescriptions.emplace_back(attributeDescriptionVertex);
586 attributeDescriptions.emplace_back(attributeDescriptionColor);
587 }
588
589 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
590 {
591 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
592 DE_NULL, // const void* pNext
593 0u, // VkPipelineVertexInputStateCreateFlags flags
594 1u, // deUint32 vertexBindingDescriptionCount
595 &bindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
596 static_cast<deUint32>(attributeDescriptions.size()), // deUint32 vertexAttributeDescriptionCount
597 attributeDescriptions.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
598 };
599
600 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
601 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
602
603 // Create pipeline.
604 {
605 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
606 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
607
608 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
609 {
610 VK_FALSE, // VkBool32 blendEnable
611 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
612 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
613 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
614 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
615 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
616 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
617 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
618 | VK_COLOR_COMPONENT_G_BIT
619 | VK_COLOR_COMPONENT_B_BIT
620 | VK_COLOR_COMPONENT_A_BIT
621 };
622
623 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo =
624 {
625 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
626 DE_NULL, // const void* pNext
627 0u, // VkPipelineColorBlendStateCreateFlags flags
628 VK_FALSE, // VkBool32 logicOpEnable
629 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
630 1u, // deUint32 attachmentCount
631 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
632 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
633 };
634
635 m_graphicsPipeline0 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
636 vkDevice, // const VkDevice device
637 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
638 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
639 DE_NULL, // const VkShaderModule tessellationControlModule
640 DE_NULL, // const VkShaderModule tessellationEvalModule
641 DE_NULL, // const VkShaderModule geometryShaderModule
642 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
643 *m_renderPass, // const VkRenderPass renderPass
644 viewports, // const std::vector<VkViewport>& viewports
645 scissors, // const std::vector<VkRect2D>& scissors
646 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
647 0u, // const deUint32 subpass
648 0u, // const deUint32 patchControlPoints
649 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
650 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
651 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
652 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
653 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
654
655 m_graphicsPipeline1 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
656 vkDevice, // const VkDevice device
657 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
658 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
659 DE_NULL, // const VkShaderModule tessellationControlModule
660 DE_NULL, // const VkShaderModule tessellationEvalModule
661 DE_NULL, // const VkShaderModule geometryShaderModule
662 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
663 *m_renderPass, // const VkRenderPass renderPass
664 viewports, // const std::vector<VkViewport>& viewports
665 scissors, // const std::vector<VkRect2D>& scissors
666 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
667 1u, // const deUint32 subpass
668 0u, // const deUint32 patchControlPoints
669 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
670 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
671 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
672 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
673 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
674
675 m_graphicsPipeline2 = makeGraphicsPipeline(vk, // const DeviceInterface& vk
676 vkDevice, // const VkDevice device
677 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
678 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
679 DE_NULL, // const VkShaderModule tessellationControlModule
680 DE_NULL, // const VkShaderModule tessellationEvalModule
681 DE_NULL, // const VkShaderModule geometryShaderModule
682 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
683 *m_renderPass, // const VkRenderPass renderPass
684 viewports, // const std::vector<VkViewport>& viewports
685 scissors, // const std::vector<VkRect2D>& scissors
686 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
687 2u, // const deUint32 subpass
688 0u, // const deUint32 patchControlPoints
689 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
690 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
691 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
692 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
693 &colorBlendStateCreateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
694
695 }
696
697 // Create command pool
698 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
699
700 // Create command buffer
701 createCommandBuffer(vk, vkDevice);
702 }
703
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)704 void MultipleSubpassesMultipleCommandBuffersTestInstance::createCommandBuffer (const DeviceInterface& vk,
705 VkDevice vkDevice)
706 {
707 const VkRenderPassBeginInfo renderPassBeginInfoA =
708 {
709 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
710 DE_NULL, // const void* pNext;
711 *m_renderPass, // VkRenderPass renderPass;
712 *m_framebufferA, // VkFramebuffer framebuffer;
713 makeRect2D(m_renderSize), // VkRect2D renderArea;
714 0u, // uint32_t clearValueCount;
715 DE_NULL // const VkClearValue* pClearValues;
716 };
717 const VkRenderPassBeginInfo renderPassBeginInfoB =
718 {
719 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
720 DE_NULL, // const void* pNext;
721 *m_renderPass, // VkRenderPass renderPass;
722 *m_framebufferB, // VkFramebuffer framebuffer;
723 makeRect2D(m_renderSize), // VkRect2D renderArea;
724 0u, // uint32_t clearValueCount;
725 DE_NULL // const VkClearValue* pClearValues;
726 };
727
728 m_cmdBufferA = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
729 m_cmdBufferB = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
730
731 const VkClearRect clearRect =
732 {
733 { // VkRect2D rect;
734 { 0, 0, }, // VkOffset2D offset;
735 { kImageWidth, kImageHeight } // VkExtent2D extent;
736 },
737 0u, // uint32_t baseArrayLayer;
738 1u // uint32_t layerCount;
739 };
740
741 const VkClearAttachment clearAttachment =
742 {
743 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
744 0u, // uint32_t colorAttachment;
745 m_clearColor // VkClearValue clearValue;
746 };
747
748 VkDeviceSize vertexBufferOffset = 0u;
749
750 // Command Buffer A will set his own event but wait for the B's event before continuing to the next subpass.
751 beginCommandBuffer(vk, *m_cmdBufferA, 0u);
752 beginCommandBuffer(vk, *m_cmdBufferB, 0u);
753 vk.cmdBeginRenderPass(*m_cmdBufferA, &renderPassBeginInfoA, VK_SUBPASS_CONTENTS_INLINE);
754 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
755 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
756 vk.cmdClearAttachments(*m_cmdBufferA, 1u, &clearAttachment, 1u, &clearRect);
757
758 vk.cmdBeginRenderPass(*m_cmdBufferB, &renderPassBeginInfoB, VK_SUBPASS_CONTENTS_INLINE);
759 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline0);
760 vk.cmdClearAttachments(*m_cmdBufferB, 1u, &clearAttachment, 1u, &clearRect);
761 vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
762
763 vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
764 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
765 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
766 vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 0u, 0u);
767
768 vertexBufferOffset = 8 * sizeof(Vertex);
769 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline1);
770 vk.cmdBindVertexBuffers(*m_cmdBufferB, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
771 vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 0u, 0u);
772 vk.cmdNextSubpass(*m_cmdBufferB, VK_SUBPASS_CONTENTS_INLINE);
773
774 vertexBufferOffset = 0u;
775 vk.cmdNextSubpass(*m_cmdBufferA, VK_SUBPASS_CONTENTS_INLINE);
776 vk.cmdBindPipeline(*m_cmdBufferA, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
777 vk.cmdBindVertexBuffers(*m_cmdBufferA, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
778 vk.cmdDraw(*m_cmdBufferA, 4u, 1u, 4u, 0u);
779
780 vertexBufferOffset = 8 * sizeof(Vertex);
781 vk.cmdBindPipeline(*m_cmdBufferB, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline2);
782 vk.cmdDraw(*m_cmdBufferB, 4u, 1u, 4u, 0u);
783 vk.cmdEndRenderPass(*m_cmdBufferB);
784 vk.cmdEndRenderPass(*m_cmdBufferA);
785 endCommandBuffer(vk, *m_cmdBufferA);
786 endCommandBuffer(vk, *m_cmdBufferB);
787 }
788
iterate(void)789 tcu::TestStatus MultipleSubpassesMultipleCommandBuffersTestInstance::iterate (void)
790 {
791 const DeviceInterface& vk = m_context.getDeviceInterface();
792 const VkDevice vkDevice = m_context.getDevice();
793 const VkQueue queue = m_context.getUniversalQueue();
794 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
795 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
796
797 {
798 const Unique<VkFence> fence (createFence(vk, vkDevice));
799 std::vector<VkCommandBuffer> commandBuffers;
800 commandBuffers.emplace_back(m_cmdBufferA.get());
801 commandBuffers.emplace_back(m_cmdBufferB.get());
802
803 const VkSubmitInfo submitInfo =
804 {
805 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
806 DE_NULL, // const void* pNext;
807 0u, // deUint32 waitSemaphoreCount;
808 DE_NULL, // const VkSemaphore* pWaitSemaphores;
809 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
810 static_cast<deUint32>(commandBuffers.size()), // deUint32 commandBufferCount;
811 commandBuffers.data(), // const VkCommandBuffer* pCommandBuffers;
812 0u, // deUint32 signalSemaphoreCount;
813 DE_NULL, // const VkSemaphore* pSignalSemaphores;
814 };
815
816 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
817 VK_CHECK(vk.waitForFences(vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
818 }
819
820 {
821 // Colors to compare to.
822 const tcu::Vec4 red = {1.0f, 0.0f, 0.0f, 1.0f};
823 const tcu::Vec4 green = {0.0f, 1.0f, 0.0f, 1.0f};
824 const tcu::Vec4 blue = {0.0f, 0.0f, 1.0f, 1.0f};
825 const tcu::Vec4 yellow = {1.0f, 1.0f, 0.0f, 1.0f};
826
827 // Read result images.
828 de::MovePtr<tcu::TextureLevel> imagePixelsA = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageA, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
829 de::MovePtr<tcu::TextureLevel> imagePixelsB = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImageB, VK_FORMAT_R32G32B32A32_SFLOAT, m_renderSize);
830
831 // Verify pixel colors match.
832 const tcu::ConstPixelBufferAccess& imageAccessA = imagePixelsA->getAccess();
833 const tcu::ConstPixelBufferAccess& imageAccessB = imagePixelsB->getAccess();
834
835
836 tcu::TextureLevel referenceImageA(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
837 tcu::TextureLevel referenceImageB(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_renderSize.x(), m_renderSize.y());
838
839 tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), 0u, 0u,
840 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
841 red);
842 tcu::clear(tcu::getSubregion(referenceImageA.getAccess(), imageAccessA.getWidth() / 2, 0u,
843 imageAccessA.getWidth() / 2, imageAccessA.getHeight()),
844 green);
845
846 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageA.getAccess(), imageAccessA, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
847 TCU_FAIL("[A] Rendered image is not correct");
848
849 tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), 0u, 0u,
850 imageAccessB.getWidth() / 2, imageAccessB.getHeight()),
851 blue);
852 tcu::clear(tcu::getSubregion(referenceImageB.getAccess(), imageAccessB.getWidth() / 2, 0u,
853 imageAccessA.getWidth() / 2, imageAccessB.getHeight()),
854 yellow);
855
856 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceImageB.getAccess(), imageAccessB, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
857 TCU_FAIL("[B] Rendered image is not correct");
858
859 }
860
861 return tcu::TestStatus::pass("Pass");
862 }
863 } // anonymous
864
createRenderPassMultipleSubpassesMultipleCommandBuffersTests(tcu::TestContext & testCtx)865 tcu::TestCaseGroup* createRenderPassMultipleSubpassesMultipleCommandBuffersTests (tcu::TestContext& testCtx)
866 {
867 de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "multiple_subpasses_multiple_command_buffers", "Multiple subpasses multiple command buffers"));
868
869 testGroup->addChild(new MultipleSubpassesMultipleCommandBuffersTest(testCtx, "test", ""));
870
871 return testGroup.release();
872 }
873
874 } // renderpass
875 } // vkt
876