1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief RenderPass tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassTests.hpp"
25
26 #include "vktRenderPassMultisampleTests.hpp"
27 #include "vktRenderPassMultisampleResolveTests.hpp"
28
29 #include "vktTestCaseUtil.hpp"
30 #include "vktTestGroupUtil.hpp"
31
32 #include "vkDefs.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkRef.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkStrUtil.hpp"
42 #include "vkTypeUtil.hpp"
43
44 #include "tcuFloat.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
51
52 #include "deRandom.hpp"
53 #include "deSTLUtil.hpp"
54 #include "deSharedPtr.hpp"
55 #include "deStringUtil.hpp"
56 #include "deUniquePtr.hpp"
57
58 #include <limits>
59 #include <set>
60 #include <string>
61 #include <vector>
62
63 using namespace vk;
64
65 using tcu::BVec4;
66 using tcu::IVec2;
67 using tcu::IVec4;
68 using tcu::UVec2;
69 using tcu::UVec4;
70 using tcu::Vec2;
71 using tcu::Vec4;
72
73 using tcu::Maybe;
74 using tcu::just;
75 using tcu::nothing;
76
77 using tcu::ConstPixelBufferAccess;
78 using tcu::PixelBufferAccess;
79
80 using tcu::TestLog;
81
82 using de::UniquePtr;
83
84 using std::pair;
85 using std::set;
86 using std::string;
87 using std::vector;
88
89 namespace vkt
90 {
91 namespace
92 {
93 enum AllocationKind
94 {
95 ALLOCATION_KIND_SUBALLOCATED,
96 ALLOCATION_KIND_DEDICATED,
97 };
98
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)99 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
100 const DeviceInterface& vkd,
101 const VkPhysicalDevice& physDevice,
102 const VkDevice device,
103 const VkBuffer& buffer,
104 const MemoryRequirement requirement,
105 Allocator& allocator,
106 AllocationKind allocationKind)
107 {
108 switch (allocationKind)
109 {
110 case ALLOCATION_KIND_SUBALLOCATED:
111 {
112 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
113
114 return allocator.allocate(memoryRequirements, requirement);
115 }
116
117 case ALLOCATION_KIND_DEDICATED:
118 {
119 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
120 }
121
122 default:
123 {
124 TCU_THROW(InternalError, "Invalid allocation kind");
125 }
126 }
127 }
128
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)129 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
130 const DeviceInterface& vkd,
131 const VkPhysicalDevice& physDevice,
132 const VkDevice device,
133 const VkImage& image,
134 const MemoryRequirement requirement,
135 Allocator& allocator,
136 AllocationKind allocationKind)
137 {
138 switch (allocationKind)
139 {
140 case ALLOCATION_KIND_SUBALLOCATED:
141 {
142 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
143
144 return allocator.allocate(memoryRequirements, requirement);
145 }
146
147 case ALLOCATION_KIND_DEDICATED:
148 {
149 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
150 }
151
152 default:
153 {
154 TCU_THROW(InternalError, "Invalid allocation kind");
155 }
156 }
157 }
158
159 enum BoolOp
160 {
161 BOOLOP_AND,
162 BOOLOP_OR,
163 BOOLOP_EQ,
164 BOOLOP_NEQ
165 };
166
boolOpToString(BoolOp op)167 const char* boolOpToString (BoolOp op)
168 {
169 switch (op)
170 {
171 case BOOLOP_OR:
172 return "||";
173
174 case BOOLOP_AND:
175 return "&&";
176
177 case BOOLOP_EQ:
178 return "==";
179
180 case BOOLOP_NEQ:
181 return "!=";
182
183 default:
184 DE_FATAL("Unknown boolean operation.");
185 return DE_NULL;
186 }
187 }
188
performBoolOp(BoolOp op,bool a,bool b)189 bool performBoolOp (BoolOp op, bool a, bool b)
190 {
191 switch (op)
192 {
193 case BOOLOP_OR:
194 return a || b;
195
196 case BOOLOP_AND:
197 return a && b;
198
199 case BOOLOP_EQ:
200 return a == b;
201
202 case BOOLOP_NEQ:
203 return a != b;
204
205 default:
206 DE_FATAL("Unknown boolean operation.");
207 return false;
208 }
209 }
210
boolOpFromIndex(size_t index)211 BoolOp boolOpFromIndex (size_t index)
212 {
213 const BoolOp ops[] =
214 {
215 BOOLOP_OR,
216 BOOLOP_AND,
217 BOOLOP_EQ,
218 BOOLOP_NEQ
219 };
220
221 return ops[index % DE_LENGTH_OF_ARRAY(ops)];
222 }
223
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkFramebufferCreateFlags pCreateInfo_flags,VkRenderPass pCreateInfo_renderPass,deUint32 pCreateInfo_attachmentCount,const VkImageView * pCreateInfo_pAttachments,deUint32 pCreateInfo_width,deUint32 pCreateInfo_height,deUint32 pCreateInfo_layers)224 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
225 VkDevice device,
226 VkFramebufferCreateFlags pCreateInfo_flags,
227 VkRenderPass pCreateInfo_renderPass,
228 deUint32 pCreateInfo_attachmentCount,
229 const VkImageView* pCreateInfo_pAttachments,
230 deUint32 pCreateInfo_width,
231 deUint32 pCreateInfo_height,
232 deUint32 pCreateInfo_layers)
233 {
234 const VkFramebufferCreateInfo pCreateInfo =
235 {
236 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
237 DE_NULL,
238 pCreateInfo_flags,
239 pCreateInfo_renderPass,
240 pCreateInfo_attachmentCount,
241 pCreateInfo_pAttachments,
242 pCreateInfo_width,
243 pCreateInfo_height,
244 pCreateInfo_layers,
245 };
246 return createFramebuffer(vk, device, &pCreateInfo);
247 }
248
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags pCreateInfo_flags,VkImageType pCreateInfo_imageType,VkFormat pCreateInfo_format,VkExtent3D pCreateInfo_extent,deUint32 pCreateInfo_mipLevels,deUint32 pCreateInfo_arrayLayers,VkSampleCountFlagBits pCreateInfo_samples,VkImageTiling pCreateInfo_tiling,VkImageUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,deUint32 pCreateInfo_queueFamilyCount,const deUint32 * pCreateInfo_pQueueFamilyIndices,VkImageLayout pCreateInfo_initialLayout)249 Move<VkImage> createImage (const DeviceInterface& vk,
250 VkDevice device,
251 VkImageCreateFlags pCreateInfo_flags,
252 VkImageType pCreateInfo_imageType,
253 VkFormat pCreateInfo_format,
254 VkExtent3D pCreateInfo_extent,
255 deUint32 pCreateInfo_mipLevels,
256 deUint32 pCreateInfo_arrayLayers,
257 VkSampleCountFlagBits pCreateInfo_samples,
258 VkImageTiling pCreateInfo_tiling,
259 VkImageUsageFlags pCreateInfo_usage,
260 VkSharingMode pCreateInfo_sharingMode,
261 deUint32 pCreateInfo_queueFamilyCount,
262 const deUint32* pCreateInfo_pQueueFamilyIndices,
263 VkImageLayout pCreateInfo_initialLayout)
264 {
265 const VkImageCreateInfo pCreateInfo =
266 {
267 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
268 DE_NULL,
269 pCreateInfo_flags,
270 pCreateInfo_imageType,
271 pCreateInfo_format,
272 pCreateInfo_extent,
273 pCreateInfo_mipLevels,
274 pCreateInfo_arrayLayers,
275 pCreateInfo_samples,
276 pCreateInfo_tiling,
277 pCreateInfo_usage,
278 pCreateInfo_sharingMode,
279 pCreateInfo_queueFamilyCount,
280 pCreateInfo_pQueueFamilyIndices,
281 pCreateInfo_initialLayout
282 };
283 return createImage(vk, device, &pCreateInfo);
284 }
285
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)286 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
287 {
288 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
289 }
290
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)291 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
292 {
293 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
294 }
295
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags pCreateInfo_flags,VkImage pCreateInfo_image,VkImageViewType pCreateInfo_viewType,VkFormat pCreateInfo_format,VkComponentMapping pCreateInfo_components,VkImageSubresourceRange pCreateInfo_subresourceRange)296 Move<VkImageView> createImageView (const DeviceInterface& vk,
297 VkDevice device,
298 VkImageViewCreateFlags pCreateInfo_flags,
299 VkImage pCreateInfo_image,
300 VkImageViewType pCreateInfo_viewType,
301 VkFormat pCreateInfo_format,
302 VkComponentMapping pCreateInfo_components,
303 VkImageSubresourceRange pCreateInfo_subresourceRange)
304 {
305 const VkImageViewCreateInfo pCreateInfo =
306 {
307 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
308 DE_NULL,
309 pCreateInfo_flags,
310 pCreateInfo_image,
311 pCreateInfo_viewType,
312 pCreateInfo_format,
313 pCreateInfo_components,
314 pCreateInfo_subresourceRange,
315 };
316 return createImageView(vk, device, &pCreateInfo);
317 }
318
createBuffer(const DeviceInterface & vk,VkDevice device,VkBufferCreateFlags pCreateInfo_flags,VkDeviceSize pCreateInfo_size,VkBufferUsageFlags pCreateInfo_usage,VkSharingMode pCreateInfo_sharingMode,deUint32 pCreateInfo_queueFamilyCount,const deUint32 * pCreateInfo_pQueueFamilyIndices)319 Move<VkBuffer> createBuffer (const DeviceInterface& vk,
320 VkDevice device,
321 VkBufferCreateFlags pCreateInfo_flags,
322 VkDeviceSize pCreateInfo_size,
323 VkBufferUsageFlags pCreateInfo_usage,
324 VkSharingMode pCreateInfo_sharingMode,
325 deUint32 pCreateInfo_queueFamilyCount,
326 const deUint32* pCreateInfo_pQueueFamilyIndices)
327 {
328 const VkBufferCreateInfo pCreateInfo =
329 {
330 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
331 DE_NULL,
332 pCreateInfo_flags,
333 pCreateInfo_size,
334 pCreateInfo_usage,
335 pCreateInfo_sharingMode,
336 pCreateInfo_queueFamilyCount,
337 pCreateInfo_pQueueFamilyIndices,
338 };
339 return createBuffer(vk, device, &pCreateInfo);
340 }
341
cmdBeginRenderPass(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkRenderPass pRenderPassBegin_renderPass,VkFramebuffer pRenderPassBegin_framebuffer,VkRect2D pRenderPassBegin_renderArea,deUint32 pRenderPassBegin_clearValueCount,const VkClearValue * pRenderPassBegin_pAttachmentClearValues,VkSubpassContents contents)342 void cmdBeginRenderPass (const DeviceInterface& vk,
343 VkCommandBuffer cmdBuffer,
344 VkRenderPass pRenderPassBegin_renderPass,
345 VkFramebuffer pRenderPassBegin_framebuffer,
346 VkRect2D pRenderPassBegin_renderArea,
347 deUint32 pRenderPassBegin_clearValueCount,
348 const VkClearValue* pRenderPassBegin_pAttachmentClearValues,
349 VkSubpassContents contents)
350 {
351 const VkRenderPassBeginInfo pRenderPassBegin =
352 {
353 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
354 DE_NULL,
355 pRenderPassBegin_renderPass,
356 pRenderPassBegin_framebuffer,
357 pRenderPassBegin_renderArea,
358 pRenderPassBegin_clearValueCount,
359 pRenderPassBegin_pAttachmentClearValues,
360 };
361 vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
362 }
363
beginCommandBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer,VkCommandBufferUsageFlags pBeginInfo_flags,VkRenderPass pInheritanceInfo_renderPass,deUint32 pInheritanceInfo_subpass,VkFramebuffer pInheritanceInfo_framebuffer,VkBool32 pInheritanceInfo_occlusionQueryEnable,VkQueryControlFlags pInheritanceInfo_queryFlags,VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)364 void beginCommandBuffer (const DeviceInterface& vk,
365 VkCommandBuffer cmdBuffer,
366 VkCommandBufferUsageFlags pBeginInfo_flags,
367 VkRenderPass pInheritanceInfo_renderPass,
368 deUint32 pInheritanceInfo_subpass,
369 VkFramebuffer pInheritanceInfo_framebuffer,
370 VkBool32 pInheritanceInfo_occlusionQueryEnable,
371 VkQueryControlFlags pInheritanceInfo_queryFlags,
372 VkQueryPipelineStatisticFlags pInheritanceInfo_pipelineStatistics)
373 {
374 const VkCommandBufferInheritanceInfo pInheritanceInfo =
375 {
376 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
377 DE_NULL,
378 pInheritanceInfo_renderPass,
379 pInheritanceInfo_subpass,
380 pInheritanceInfo_framebuffer,
381 pInheritanceInfo_occlusionQueryEnable,
382 pInheritanceInfo_queryFlags,
383 pInheritanceInfo_pipelineStatistics,
384 };
385 const VkCommandBufferBeginInfo pBeginInfo =
386 {
387 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
388 DE_NULL,
389 pBeginInfo_flags,
390 &pInheritanceInfo,
391 };
392 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
393 }
394
endCommandBuffer(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)395 void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
396 {
397 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
398 }
399
queueSubmit(const DeviceInterface & vk,VkQueue queue,deUint32 cmdBufferCount,const VkCommandBuffer * pCmdBuffers,VkFence fence)400 void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
401 {
402 const VkSubmitInfo submitInfo =
403 {
404 VK_STRUCTURE_TYPE_SUBMIT_INFO,
405 DE_NULL,
406 0u, // waitSemaphoreCount
407 (const VkSemaphore*)DE_NULL, // pWaitSemaphores
408 (const VkPipelineStageFlags*)DE_NULL,
409 cmdBufferCount, // commandBufferCount
410 pCmdBuffers,
411 0u, // signalSemaphoreCount
412 (const VkSemaphore*)DE_NULL, // pSignalSemaphores
413 };
414 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
415 }
416
waitForFences(const DeviceInterface & vk,VkDevice device,deUint32 fenceCount,const VkFence * pFences,VkBool32 waitAll,deUint64 timeout)417 void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
418 {
419 VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
420 }
421
getImageAspectFlags(VkFormat vkFormat)422 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
423 {
424 const tcu::TextureFormat format = mapVkFormat(vkFormat);
425
426 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
427
428 switch (format.order)
429 {
430 case tcu::TextureFormat::DS:
431 return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
432
433 case tcu::TextureFormat::D:
434 return VK_IMAGE_ASPECT_DEPTH_BIT;
435
436 case tcu::TextureFormat::S:
437 return VK_IMAGE_ASPECT_STENCIL_BIT;
438
439 default:
440 return VK_IMAGE_ASPECT_COLOR_BIT;
441 }
442 }
443
getAllMemoryReadFlags(void)444 VkAccessFlags getAllMemoryReadFlags (void)
445 {
446 return VK_ACCESS_TRANSFER_READ_BIT
447 | VK_ACCESS_UNIFORM_READ_BIT
448 | VK_ACCESS_HOST_READ_BIT
449 | VK_ACCESS_INDEX_READ_BIT
450 | VK_ACCESS_SHADER_READ_BIT
451 | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
452 | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
453 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
454 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
455 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
456 }
457
getAllMemoryWriteFlags(void)458 VkAccessFlags getAllMemoryWriteFlags (void)
459 {
460 return VK_ACCESS_TRANSFER_WRITE_BIT
461 | VK_ACCESS_HOST_WRITE_BIT
462 | VK_ACCESS_SHADER_WRITE_BIT
463 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
464 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
465 }
466
getMemoryFlagsForLayout(const VkImageLayout layout)467 VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
468 {
469 switch (layout)
470 {
471 case VK_IMAGE_LAYOUT_GENERAL: return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
472 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
473 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
474 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
475 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: return VK_ACCESS_SHADER_READ_BIT;
476 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VK_ACCESS_TRANSFER_READ_BIT;
477 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VK_ACCESS_TRANSFER_WRITE_BIT;
478 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
479 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR: return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
480 default:
481 return (VkAccessFlags)0;
482 }
483 }
484
getAllPipelineStageFlags(void)485 VkPipelineStageFlags getAllPipelineStageFlags (void)
486 {
487 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
488 | VK_PIPELINE_STAGE_TRANSFER_BIT
489 | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
490 | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
491 | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
492 | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
493 | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
494 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
495 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
496 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
497 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
498 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
499 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
500 }
501
502 class AttachmentReference
503 {
504 public:
AttachmentReference(deUint32 attachment,VkImageLayout layout)505 AttachmentReference (deUint32 attachment,
506 VkImageLayout layout)
507 : m_attachment (attachment)
508 , m_layout (layout)
509 {
510 }
511
getAttachment(void) const512 deUint32 getAttachment (void) const { return m_attachment; }
getImageLayout(void) const513 VkImageLayout getImageLayout (void) const { return m_layout; }
514
515 private:
516 deUint32 m_attachment;
517 VkImageLayout m_layout;
518 };
519
520 class Subpass
521 {
522 public:
Subpass(VkPipelineBindPoint pipelineBindPoint,VkSubpassDescriptionFlags flags,const vector<AttachmentReference> & inputAttachments,const vector<AttachmentReference> & colorAttachments,const vector<AttachmentReference> & resolveAttachments,AttachmentReference depthStencilAttachment,const vector<deUint32> & preserveAttachments)523 Subpass (VkPipelineBindPoint pipelineBindPoint,
524 VkSubpassDescriptionFlags flags,
525 const vector<AttachmentReference>& inputAttachments,
526 const vector<AttachmentReference>& colorAttachments,
527 const vector<AttachmentReference>& resolveAttachments,
528 AttachmentReference depthStencilAttachment,
529 const vector<deUint32>& preserveAttachments)
530 : m_pipelineBindPoint (pipelineBindPoint)
531 , m_flags (flags)
532 , m_inputAttachments (inputAttachments)
533 , m_colorAttachments (colorAttachments)
534 , m_resolveAttachments (resolveAttachments)
535 , m_depthStencilAttachment (depthStencilAttachment)
536 , m_preserveAttachments (preserveAttachments)
537 {
538 }
539
getPipelineBindPoint(void) const540 VkPipelineBindPoint getPipelineBindPoint (void) const { return m_pipelineBindPoint; }
getFlags(void) const541 VkSubpassDescriptionFlags getFlags (void) const { return m_flags; }
getInputAttachments(void) const542 const vector<AttachmentReference>& getInputAttachments (void) const { return m_inputAttachments; }
getColorAttachments(void) const543 const vector<AttachmentReference>& getColorAttachments (void) const { return m_colorAttachments; }
getResolveAttachments(void) const544 const vector<AttachmentReference>& getResolveAttachments (void) const { return m_resolveAttachments; }
getDepthStencilAttachment(void) const545 const AttachmentReference& getDepthStencilAttachment (void) const { return m_depthStencilAttachment; }
getPreserveAttachments(void) const546 const vector<deUint32>& getPreserveAttachments (void) const { return m_preserveAttachments; }
547
548 private:
549 VkPipelineBindPoint m_pipelineBindPoint;
550 VkSubpassDescriptionFlags m_flags;
551
552 vector<AttachmentReference> m_inputAttachments;
553 vector<AttachmentReference> m_colorAttachments;
554 vector<AttachmentReference> m_resolveAttachments;
555 AttachmentReference m_depthStencilAttachment;
556
557 vector<deUint32> m_preserveAttachments;
558 };
559
560 class SubpassDependency
561 {
562 public:
SubpassDependency(deUint32 srcPass,deUint32 dstPass,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags outputMask,VkAccessFlags inputMask,VkDependencyFlags flags)563 SubpassDependency (deUint32 srcPass,
564 deUint32 dstPass,
565
566 VkPipelineStageFlags srcStageMask,
567 VkPipelineStageFlags dstStageMask,
568
569 VkAccessFlags outputMask,
570 VkAccessFlags inputMask,
571
572 VkDependencyFlags flags)
573 : m_srcPass (srcPass)
574 , m_dstPass (dstPass)
575
576 , m_srcStageMask (srcStageMask)
577 , m_dstStageMask (dstStageMask)
578
579 , m_outputMask (outputMask)
580 , m_inputMask (inputMask)
581 , m_flags (flags)
582 {
583 }
584
getSrcPass(void) const585 deUint32 getSrcPass (void) const { return m_srcPass; }
getDstPass(void) const586 deUint32 getDstPass (void) const { return m_dstPass; }
587
getSrcStageMask(void) const588 VkPipelineStageFlags getSrcStageMask (void) const { return m_srcStageMask; }
getDstStageMask(void) const589 VkPipelineStageFlags getDstStageMask (void) const { return m_dstStageMask; }
590
getOutputMask(void) const591 VkAccessFlags getOutputMask (void) const { return m_outputMask; }
getInputMask(void) const592 VkAccessFlags getInputMask (void) const { return m_inputMask; }
593
getFlags(void) const594 VkDependencyFlags getFlags (void) const { return m_flags; }
595
596 private:
597 deUint32 m_srcPass;
598 deUint32 m_dstPass;
599
600 VkPipelineStageFlags m_srcStageMask;
601 VkPipelineStageFlags m_dstStageMask;
602
603 VkAccessFlags m_outputMask;
604 VkAccessFlags m_inputMask;
605 VkDependencyFlags m_flags;
606 };
607
608 class Attachment
609 {
610 public:
Attachment(VkFormat format,VkSampleCountFlagBits samples,VkAttachmentLoadOp loadOp,VkAttachmentStoreOp storeOp,VkAttachmentLoadOp stencilLoadOp,VkAttachmentStoreOp stencilStoreOp,VkImageLayout initialLayout,VkImageLayout finalLayout)611 Attachment (VkFormat format,
612 VkSampleCountFlagBits samples,
613
614 VkAttachmentLoadOp loadOp,
615 VkAttachmentStoreOp storeOp,
616
617 VkAttachmentLoadOp stencilLoadOp,
618 VkAttachmentStoreOp stencilStoreOp,
619
620 VkImageLayout initialLayout,
621 VkImageLayout finalLayout)
622 : m_format (format)
623 , m_samples (samples)
624
625 , m_loadOp (loadOp)
626 , m_storeOp (storeOp)
627
628 , m_stencilLoadOp (stencilLoadOp)
629 , m_stencilStoreOp (stencilStoreOp)
630
631 , m_initialLayout (initialLayout)
632 , m_finalLayout (finalLayout)
633 {
634 }
635
getFormat(void) const636 VkFormat getFormat (void) const { return m_format; }
getSamples(void) const637 VkSampleCountFlagBits getSamples (void) const { return m_samples; }
638
getLoadOp(void) const639 VkAttachmentLoadOp getLoadOp (void) const { return m_loadOp; }
getStoreOp(void) const640 VkAttachmentStoreOp getStoreOp (void) const { return m_storeOp; }
641
642
getStencilLoadOp(void) const643 VkAttachmentLoadOp getStencilLoadOp (void) const { return m_stencilLoadOp; }
getStencilStoreOp(void) const644 VkAttachmentStoreOp getStencilStoreOp (void) const { return m_stencilStoreOp; }
645
getInitialLayout(void) const646 VkImageLayout getInitialLayout (void) const { return m_initialLayout; }
getFinalLayout(void) const647 VkImageLayout getFinalLayout (void) const { return m_finalLayout; }
648
649 private:
650 VkFormat m_format;
651 VkSampleCountFlagBits m_samples;
652
653 VkAttachmentLoadOp m_loadOp;
654 VkAttachmentStoreOp m_storeOp;
655
656 VkAttachmentLoadOp m_stencilLoadOp;
657 VkAttachmentStoreOp m_stencilStoreOp;
658
659 VkImageLayout m_initialLayout;
660 VkImageLayout m_finalLayout;
661 };
662
663 class RenderPass
664 {
665 public:
RenderPass(const vector<Attachment> & attachments,const vector<Subpass> & subpasses,const vector<SubpassDependency> & dependencies,const vector<VkInputAttachmentAspectReferenceKHR> inputAspects=vector<VkInputAttachmentAspectReferenceKHR> ())666 RenderPass (const vector<Attachment>& attachments,
667 const vector<Subpass>& subpasses,
668 const vector<SubpassDependency>& dependencies,
669 const vector<VkInputAttachmentAspectReferenceKHR> inputAspects = vector<VkInputAttachmentAspectReferenceKHR>())
670 : m_attachments (attachments)
671 , m_subpasses (subpasses)
672 , m_dependencies (dependencies)
673 , m_inputAspects (inputAspects)
674 {
675 }
676
getAttachments(void) const677 const vector<Attachment>& getAttachments (void) const { return m_attachments; }
getSubpasses(void) const678 const vector<Subpass>& getSubpasses (void) const { return m_subpasses; }
getDependencies(void) const679 const vector<SubpassDependency>& getDependencies (void) const { return m_dependencies; }
getInputAspects(void) const680 const vector<VkInputAttachmentAspectReferenceKHR> getInputAspects (void) const { return m_inputAspects; }
681
682 private:
683 const vector<Attachment> m_attachments;
684 const vector<Subpass> m_subpasses;
685 const vector<SubpassDependency> m_dependencies;
686 const vector<VkInputAttachmentAspectReferenceKHR> m_inputAspects;
687 };
688
689 struct TestConfig
690 {
691 enum RenderTypes
692 {
693 RENDERTYPES_NONE = 0,
694 RENDERTYPES_CLEAR = (1<<1),
695 RENDERTYPES_DRAW = (1<<2)
696 };
697
698 enum CommandBufferTypes
699 {
700 COMMANDBUFFERTYPES_INLINE = (1<<0),
701 COMMANDBUFFERTYPES_SECONDARY = (1<<1)
702 };
703
704 enum ImageMemory
705 {
706 IMAGEMEMORY_STRICT = (1<<0),
707 IMAGEMEMORY_LAZY = (1<<1)
708 };
709
TestConfigvkt::__anon96ae15a30111::TestConfig710 TestConfig (const RenderPass& renderPass_,
711 RenderTypes renderTypes_,
712 CommandBufferTypes commandBufferTypes_,
713 ImageMemory imageMemory_,
714 const UVec2& targetSize_,
715 const UVec2& renderPos_,
716 const UVec2& renderSize_,
717 deUint32 seed_,
718 AllocationKind allocationKind_)
719 : renderPass (renderPass_)
720 , renderTypes (renderTypes_)
721 , commandBufferTypes (commandBufferTypes_)
722 , imageMemory (imageMemory_)
723 , targetSize (targetSize_)
724 , renderPos (renderPos_)
725 , renderSize (renderSize_)
726 , seed (seed_)
727 , allocationKind (allocationKind_)
728 {
729 }
730
731 RenderPass renderPass;
732 RenderTypes renderTypes;
733 CommandBufferTypes commandBufferTypes;
734 ImageMemory imageMemory;
735 UVec2 targetSize;
736 UVec2 renderPos;
737 UVec2 renderSize;
738 deUint32 seed;
739 AllocationKind allocationKind;
740 };
741
operator |(TestConfig::RenderTypes a,TestConfig::RenderTypes b)742 TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
743 {
744 return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
745 }
746
operator |(TestConfig::CommandBufferTypes a,TestConfig::CommandBufferTypes b)747 TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
748 {
749 return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
750 }
751
operator |(TestConfig::ImageMemory a,TestConfig::ImageMemory b)752 TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
753 {
754 return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
755 }
756
logRenderPassInfo(TestLog & log,const RenderPass & renderPass)757 void logRenderPassInfo (TestLog& log,
758 const RenderPass& renderPass)
759 {
760 const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");
761
762 {
763 const tcu::ScopedLogSection attachmentsSection (log, "Attachments", "Attachments");
764 const vector<Attachment>& attachments = renderPass.getAttachments();
765
766 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
767 {
768 const tcu::ScopedLogSection attachmentSection (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
769 const Attachment& attachment = attachments[attachmentNdx];
770
771 log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
772 log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;
773
774 log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
775 log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;
776
777 log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
778 log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;
779
780 log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
781 log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
782 }
783 }
784
785 if (!renderPass.getInputAspects().empty())
786 {
787 const tcu::ScopedLogSection inputAspectSection (log, "InputAspects", "InputAspects");
788
789 for (size_t aspectNdx = 0; aspectNdx < renderPass.getInputAspects().size(); aspectNdx++)
790 {
791 const VkInputAttachmentAspectReferenceKHR& inputAspect (renderPass.getInputAspects()[aspectNdx]);
792
793 log << TestLog::Message << "Subpass: " << inputAspect.subpass << TestLog::EndMessage;
794 log << TestLog::Message << "InputAttachmentIndex: " << inputAspect.inputAttachmentIndex << TestLog::EndMessage;
795 log << TestLog::Message << "AspectFlags: " << getImageAspectFlagsStr(inputAspect.aspectMask) << TestLog::EndMessage;
796 }
797 }
798
799 {
800 const tcu::ScopedLogSection subpassesSection (log, "Subpasses", "Subpasses");
801 const vector<Subpass>& subpasses = renderPass.getSubpasses();
802
803 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
804 {
805 const tcu::ScopedLogSection subpassSection (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
806 const Subpass& subpass = subpasses[subpassNdx];
807
808 const vector<AttachmentReference>& inputAttachments = subpass.getInputAttachments();
809 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
810 const vector<AttachmentReference>& resolveAttachments = subpass.getResolveAttachments();
811 const vector<deUint32>& preserveAttachments = subpass.getPreserveAttachments();
812
813 if (!inputAttachments.empty())
814 {
815 const tcu::ScopedLogSection inputAttachmentsSection (log, "Inputs", "Inputs");
816
817 for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
818 {
819 const tcu::ScopedLogSection inputAttachmentSection (log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
820 const AttachmentReference& inputAttachment = inputAttachments[inputNdx];
821
822 log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
823 log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
824 }
825 }
826
827 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
828 {
829 const tcu::ScopedLogSection depthStencilAttachmentSection (log, "DepthStencil", "DepthStencil");
830 const AttachmentReference& depthStencilAttachment = subpass.getDepthStencilAttachment();
831
832 log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
833 log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
834 }
835
836 if (!colorAttachments.empty())
837 {
838 const tcu::ScopedLogSection colorAttachmentsSection (log, "Colors", "Colors");
839
840 for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
841 {
842 const tcu::ScopedLogSection colorAttachmentSection (log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
843 const AttachmentReference& colorAttachment = colorAttachments[colorNdx];
844
845 log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
846 log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
847 }
848 }
849
850 if (!resolveAttachments.empty())
851 {
852 const tcu::ScopedLogSection resolveAttachmentsSection (log, "Resolves", "Resolves");
853
854 for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
855 {
856 const tcu::ScopedLogSection resolveAttachmentSection (log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
857 const AttachmentReference& resolveAttachment = resolveAttachments[resolveNdx];
858
859 log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
860 log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
861 }
862 }
863
864 if (!preserveAttachments.empty())
865 {
866 const tcu::ScopedLogSection preserveAttachmentsSection (log, "Preserves", "Preserves");
867
868 for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
869 {
870 const tcu::ScopedLogSection preserveAttachmentSection (log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
871 const deUint32 preserveAttachment = preserveAttachments[preserveNdx];
872
873 log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
874 }
875 }
876 }
877
878 }
879
880 if (!renderPass.getDependencies().empty())
881 {
882 const tcu::ScopedLogSection dependenciesSection (log, "Dependencies", "Dependencies");
883
884 for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
885 {
886 const tcu::ScopedLogSection dependencySection (log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
887 const SubpassDependency& dep = renderPass.getDependencies()[depNdx];
888
889 log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
890 log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;
891
892 log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
893 log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;
894
895 log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
896 log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
897 log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
898 }
899 }
900 }
901
clearColorToString(VkFormat vkFormat,VkClearColorValue value)902 std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
903 {
904 const tcu::TextureFormat format = mapVkFormat(vkFormat);
905 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
906 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
907
908 std::ostringstream stream;
909
910 stream << "(";
911
912 switch (channelClass)
913 {
914 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
915 for (int i = 0; i < 4; i++)
916 {
917 if (i > 0)
918 stream << ", ";
919
920 if (channelMask[i])
921 stream << value.int32[i];
922 else
923 stream << "Undef";
924 }
925 break;
926
927 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
928 for (int i = 0; i < 4; i++)
929 {
930 if (i > 0)
931 stream << ", ";
932
933 if (channelMask[i])
934 stream << value.uint32[i];
935 else
936 stream << "Undef";
937 }
938 break;
939
940 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
941 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
942 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
943 for (int i = 0; i < 4; i++)
944 {
945 if (i > 0)
946 stream << ", ";
947
948 if (channelMask[i])
949 stream << value.float32[i];
950 else
951 stream << "Undef";
952 }
953 break;
954
955 default:
956 DE_FATAL("Unknown channel class");
957 }
958
959 stream << ")";
960
961 return stream.str();
962 }
963
clearValueToString(VkFormat vkFormat,VkClearValue value)964 std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
965 {
966 const tcu::TextureFormat format = mapVkFormat(vkFormat);
967
968 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
969 {
970 std::ostringstream stream;
971
972 stream << "(";
973
974 if (tcu::hasStencilComponent(format.order))
975 stream << "stencil: " << value.depthStencil.stencil;
976
977 if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
978 stream << ", ";
979
980 if (tcu::hasDepthComponent(format.order))
981 stream << "depth: " << value.depthStencil.depth;
982
983 stream << ")";
984
985 return stream.str();
986 }
987 else
988 return clearColorToString(vkFormat, value.color);
989 }
990
randomColorClearValue(const Attachment & attachment,de::Random & rng)991 VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
992 {
993 const float clearNan = tcu::Float32::nan().asFloat();
994 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
995 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
996 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
997 VkClearColorValue clearColor;
998
999 switch (channelClass)
1000 {
1001 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1002 {
1003 for (int ndx = 0; ndx < 4; ndx++)
1004 {
1005 if (!channelMask[ndx])
1006 clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
1007 else
1008 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1009 }
1010 break;
1011 }
1012
1013 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1014 {
1015 for (int ndx = 0; ndx < 4; ndx++)
1016 {
1017 if (!channelMask[ndx])
1018 clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
1019 else
1020 clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
1021 }
1022 break;
1023 }
1024
1025 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1026 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1027 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1028 {
1029 for (int ndx = 0; ndx < 4; ndx++)
1030 {
1031 if (!channelMask[ndx])
1032 clearColor.float32[ndx] = clearNan;
1033 else
1034 clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
1035 }
1036 break;
1037 }
1038
1039 default:
1040 DE_FATAL("Unknown channel class");
1041 }
1042
1043 return clearColor;
1044 }
1045
createAttachmentDescription(const Attachment & attachment)1046 VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
1047 {
1048 const VkAttachmentDescription attachmentDescription =
1049 {
1050 0, // flags
1051
1052 attachment.getFormat(), // format
1053 attachment.getSamples(), // samples
1054
1055 attachment.getLoadOp(), // loadOp
1056 attachment.getStoreOp(), // storeOp
1057
1058 attachment.getStencilLoadOp(), // stencilLoadOp
1059 attachment.getStencilStoreOp(), // stencilStoreOp
1060
1061 attachment.getInitialLayout(), // initialLayout
1062 attachment.getFinalLayout(), // finalLayout
1063 };
1064
1065 return attachmentDescription;
1066 }
1067
createAttachmentReference(const AttachmentReference & referenceInfo)1068 VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
1069 {
1070 const VkAttachmentReference reference =
1071 {
1072 referenceInfo.getAttachment(), // attachment;
1073 referenceInfo.getImageLayout() // layout;
1074 };
1075
1076 return reference;
1077 }
1078
createSubpassDescription(const Subpass & subpass,vector<VkAttachmentReference> * attachmentReferenceLists,vector<deUint32> * preserveAttachmentReferences)1079 VkSubpassDescription createSubpassDescription (const Subpass& subpass,
1080 vector<VkAttachmentReference>* attachmentReferenceLists,
1081 vector<deUint32>* preserveAttachmentReferences)
1082 {
1083 vector<VkAttachmentReference>& inputAttachmentReferences = attachmentReferenceLists[0];
1084 vector<VkAttachmentReference>& colorAttachmentReferences = attachmentReferenceLists[1];
1085 vector<VkAttachmentReference>& resolveAttachmentReferences = attachmentReferenceLists[2];
1086 vector<VkAttachmentReference>& depthStencilAttachmentReferences = attachmentReferenceLists[3];
1087
1088 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
1089 colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));
1090
1091 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
1092 inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));
1093
1094 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
1095 resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));
1096
1097 depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));
1098
1099 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
1100 preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);
1101
1102 DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());
1103
1104 {
1105 const VkSubpassDescription subpassDescription =
1106 {
1107 subpass.getFlags(), // flags;
1108 subpass.getPipelineBindPoint(), // pipelineBindPoint;
1109
1110 (deUint32)inputAttachmentReferences.size(), // inputCount;
1111 inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0], // inputAttachments;
1112
1113 (deUint32)colorAttachmentReferences.size(), // colorCount;
1114 colorAttachmentReferences.empty() ? DE_NULL : &colorAttachmentReferences[0], // colorAttachments;
1115 resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0], // resolveAttachments;
1116
1117 &depthStencilAttachmentReferences[0], // pDepthStencilAttachment;
1118 (deUint32)preserveAttachmentReferences->size(), // preserveCount;
1119 preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0] // preserveAttachments;
1120 };
1121
1122 return subpassDescription;
1123 }
1124 }
1125
createSubpassDependency(const SubpassDependency & dependencyInfo)1126 VkSubpassDependency createSubpassDependency (const SubpassDependency& dependencyInfo)
1127 {
1128 const VkSubpassDependency dependency =
1129 {
1130 dependencyInfo.getSrcPass(), // srcSubpass;
1131 dependencyInfo.getDstPass(), // destSubpass;
1132
1133 dependencyInfo.getSrcStageMask(), // srcStageMask;
1134 dependencyInfo.getDstStageMask(), // destStageMask;
1135
1136 dependencyInfo.getOutputMask(), // outputMask;
1137 dependencyInfo.getInputMask(), // inputMask;
1138
1139 dependencyInfo.getFlags() // dependencyFlags;
1140 };
1141
1142 return dependency;
1143 }
1144
createRenderPass(const DeviceInterface & vk,VkDevice device,const RenderPass & renderPassInfo)1145 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
1146 VkDevice device,
1147 const RenderPass& renderPassInfo)
1148 {
1149 const size_t perSubpassAttachmentReferenceLists = 4;
1150 vector<VkAttachmentDescription> attachments;
1151 vector<VkSubpassDescription> subpasses;
1152 vector<VkSubpassDependency> dependencies;
1153 vector<vector<VkAttachmentReference> > attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
1154 vector<vector<deUint32> > preserveAttachments(renderPassInfo.getSubpasses().size());
1155
1156 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
1157 attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));
1158
1159 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1160 subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));
1161
1162 for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
1163 dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));
1164
1165 if (renderPassInfo.getInputAspects().empty())
1166 {
1167 const VkRenderPassCreateInfo createInfo =
1168 {
1169 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1170 DE_NULL,
1171 (VkRenderPassCreateFlags)0u,
1172 (deUint32)attachments.size(),
1173 (attachments.empty() ? DE_NULL : &attachments[0]),
1174 (deUint32)subpasses.size(),
1175 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1176 (deUint32)dependencies.size(),
1177 (dependencies.empty() ? DE_NULL : &dependencies[0])
1178 };
1179
1180 return createRenderPass(vk, device, &createInfo);
1181 }
1182 else
1183 {
1184 const VkRenderPassInputAttachmentAspectCreateInfoKHR inputAspectCreateInfo =
1185 {
1186 VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR,
1187 DE_NULL,
1188
1189 (deUint32)renderPassInfo.getInputAspects().size(),
1190 renderPassInfo.getInputAspects().data(),
1191 };
1192 const VkRenderPassCreateInfo createInfo =
1193 {
1194 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1195 &inputAspectCreateInfo,
1196 (VkRenderPassCreateFlags)0u,
1197 (deUint32)attachments.size(),
1198 (attachments.empty() ? DE_NULL : &attachments[0]),
1199 (deUint32)subpasses.size(),
1200 (subpasses.empty() ? DE_NULL : &subpasses[0]),
1201 (deUint32)dependencies.size(),
1202 (dependencies.empty() ? DE_NULL : &dependencies[0])
1203 };
1204
1205 return createRenderPass(vk, device, &createInfo);
1206 }
1207 }
1208
createFramebuffer(const DeviceInterface & vk,VkDevice device,VkRenderPass renderPass,const UVec2 & size,const vector<VkImageView> & attachments)1209 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vk,
1210 VkDevice device,
1211 VkRenderPass renderPass,
1212 const UVec2& size,
1213 const vector<VkImageView>& attachments)
1214 {
1215 return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
1216 }
1217
createAttachmentImage(const DeviceInterface & vk,VkDevice device,deUint32 queueIndex,const UVec2 & size,VkFormat format,VkSampleCountFlagBits samples,VkImageUsageFlags usageFlags,VkImageLayout layout)1218 Move<VkImage> createAttachmentImage (const DeviceInterface& vk,
1219 VkDevice device,
1220 deUint32 queueIndex,
1221 const UVec2& size,
1222 VkFormat format,
1223 VkSampleCountFlagBits samples,
1224 VkImageUsageFlags usageFlags,
1225 VkImageLayout layout)
1226 {
1227 VkImageUsageFlags targetUsageFlags = 0;
1228 const tcu::TextureFormat textureFormat = mapVkFormat(format);
1229
1230 DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1231 || ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));
1232
1233 DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
1234 || ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));
1235
1236 if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
1237 targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1238 else
1239 targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1240
1241 return createImage(vk, device,
1242 (VkImageCreateFlags)0,
1243 VK_IMAGE_TYPE_2D,
1244 format,
1245 vk::makeExtent3D(size.x(), size.y(), 1u),
1246 1u /* mipLevels */,
1247 1u /* arraySize */,
1248 samples,
1249 VK_IMAGE_TILING_OPTIMAL,
1250 usageFlags | targetUsageFlags,
1251 VK_SHARING_MODE_EXCLUSIVE,
1252 1,
1253 &queueIndex,
1254 layout);
1255 }
1256
createImageMemory(const InstanceInterface & vki,const VkPhysicalDevice & vkd,const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image,bool lazy,AllocationKind allocationKind)1257 de::MovePtr<Allocation> createImageMemory (const InstanceInterface& vki,
1258 const VkPhysicalDevice& vkd,
1259 const DeviceInterface& vk,
1260 VkDevice device,
1261 Allocator& allocator,
1262 VkImage image,
1263 bool lazy,
1264 AllocationKind allocationKind)
1265 {
1266 const MemoryRequirement memoryRequirement = lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
1267 de::MovePtr<Allocation> allocation = allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);
1268
1269 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
1270
1271 return allocation;
1272 }
1273
createImageAttachmentView(const DeviceInterface & vk,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)1274 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vk,
1275 VkDevice device,
1276 VkImage image,
1277 VkFormat format,
1278 VkImageAspectFlags aspect)
1279 {
1280 const VkImageSubresourceRange range =
1281 {
1282 aspect,
1283 0,
1284 1,
1285 0,
1286 1
1287 };
1288
1289 return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
1290 }
1291
randomClearValue(const Attachment & attachment,de::Random & rng)1292 VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
1293 {
1294 const float clearNan = tcu::Float32::nan().asFloat();
1295 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
1296
1297 if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
1298 {
1299 VkClearValue clearValue;
1300
1301 clearValue.depthStencil.depth = clearNan;
1302 clearValue.depthStencil.stencil = 0xCDu;
1303
1304 if (tcu::hasStencilComponent(format.order))
1305 clearValue.depthStencil.stencil = rng.getBool()
1306 ? 0xFFu
1307 : 0x0u;
1308
1309 if (tcu::hasDepthComponent(format.order))
1310 clearValue.depthStencil.depth = rng.getBool()
1311 ? 1.0f
1312 : 0.0f;
1313
1314 return clearValue;
1315 }
1316 else
1317 {
1318 VkClearValue clearValue;
1319
1320 clearValue.color = randomColorClearValue(attachment, rng);
1321
1322 return clearValue;
1323 }
1324 }
1325
1326 class AttachmentResources
1327 {
1328 public:
AttachmentResources(const InstanceInterface & vki,const VkPhysicalDevice & physDevice,const DeviceInterface & vk,VkDevice device,Allocator & allocator,deUint32 queueIndex,const UVec2 & size,const Attachment & attachmentInfo,VkImageUsageFlags usageFlags,const AllocationKind allocationKind)1329 AttachmentResources (const InstanceInterface& vki,
1330 const VkPhysicalDevice& physDevice,
1331 const DeviceInterface& vk,
1332 VkDevice device,
1333 Allocator& allocator,
1334 deUint32 queueIndex,
1335 const UVec2& size,
1336 const Attachment& attachmentInfo,
1337 VkImageUsageFlags usageFlags,
1338 const AllocationKind allocationKind)
1339 : m_image (createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
1340 , m_imageMemory (createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
1341 , m_attachmentView (createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
1342 {
1343 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1344 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1345 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1346
1347 if (isDepthFormat && isStencilFormat)
1348 {
1349 m_depthInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
1350 m_stencilInputAttachmentView = createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);
1351
1352 m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
1353 }
1354 else
1355 m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);
1356
1357 if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
1358 {
1359 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
1360 {
1361 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachmentInfo.getFormat());
1362 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachmentInfo.getFormat());
1363
1364 m_bufferSize = size.x() * size.y() * depthFormat.getPixelSize();
1365 m_secondaryBufferSize = size.x() * size.y() * stencilFormat.getPixelSize();
1366
1367 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1368 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1369
1370 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1371
1372 m_secondaryBuffer = createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1373 m_secondaryBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1374
1375 bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
1376 }
1377 else
1378 {
1379 m_bufferSize = size.x() * size.y() * format.getPixelSize();
1380
1381 m_buffer = createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
1382 m_bufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);
1383
1384 bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
1385 }
1386 }
1387 }
1388
getInputAttachmentViews(void) const1389 const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
1390 {
1391 return m_inputAttachmentViews;
1392 }
1393
~AttachmentResources(void)1394 ~AttachmentResources (void)
1395 {
1396 }
1397
getAttachmentView(void) const1398 VkImageView getAttachmentView (void) const
1399 {
1400 return *m_attachmentView;
1401 }
1402
getImage(void) const1403 VkImage getImage (void) const
1404 {
1405 return *m_image;
1406 }
1407
getBuffer(void) const1408 VkBuffer getBuffer (void) const
1409 {
1410 DE_ASSERT(*m_buffer != DE_NULL);
1411 return *m_buffer;
1412 }
1413
getBufferSize(void) const1414 VkDeviceSize getBufferSize (void) const
1415 {
1416 DE_ASSERT(*m_buffer != DE_NULL);
1417 return m_bufferSize;
1418 }
1419
getResultMemory(void) const1420 const Allocation& getResultMemory (void) const
1421 {
1422 DE_ASSERT(m_bufferMemory);
1423 return *m_bufferMemory;
1424 }
1425
getSecondaryBuffer(void) const1426 VkBuffer getSecondaryBuffer (void) const
1427 {
1428 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1429 return *m_secondaryBuffer;
1430 }
1431
getSecondaryBufferSize(void) const1432 VkDeviceSize getSecondaryBufferSize (void) const
1433 {
1434 DE_ASSERT(*m_secondaryBuffer != DE_NULL);
1435 return m_secondaryBufferSize;
1436 }
1437
getSecondaryResultMemory(void) const1438 const Allocation& getSecondaryResultMemory (void) const
1439 {
1440 DE_ASSERT(m_secondaryBufferMemory);
1441 return *m_secondaryBufferMemory;
1442 }
1443
1444 private:
1445 const Unique<VkImage> m_image;
1446 const UniquePtr<Allocation> m_imageMemory;
1447 const Unique<VkImageView> m_attachmentView;
1448
1449 Move<VkImageView> m_depthInputAttachmentView;
1450 Move<VkImageView> m_stencilInputAttachmentView;
1451 pair<VkImageView, VkImageView> m_inputAttachmentViews;
1452
1453 Move<VkBuffer> m_buffer;
1454 VkDeviceSize m_bufferSize;
1455 de::MovePtr<Allocation> m_bufferMemory;
1456
1457 Move<VkBuffer> m_secondaryBuffer;
1458 VkDeviceSize m_secondaryBufferSize;
1459 de::MovePtr<Allocation> m_secondaryBufferMemory;
1460 };
1461
uploadBufferData(const DeviceInterface & vk,VkDevice device,const Allocation & memory,size_t size,const void * data)1462 void uploadBufferData (const DeviceInterface& vk,
1463 VkDevice device,
1464 const Allocation& memory,
1465 size_t size,
1466 const void* data)
1467 {
1468 const VkMappedMemoryRange range =
1469 {
1470 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
1471 DE_NULL, // pNext;
1472 memory.getMemory(), // mem;
1473 memory.getOffset(), // offset;
1474 (VkDeviceSize)size // size;
1475 };
1476 void* const ptr = memory.getHostPtr();
1477
1478 deMemcpy(ptr, data, size);
1479 VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
1480 }
1481
getPrimaryImageAspect(tcu::TextureFormat::ChannelOrder order)1482 VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
1483 {
1484 DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);
1485
1486 switch (order)
1487 {
1488 case tcu::TextureFormat::D:
1489 case tcu::TextureFormat::DS:
1490 return VK_IMAGE_ASPECT_DEPTH_BIT;
1491
1492 case tcu::TextureFormat::S:
1493 return VK_IMAGE_ASPECT_STENCIL_BIT;
1494
1495 default:
1496 return VK_IMAGE_ASPECT_COLOR_BIT;
1497 }
1498 }
1499
1500 class RenderQuad
1501 {
1502 public:
RenderQuad(const Vec2 & posA,const Vec2 & posB)1503 RenderQuad (const Vec2& posA, const Vec2& posB)
1504 : m_vertices(6)
1505 {
1506 m_vertices[0] = posA;
1507 m_vertices[1] = Vec2(posA[0], posB[1]);
1508 m_vertices[2] = posB;
1509
1510 m_vertices[3] = posB;
1511 m_vertices[4] = Vec2(posB[0], posA[1]);
1512 m_vertices[5] = posA;
1513 }
1514
getCornerA(void) const1515 const Vec2& getCornerA (void) const
1516 {
1517 return m_vertices[0];
1518 }
1519
getCornerB(void) const1520 const Vec2& getCornerB (void) const
1521 {
1522 return m_vertices[2];
1523 }
1524
getVertexPointer(void) const1525 const void* getVertexPointer (void) const
1526 {
1527 return &m_vertices[0];
1528 }
1529
getVertexDataSize(void) const1530 size_t getVertexDataSize (void) const
1531 {
1532 return sizeof(Vec2) * m_vertices.size();
1533 }
1534
1535 private:
1536 vector<Vec2> m_vertices;
1537 };
1538
1539 class ColorClear
1540 {
1541 public:
ColorClear(const UVec2 & offset,const UVec2 & size,const VkClearColorValue & color)1542 ColorClear (const UVec2& offset,
1543 const UVec2& size,
1544 const VkClearColorValue& color)
1545 : m_offset (offset)
1546 , m_size (size)
1547 , m_color (color)
1548 {
1549 }
1550
getOffset(void) const1551 const UVec2& getOffset (void) const { return m_offset; }
getSize(void) const1552 const UVec2& getSize (void) const { return m_size; }
getColor(void) const1553 const VkClearColorValue& getColor (void) const { return m_color; }
1554
1555 private:
1556 UVec2 m_offset;
1557 UVec2 m_size;
1558 VkClearColorValue m_color;
1559 };
1560
1561 class DepthStencilClear
1562 {
1563 public:
DepthStencilClear(const UVec2 & offset,const UVec2 & size,float depth,deUint32 stencil)1564 DepthStencilClear (const UVec2& offset,
1565 const UVec2& size,
1566 float depth,
1567 deUint32 stencil)
1568 : m_offset (offset)
1569 , m_size (size)
1570 , m_depth (depth)
1571 , m_stencil (stencil)
1572 {
1573 }
1574
getOffset(void) const1575 const UVec2& getOffset (void) const { return m_offset; }
getSize(void) const1576 const UVec2& getSize (void) const { return m_size; }
getDepth(void) const1577 float getDepth (void) const { return m_depth; }
getStencil(void) const1578 deUint32 getStencil (void) const { return m_stencil; }
1579
1580 private:
1581 const UVec2 m_offset;
1582 const UVec2 m_size;
1583
1584 const float m_depth;
1585 const deUint32 m_stencil;
1586 };
1587
1588 class SubpassRenderInfo
1589 {
1590 public:
SubpassRenderInfo(const RenderPass & renderPass,deUint32 subpassIndex,bool isSecondary_,const UVec2 & viewportOffset,const UVec2 & viewportSize,const Maybe<RenderQuad> & renderQuad,const vector<ColorClear> & colorClears,const Maybe<DepthStencilClear> & depthStencilClear)1591 SubpassRenderInfo (const RenderPass& renderPass,
1592 deUint32 subpassIndex,
1593
1594 bool isSecondary_,
1595
1596 const UVec2& viewportOffset,
1597 const UVec2& viewportSize,
1598
1599 const Maybe<RenderQuad>& renderQuad,
1600 const vector<ColorClear>& colorClears,
1601 const Maybe<DepthStencilClear>& depthStencilClear)
1602 : m_viewportOffset (viewportOffset)
1603 , m_viewportSize (viewportSize)
1604 , m_subpassIndex (subpassIndex)
1605 , m_isSecondary (isSecondary_)
1606 , m_flags (renderPass.getSubpasses()[subpassIndex].getFlags())
1607 , m_renderQuad (renderQuad)
1608 , m_colorClears (colorClears)
1609 , m_depthStencilClear (depthStencilClear)
1610 , m_colorAttachments (renderPass.getSubpasses()[subpassIndex].getColorAttachments())
1611 , m_inputAttachments (renderPass.getSubpasses()[subpassIndex].getInputAttachments())
1612 {
1613 for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
1614 m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);
1615
1616 if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
1617 {
1618 m_depthStencilAttachment = tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
1619 m_depthStencilAttachmentInfo = tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
1620 }
1621 }
1622
getViewportOffset(void) const1623 const UVec2& getViewportOffset (void) const { return m_viewportOffset; }
getViewportSize(void) const1624 const UVec2& getViewportSize (void) const { return m_viewportSize; }
1625
getSubpassIndex(void) const1626 deUint32 getSubpassIndex (void) const { return m_subpassIndex; }
isSecondary(void) const1627 bool isSecondary (void) const { return m_isSecondary; }
1628
getRenderQuad(void) const1629 const Maybe<RenderQuad>& getRenderQuad (void) const { return m_renderQuad; }
getColorClears(void) const1630 const vector<ColorClear>& getColorClears (void) const { return m_colorClears; }
getDepthStencilClear(void) const1631 const Maybe<DepthStencilClear>& getDepthStencilClear (void) const { return m_depthStencilClear; }
1632
getInputAttachmentCount(void) const1633 deUint32 getInputAttachmentCount (void) const { return (deUint32)m_inputAttachments.size(); }
getInputAttachmentIndex(deUint32 attachmentNdx) const1634 deUint32 getInputAttachmentIndex (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
getInputAttachmentLayout(deUint32 attachmentNdx) const1635 VkImageLayout getInputAttachmentLayout (deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }
1636
getColorAttachmentCount(void) const1637 deUint32 getColorAttachmentCount (void) const { return (deUint32)m_colorAttachments.size(); }
getColorAttachmentLayout(deUint32 attachmentNdx) const1638 VkImageLayout getColorAttachmentLayout (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
getColorAttachmentIndex(deUint32 attachmentNdx) const1639 deUint32 getColorAttachmentIndex (deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
getColorAttachment(deUint32 attachmentNdx) const1640 const Attachment& getColorAttachment (deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
getDepthStencilAttachmentLayout(void) const1641 Maybe<VkImageLayout> getDepthStencilAttachmentLayout (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
getDepthStencilAttachmentIndex(void) const1642 Maybe<deUint32> getDepthStencilAttachmentIndex (void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
getDepthStencilAttachment(void) const1643 const Maybe<Attachment>& getDepthStencilAttachment (void) const { return m_depthStencilAttachmentInfo; }
getSubpassFlags(void) const1644 VkSubpassDescriptionFlags getSubpassFlags (void) const { return m_flags; }
1645
1646 private:
1647 UVec2 m_viewportOffset;
1648 UVec2 m_viewportSize;
1649
1650 deUint32 m_subpassIndex;
1651 bool m_isSecondary;
1652 VkSubpassDescriptionFlags m_flags;
1653
1654 Maybe<RenderQuad> m_renderQuad;
1655 vector<ColorClear> m_colorClears;
1656 Maybe<DepthStencilClear> m_depthStencilClear;
1657
1658 vector<AttachmentReference> m_colorAttachments;
1659 vector<Attachment> m_colorAttachmentInfo;
1660
1661 Maybe<AttachmentReference> m_depthStencilAttachment;
1662 Maybe<Attachment> m_depthStencilAttachmentInfo;
1663
1664 vector<AttachmentReference> m_inputAttachments;
1665 };
1666
createSubpassPipeline(const DeviceInterface & vk,VkDevice device,VkRenderPass renderPass,VkShaderModule vertexShaderModule,VkShaderModule fragmentShaderModule,VkPipelineLayout pipelineLayout,const SubpassRenderInfo & renderInfo)1667 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vk,
1668 VkDevice device,
1669 VkRenderPass renderPass,
1670 VkShaderModule vertexShaderModule,
1671 VkShaderModule fragmentShaderModule,
1672 VkPipelineLayout pipelineLayout,
1673 const SubpassRenderInfo& renderInfo)
1674 {
1675 const VkSpecializationInfo emptyShaderSpecializations =
1676 {
1677 0u, // mapEntryCount
1678 DE_NULL, // pMap
1679 0u, // dataSize
1680 DE_NULL, // pData
1681 };
1682
1683 Maybe<VkSampleCountFlagBits> rasterSamples;
1684 vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates;
1685
1686 for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
1687 {
1688 const Attachment& attachment = renderInfo.getColorAttachment(attachmentNdx);
1689
1690 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1691
1692 rasterSamples = attachment.getSamples();
1693
1694 {
1695 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1696 {
1697 VK_FALSE, // blendEnable
1698 VK_BLEND_FACTOR_SRC_ALPHA, // srcBlendColor
1699 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // destBlendColor
1700 VK_BLEND_OP_ADD, // blendOpColor
1701 VK_BLEND_FACTOR_ONE, // srcBlendAlpha
1702 VK_BLEND_FACTOR_ONE, // destBlendAlpha
1703 VK_BLEND_OP_ADD, // blendOpAlpha
1704 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT, // channelWriteMask
1705 };
1706
1707 attachmentBlendStates.push_back(attachmentBlendState);
1708 }
1709 }
1710
1711 if (renderInfo.getDepthStencilAttachment())
1712 {
1713 const Attachment& attachment = *renderInfo.getDepthStencilAttachment();
1714
1715 DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
1716 rasterSamples = attachment.getSamples();
1717 }
1718
1719 // If there are no attachment use single sample
1720 if (!rasterSamples)
1721 rasterSamples = VK_SAMPLE_COUNT_1_BIT;
1722
1723 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1724 {
1725 {
1726 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1727 DE_NULL, // pNext
1728 (VkPipelineShaderStageCreateFlags)0u,
1729 VK_SHADER_STAGE_VERTEX_BIT, // stage
1730 vertexShaderModule, // shader
1731 "main",
1732 &emptyShaderSpecializations
1733 },
1734 {
1735 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
1736 DE_NULL, // pNext
1737 (VkPipelineShaderStageCreateFlags)0u,
1738 VK_SHADER_STAGE_FRAGMENT_BIT, // stage
1739 fragmentShaderModule, // shader
1740 "main",
1741 &emptyShaderSpecializations
1742 }
1743 };
1744 const VkVertexInputBindingDescription vertexBinding =
1745 {
1746 0u, // binding
1747 (deUint32)sizeof(tcu::Vec2), // strideInBytes
1748 VK_VERTEX_INPUT_RATE_VERTEX, // stepRate
1749 };
1750 const VkVertexInputAttributeDescription vertexAttrib =
1751 {
1752 0u, // location
1753 0u, // binding
1754 VK_FORMAT_R32G32_SFLOAT, // format
1755 0u, // offsetInBytes
1756 };
1757 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1758 {
1759 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType
1760 DE_NULL, // pNext
1761 (VkPipelineVertexInputStateCreateFlags)0u,
1762 1u, // bindingCount
1763 &vertexBinding, // pVertexBindingDescriptions
1764 1u, // attributeCount
1765 &vertexAttrib, // pVertexAttributeDescriptions
1766 };
1767 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1768 {
1769 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType
1770 DE_NULL, // pNext
1771 (VkPipelineInputAssemblyStateCreateFlags)0u,
1772 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
1773 VK_FALSE, // primitiveRestartEnable
1774 };
1775 const VkViewport viewport =
1776 {
1777 (float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y(),
1778 (float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y(),
1779 0.0f, 1.0f
1780 };
1781 const VkRect2D scissor =
1782 {
1783 { (deInt32)renderInfo.getViewportOffset().x(), (deInt32)renderInfo.getViewportOffset().y() },
1784 { renderInfo.getViewportSize().x(), renderInfo.getViewportSize().y() }
1785 };
1786 const VkPipelineViewportStateCreateInfo viewportState =
1787 {
1788 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1789 DE_NULL,
1790 (VkPipelineViewportStateCreateFlags)0u,
1791 1u,
1792 &viewport,
1793 1u,
1794 &scissor
1795 };
1796 const VkPipelineRasterizationStateCreateInfo rasterState =
1797 {
1798 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType
1799 DE_NULL, // pNext
1800 (VkPipelineRasterizationStateCreateFlags)0u,
1801 VK_TRUE, // depthClipEnable
1802 VK_FALSE, // rasterizerDiscardEnable
1803 VK_POLYGON_MODE_FILL, // fillMode
1804 VK_CULL_MODE_NONE, // cullMode
1805 VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1806 VK_FALSE, // depthBiasEnable
1807 0.0f, // depthBias
1808 0.0f, // depthBiasClamp
1809 0.0f, // slopeScaledDepthBias
1810 1.0f // lineWidth
1811 };
1812 const VkPipelineMultisampleStateCreateInfo multisampleState =
1813 {
1814 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType
1815 DE_NULL, // pNext
1816 (VkPipelineMultisampleStateCreateFlags)0u,
1817 *rasterSamples, // rasterSamples
1818 VK_FALSE, // sampleShadingEnable
1819 0.0f, // minSampleShading
1820 DE_NULL, // pSampleMask
1821 VK_FALSE, // alphaToCoverageEnable
1822 VK_FALSE, // alphaToOneEnable
1823 };
1824 const size_t stencilIndex = renderInfo.getSubpassIndex();
1825 const VkBool32 writeDepth = renderInfo.getDepthStencilAttachmentLayout()
1826 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1827 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR
1828 ? VK_TRUE
1829 : VK_FALSE;
1830 const VkBool32 writeStencil = renderInfo.getDepthStencilAttachmentLayout()
1831 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1832 && *renderInfo.getDepthStencilAttachmentLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
1833 ? VK_TRUE
1834 : VK_FALSE;
1835 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1836 {
1837 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType
1838 DE_NULL, // pNext
1839 (VkPipelineDepthStencilStateCreateFlags)0u,
1840 writeDepth, // depthTestEnable
1841 writeDepth, // depthWriteEnable
1842 VK_COMPARE_OP_ALWAYS, // depthCompareOp
1843 VK_FALSE, // depthBoundsEnable
1844 writeStencil, // stencilTestEnable
1845 {
1846 VK_STENCIL_OP_REPLACE, // stencilFailOp
1847 VK_STENCIL_OP_REPLACE, // stencilPassOp
1848 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1849 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1850 ~0u, // stencilCompareMask
1851 ~0u, // stencilWriteMask
1852 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1853 }, // front
1854 {
1855 VK_STENCIL_OP_REPLACE, // stencilFailOp
1856 VK_STENCIL_OP_REPLACE, // stencilPassOp
1857 VK_STENCIL_OP_REPLACE, // stencilDepthFailOp
1858 VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1859 ~0u, // stencilCompareMask
1860 ~0u, // stencilWriteMask
1861 ((stencilIndex % 2) == 0) ? ~0x0u : 0x0u // stencilReference
1862 }, // back
1863
1864 0.0f, // minDepthBounds;
1865 1.0f // maxDepthBounds;
1866 };
1867 const VkPipelineColorBlendStateCreateInfo blendState =
1868 {
1869 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType
1870 DE_NULL, // pNext
1871 (VkPipelineColorBlendStateCreateFlags)0u,
1872 VK_FALSE, // logicOpEnable
1873 VK_LOGIC_OP_COPY, // logicOp
1874 (deUint32)attachmentBlendStates.size(), // attachmentCount
1875 attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
1876 { 0.0f, 0.0f, 0.0f, 0.0f } // blendConst
1877 };
1878 const VkGraphicsPipelineCreateInfo createInfo =
1879 {
1880 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType
1881 DE_NULL, // pNext
1882 (VkPipelineCreateFlags)0u,
1883
1884 2, // stageCount
1885 shaderStages, // pStages
1886
1887 &vertexInputState, // pVertexInputState
1888 &inputAssemblyState, // pInputAssemblyState
1889 DE_NULL, // pTessellationState
1890 &viewportState, // pViewportState
1891 &rasterState, // pRasterState
1892 &multisampleState, // pMultisampleState
1893 &depthStencilState, // pDepthStencilState
1894 &blendState, // pColorBlendState
1895 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1896 pipelineLayout, // layout
1897
1898 renderPass, // renderPass
1899 renderInfo.getSubpassIndex(), // subpass
1900 DE_NULL, // basePipelineHandle
1901 0u // basePipelineIndex
1902 };
1903
1904 return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
1905 }
1906
1907 class SubpassRenderer
1908 {
1909 public:
SubpassRenderer(Context & context,const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkRenderPass renderPass,VkFramebuffer framebuffer,VkCommandPool commandBufferPool,deUint32 queueFamilyIndex,const vector<VkImage> & attachmentImages,const vector<pair<VkImageView,VkImageView>> & attachmentViews,const SubpassRenderInfo & renderInfo,const vector<Attachment> & attachmentInfos,const AllocationKind allocationKind)1910 SubpassRenderer (Context& context,
1911 const DeviceInterface& vk,
1912 VkDevice device,
1913 Allocator& allocator,
1914 VkRenderPass renderPass,
1915 VkFramebuffer framebuffer,
1916 VkCommandPool commandBufferPool,
1917 deUint32 queueFamilyIndex,
1918 const vector<VkImage>& attachmentImages,
1919 const vector<pair<VkImageView, VkImageView> >& attachmentViews,
1920 const SubpassRenderInfo& renderInfo,
1921 const vector<Attachment>& attachmentInfos,
1922 const AllocationKind allocationKind)
1923 : m_renderInfo (renderInfo)
1924 {
1925 const InstanceInterface& vki = context.getInstanceInterface();
1926 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
1927 const deUint32 subpassIndex = renderInfo.getSubpassIndex();
1928 vector<VkDescriptorSetLayoutBinding> bindings;
1929
1930 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
1931 m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);
1932
1933 if (renderInfo.getDepthStencilAttachmentIndex())
1934 m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];
1935
1936 if (renderInfo.getRenderQuad())
1937 {
1938 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
1939
1940 if (renderInfo.getInputAttachmentCount() > 0)
1941 {
1942 deUint32 bindingIndex = 0;
1943
1944 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
1945 {
1946 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
1947 const VkImageLayout layout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
1948 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
1949 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
1950 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
1951 const deUint32 bindingCount = (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
1952 && (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
1953 ? 2u
1954 : 1u;
1955
1956 for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
1957 {
1958 const VkDescriptorSetLayoutBinding binding =
1959 {
1960 bindingIndex,
1961 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1962 1u,
1963 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1964 DE_NULL
1965 };
1966
1967 bindings.push_back(binding);
1968 bindingIndex++;
1969 }
1970 }
1971
1972 const VkDescriptorSetLayoutCreateInfo createInfo =
1973 {
1974 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1975 DE_NULL,
1976
1977 0u,
1978 (deUint32)bindings.size(),
1979 &bindings[0]
1980 };
1981
1982 m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
1983 }
1984
1985 const VkDescriptorSetLayout descriptorSetLayout = *m_descriptorSetLayout;
1986 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1987 {
1988 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType;
1989 DE_NULL, // pNext;
1990 (vk::VkPipelineLayoutCreateFlags)0,
1991 m_descriptorSetLayout ? 1u :0u , // setLayoutCount;
1992 m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL, // pSetLayouts;
1993 0u, // pushConstantRangeCount;
1994 DE_NULL, // pPushConstantRanges;
1995 };
1996
1997 m_vertexShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
1998 m_fragmentShaderModule = createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
1999 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams);
2000 m_pipeline = createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);
2001
2002 m_vertexBuffer = createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
2003 m_vertexBufferMemory = allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);
2004
2005 bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
2006 uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());
2007
2008 if (renderInfo.getInputAttachmentCount() > 0)
2009 {
2010 {
2011 const VkDescriptorPoolSize poolSize =
2012 {
2013 vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2014 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2015 renderInfo.getInputAttachmentCount() * 2u
2016 };
2017 const VkDescriptorPoolCreateInfo createInfo =
2018 {
2019 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
2020 DE_NULL,
2021 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2022
2023 // \note Reserve 2 per input attachment since depthStencil attachments require 2.
2024 renderInfo.getInputAttachmentCount() * 2u,
2025 1u,
2026 &poolSize
2027 };
2028
2029 m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
2030 }
2031 {
2032 const VkDescriptorSetAllocateInfo allocateInfo =
2033 {
2034 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2035 DE_NULL,
2036
2037 *m_descriptorPool,
2038 1u,
2039 &descriptorSetLayout
2040 };
2041
2042 m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
2043 }
2044 {
2045 vector<VkWriteDescriptorSet> writes (bindings.size());
2046 vector<VkDescriptorImageInfo> imageInfos (bindings.size());
2047 deUint32 bindingIndex = 0;
2048
2049 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2050 {
2051 const Attachment attachmentInfo = attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
2052 const tcu::TextureFormat format = mapVkFormat(attachmentInfo.getFormat());
2053 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
2054 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
2055 const VkImageLayout inputAttachmentLayout = renderInfo.getInputAttachmentLayout(inputAttachmentNdx);
2056
2057
2058 if (isDepthFormat && isStencilFormat)
2059 {
2060 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
2061 {
2062 const VkDescriptorImageInfo imageInfo =
2063 {
2064 (VkSampler)0,
2065 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2066 inputAttachmentLayout
2067 };
2068 imageInfos[bindingIndex] = imageInfo;
2069
2070 {
2071 const VkWriteDescriptorSet write =
2072 {
2073 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2074 DE_NULL,
2075
2076 *m_descriptorSet,
2077 bindingIndex,
2078 0u,
2079 1u,
2080 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2081 &imageInfos[bindingIndex],
2082 DE_NULL,
2083 DE_NULL
2084 };
2085 writes[bindingIndex] = write;
2086
2087 bindingIndex++;
2088 }
2089 }
2090
2091 if (inputAttachmentLayout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
2092 {
2093 const VkDescriptorImageInfo imageInfo =
2094 {
2095 (VkSampler)0,
2096 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
2097 inputAttachmentLayout
2098 };
2099 imageInfos[bindingIndex] = imageInfo;
2100
2101 {
2102 const VkWriteDescriptorSet write =
2103 {
2104 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2105 DE_NULL,
2106
2107 *m_descriptorSet,
2108 bindingIndex,
2109 0u,
2110 1u,
2111 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2112 &imageInfos[bindingIndex],
2113 DE_NULL,
2114 DE_NULL
2115 };
2116 writes[bindingIndex] = write;
2117
2118 bindingIndex++;
2119 }
2120 }
2121 }
2122 else
2123 {
2124 const VkDescriptorImageInfo imageInfo =
2125 {
2126 (VkSampler)0,
2127 attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
2128 inputAttachmentLayout
2129 };
2130 imageInfos[bindingIndex] = imageInfo;
2131
2132 {
2133 const VkWriteDescriptorSet write =
2134 {
2135 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
2136 DE_NULL,
2137
2138 *m_descriptorSet,
2139 bindingIndex,
2140 0u,
2141 1u,
2142 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2143 &imageInfos[bindingIndex],
2144 DE_NULL,
2145 DE_NULL
2146 };
2147 writes[bindingIndex] = write;
2148
2149 bindingIndex++;
2150 }
2151 }
2152 }
2153
2154 vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
2155 }
2156 }
2157 }
2158
2159 if (renderInfo.isSecondary())
2160 {
2161 m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2162
2163 beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
2164 pushRenderCommands(vk, *m_commandBuffer);
2165 endCommandBuffer(vk, *m_commandBuffer);
2166 }
2167 }
2168
isSecondary(void) const2169 bool isSecondary (void) const
2170 {
2171 return m_commandBuffer;
2172 }
2173
getCommandBuffer(void) const2174 VkCommandBuffer getCommandBuffer (void) const
2175 {
2176 DE_ASSERT(isSecondary());
2177 return *m_commandBuffer;
2178 }
2179
pushRenderCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer)2180 void pushRenderCommands (const DeviceInterface& vk,
2181 VkCommandBuffer commandBuffer)
2182 {
2183 if (!m_renderInfo.getColorClears().empty())
2184 {
2185 const vector<ColorClear>& colorClears (m_renderInfo.getColorClears());
2186
2187 for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
2188 {
2189 const ColorClear& colorClear = colorClears[attachmentNdx];
2190 const VkClearAttachment attachment =
2191 {
2192 VK_IMAGE_ASPECT_COLOR_BIT,
2193 attachmentNdx,
2194 makeClearValue(colorClear.getColor()),
2195 };
2196 const VkClearRect rect =
2197 {
2198 {
2199 { (deInt32)colorClear.getOffset().x(), (deInt32)colorClear.getOffset().y() },
2200 { colorClear.getSize().x(), colorClear.getSize().y() }
2201 }, // rect
2202 0u, // baseArrayLayer
2203 1u, // layerCount
2204 };
2205
2206 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2207 }
2208 }
2209
2210 if (m_renderInfo.getDepthStencilClear())
2211 {
2212 const DepthStencilClear& depthStencilClear = *m_renderInfo.getDepthStencilClear();
2213 const deUint32 attachmentNdx = m_renderInfo.getColorAttachmentCount();
2214 tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2215 const VkImageLayout layout = *m_renderInfo.getDepthStencilAttachmentLayout();
2216 const VkClearAttachment attachment =
2217 {
2218 (VkImageAspectFlags)((hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2219 | (hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2220 attachmentNdx,
2221 makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
2222 };
2223 const VkClearRect rect =
2224 {
2225 {
2226 { (deInt32)depthStencilClear.getOffset().x(), (deInt32)depthStencilClear.getOffset().y() },
2227 { depthStencilClear.getSize().x(), depthStencilClear.getSize().y() }
2228 }, // rect
2229 0u, // baseArrayLayer
2230 1u, // layerCount
2231 };
2232
2233 if ((tcu::hasDepthComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
2234 || (tcu::hasStencilComponent(format.order) && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR))
2235 {
2236 vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
2237 }
2238 }
2239
2240 vector<VkImageMemoryBarrier> selfDeps;
2241 VkPipelineStageFlags srcStages = 0;
2242 VkPipelineStageFlags dstStages = 0;
2243
2244 for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
2245 {
2246 for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
2247 {
2248 if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
2249 {
2250 const VkImageMemoryBarrier barrier =
2251 {
2252 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2253 DE_NULL, // pNext
2254
2255 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2256 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2257
2258 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2259 VK_IMAGE_LAYOUT_GENERAL, // newLayout
2260
2261 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2262 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2263
2264 m_colorAttachmentImages[colorAttachmentNdx], // image
2265 { // subresourceRange
2266 VK_IMAGE_ASPECT_COLOR_BIT, // aspect
2267 0, // baseMipLevel
2268 1, // mipLevels
2269 0, // baseArraySlice
2270 1 // arraySize
2271 }
2272 };
2273
2274 srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2275 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2276
2277 selfDeps.push_back(barrier);
2278 }
2279 }
2280
2281 if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
2282 {
2283 const tcu::TextureFormat format = mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
2284 const bool hasDepth = hasDepthComponent(format.order);
2285 const bool hasStencil = hasStencilComponent(format.order);
2286 const VkImageMemoryBarrier barrier =
2287 {
2288 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2289 DE_NULL, // pNext;
2290
2291 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // srcAccessMask
2292 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2293
2294 VK_IMAGE_LAYOUT_GENERAL, // oldLayout
2295 VK_IMAGE_LAYOUT_GENERAL, // newLayout;
2296
2297 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex;
2298 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex;
2299
2300 m_depthStencilAttachmentImage, // image;
2301 { // subresourceRange;
2302 (hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
2303 | (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u), // aspect;
2304 0, // baseMipLevel;
2305 1, // mipLevels;
2306 0, // baseArraySlice;
2307 1 // arraySize;
2308 }
2309 };
2310
2311 srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
2312 dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
2313
2314 selfDeps.push_back(barrier);
2315 }
2316 }
2317
2318 if (!selfDeps.empty())
2319 {
2320 DE_ASSERT(srcStages != 0);
2321 DE_ASSERT(dstStages != 0);
2322 vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
2323 }
2324
2325 if (m_renderInfo.getRenderQuad())
2326 {
2327 const VkDeviceSize offset = 0;
2328 const VkBuffer vertexBuffer = *m_vertexBuffer;
2329
2330 vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
2331
2332 if (m_descriptorSet)
2333 {
2334 const VkDescriptorSet descriptorSet = *m_descriptorSet;
2335 vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
2336 }
2337
2338 vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
2339 vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
2340 }
2341 }
2342
2343 private:
2344 const SubpassRenderInfo m_renderInfo;
2345 Move<VkCommandBuffer> m_commandBuffer;
2346 Move<VkPipeline> m_pipeline;
2347 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2348 Move<VkPipelineLayout> m_pipelineLayout;
2349
2350 Move<VkShaderModule> m_vertexShaderModule;
2351 Move<VkShaderModule> m_fragmentShaderModule;
2352
2353 Move<VkDescriptorPool> m_descriptorPool;
2354 Move<VkDescriptorSet> m_descriptorSet;
2355 Move<VkBuffer> m_vertexBuffer;
2356 de::MovePtr<Allocation> m_vertexBufferMemory;
2357 vector<VkImage> m_colorAttachmentImages;
2358 VkImage m_depthStencilAttachmentImage;
2359 };
2360
pushImageInitializationCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,const vector<Attachment> & attachmentInfo,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,deUint32 queueIndex,const vector<Maybe<VkClearValue>> & clearValues)2361 void pushImageInitializationCommands (const DeviceInterface& vk,
2362 VkCommandBuffer commandBuffer,
2363 const vector<Attachment>& attachmentInfo,
2364 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2365 deUint32 queueIndex,
2366 const vector<Maybe<VkClearValue> >& clearValues)
2367 {
2368 {
2369 vector<VkImageMemoryBarrier> initializeLayouts;
2370
2371 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2372 {
2373 if (!clearValues[attachmentNdx])
2374 continue;
2375
2376 const VkImageMemoryBarrier barrier =
2377 {
2378 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2379 DE_NULL, // pNext;
2380
2381 (VkAccessFlags)0, // srcAccessMask
2382 getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
2383
2384 VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
2385 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout;
2386
2387 queueIndex, // srcQueueFamilyIndex;
2388 queueIndex, // destQueueFamilyIndex;
2389
2390 attachmentResources[attachmentNdx]->getImage(), // image;
2391 { // subresourceRange;
2392 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2393 0, // baseMipLevel;
2394 1, // mipLevels;
2395 0, // baseArraySlice;
2396 1 // arraySize;
2397 }
2398 };
2399
2400 initializeLayouts.push_back(barrier);
2401 }
2402
2403 if (!initializeLayouts.empty())
2404 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2405 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2406 0, (const VkMemoryBarrier*)DE_NULL,
2407 0, (const VkBufferMemoryBarrier*)DE_NULL,
2408 (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
2409 }
2410
2411 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2412 {
2413 if (!clearValues[attachmentNdx])
2414 continue;
2415
2416 const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());
2417
2418 if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
2419 {
2420 const float clearNan = tcu::Float32::nan().asFloat();
2421 const float clearDepth = hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
2422 const deUint32 clearStencil = hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
2423 const VkClearDepthStencilValue depthStencil =
2424 {
2425 clearDepth,
2426 clearStencil
2427 };
2428 const VkImageSubresourceRange range =
2429 {
2430 (VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
2431 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
2432 0,
2433 1,
2434 0,
2435 1
2436 };
2437
2438 vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
2439 }
2440 else
2441 {
2442 const VkImageSubresourceRange range =
2443 {
2444 VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask;
2445 0, // baseMipLevel;
2446 1, // mipLevels;
2447 0, // baseArrayLayer;
2448 1 // layerCount;
2449 };
2450 const VkClearColorValue clearColor = clearValues[attachmentNdx]->color;
2451
2452 vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
2453 }
2454 }
2455
2456 {
2457 vector<VkImageMemoryBarrier> renderPassLayouts;
2458
2459 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2460 {
2461 const VkImageLayout oldLayout = clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
2462 const VkImageMemoryBarrier barrier =
2463 {
2464 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType;
2465 DE_NULL, // pNext;
2466
2467 (oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0), // srcAccessMask
2468 getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()), // dstAccessMask
2469
2470 oldLayout, // oldLayout
2471 attachmentInfo[attachmentNdx].getInitialLayout(), // newLayout;
2472
2473 queueIndex, // srcQueueFamilyIndex;
2474 queueIndex, // destQueueFamilyIndex;
2475
2476 attachmentResources[attachmentNdx]->getImage(), // image;
2477 { // subresourceRange;
2478 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2479 0, // baseMipLevel;
2480 1, // mipLevels;
2481 0, // baseArraySlice;
2482 1 // arraySize;
2483 }
2484 };
2485
2486 renderPassLayouts.push_back(barrier);
2487 }
2488
2489 if (!renderPassLayouts.empty())
2490 vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2491 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
2492 0, (const VkMemoryBarrier*)DE_NULL,
2493 0, (const VkBufferMemoryBarrier*)DE_NULL,
2494 (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
2495 }
2496 }
2497
pushRenderPassCommands(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkRenderPass renderPass,VkFramebuffer framebuffer,const vector<de::SharedPtr<SubpassRenderer>> & subpassRenderers,const UVec2 & renderPos,const UVec2 & renderSize,const vector<Maybe<VkClearValue>> & renderPassClearValues,TestConfig::RenderTypes render)2498 void pushRenderPassCommands (const DeviceInterface& vk,
2499 VkCommandBuffer commandBuffer,
2500 VkRenderPass renderPass,
2501 VkFramebuffer framebuffer,
2502 const vector<de::SharedPtr<SubpassRenderer> >& subpassRenderers,
2503 const UVec2& renderPos,
2504 const UVec2& renderSize,
2505 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2506 TestConfig::RenderTypes render)
2507 {
2508 const float clearNan = tcu::Float32::nan().asFloat();
2509 vector<VkClearValue> attachmentClearValues;
2510
2511 for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
2512 {
2513 if (renderPassClearValues[attachmentNdx])
2514 attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
2515 else
2516 attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
2517 }
2518
2519 {
2520 const VkRect2D renderArea =
2521 {
2522 { (deInt32)renderPos.x(), (deInt32)renderPos.y() },
2523 { renderSize.x(), renderSize.y() }
2524 };
2525
2526 for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
2527 {
2528 const VkSubpassContents contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;
2529
2530 if (subpassNdx == 0)
2531 cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
2532 else
2533 vk.cmdNextSubpass(commandBuffer, contents);
2534
2535 if (render)
2536 {
2537 if (contents == VK_SUBPASS_CONTENTS_INLINE)
2538 {
2539 subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
2540 }
2541 else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
2542 {
2543 const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
2544 vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
2545 }
2546 else
2547 DE_FATAL("Invalid contents");
2548 }
2549 }
2550
2551 vk.cmdEndRenderPass(commandBuffer);
2552 }
2553 }
2554
pushReadImagesToBuffers(const DeviceInterface & vk,VkCommandBuffer commandBuffer,deUint32 queueIndex,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<Attachment> & attachmentInfo,const vector<bool> & isLazy,const UVec2 & targetSize)2555 void pushReadImagesToBuffers (const DeviceInterface& vk,
2556 VkCommandBuffer commandBuffer,
2557 deUint32 queueIndex,
2558
2559 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
2560 const vector<Attachment>& attachmentInfo,
2561 const vector<bool>& isLazy,
2562
2563 const UVec2& targetSize)
2564 {
2565 {
2566 vector<VkImageMemoryBarrier> imageBarriers;
2567
2568 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2569 {
2570 if (isLazy[attachmentNdx])
2571 continue;
2572
2573 const VkImageLayout oldLayout = attachmentInfo[attachmentNdx].getFinalLayout();
2574 const VkImageMemoryBarrier barrier =
2575 {
2576 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType
2577 DE_NULL, // pNext
2578
2579 getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout), // srcAccessMask
2580 getAllMemoryReadFlags(), // dstAccessMask
2581
2582 oldLayout, // oldLayout
2583 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
2584
2585 queueIndex, // srcQueueFamilyIndex
2586 queueIndex, // destQueueFamilyIndex
2587
2588 attachmentResources[attachmentNdx]->getImage(), // image
2589 { // subresourceRange
2590 getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()), // aspect;
2591 0, // baseMipLevel
2592 1, // mipLevels
2593 0, // baseArraySlice
2594 1 // arraySize
2595 }
2596 };
2597
2598 imageBarriers.push_back(barrier);
2599 }
2600
2601 if (!imageBarriers.empty())
2602 vk.cmdPipelineBarrier(commandBuffer,
2603 getAllPipelineStageFlags(),
2604 getAllPipelineStageFlags(),
2605 (VkDependencyFlags)0,
2606 0, (const VkMemoryBarrier*)DE_NULL,
2607 0, (const VkBufferMemoryBarrier*)DE_NULL,
2608 (deUint32)imageBarriers.size(), &imageBarriers[0]);
2609 }
2610
2611 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2612 {
2613 if (isLazy[attachmentNdx])
2614 continue;
2615
2616 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2617 const VkBufferImageCopy rect =
2618 {
2619 0, // bufferOffset
2620 0, // bufferRowLength
2621 0, // bufferImageHeight
2622 { // imageSubresource
2623 (vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order), // aspect
2624 0, // mipLevel
2625 0, // arraySlice
2626 1 // arraySize
2627 },
2628 { 0, 0, 0 }, // imageOffset
2629 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2630 };
2631
2632 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);
2633
2634 if (tcu::TextureFormat::DS == order)
2635 {
2636 const VkBufferImageCopy stencilRect =
2637 {
2638 0, // bufferOffset
2639 0, // bufferRowLength
2640 0, // bufferImageHeight
2641 { // imageSubresource
2642 VK_IMAGE_ASPECT_STENCIL_BIT, // aspect
2643 0, // mipLevel
2644 0, // arraySlice
2645 1 // arraySize
2646 },
2647 { 0, 0, 0 }, // imageOffset
2648 { targetSize.x(), targetSize.y(), 1u } // imageExtent
2649 };
2650
2651 vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
2652 }
2653 }
2654
2655 {
2656 vector<VkBufferMemoryBarrier> bufferBarriers;
2657
2658 for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
2659 {
2660 if (isLazy[attachmentNdx])
2661 continue;
2662
2663 const tcu::TextureFormat::ChannelOrder order = mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
2664 const VkBufferMemoryBarrier bufferBarrier =
2665 {
2666 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2667 DE_NULL,
2668
2669 getAllMemoryWriteFlags(),
2670 getAllMemoryReadFlags(),
2671
2672 queueIndex,
2673 queueIndex,
2674
2675 attachmentResources[attachmentNdx]->getBuffer(),
2676 0,
2677 attachmentResources[attachmentNdx]->getBufferSize()
2678 };
2679
2680 bufferBarriers.push_back(bufferBarrier);
2681
2682 if (tcu::TextureFormat::DS == order)
2683 {
2684 const VkBufferMemoryBarrier secondaryBufferBarrier =
2685 {
2686 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2687 DE_NULL,
2688
2689 getAllMemoryWriteFlags(),
2690 getAllMemoryReadFlags(),
2691
2692 queueIndex,
2693 queueIndex,
2694
2695 attachmentResources[attachmentNdx]->getSecondaryBuffer(),
2696 0,
2697 attachmentResources[attachmentNdx]->getSecondaryBufferSize()
2698 };
2699
2700 bufferBarriers.push_back(secondaryBufferBarrier);
2701 }
2702 }
2703
2704 if (!bufferBarriers.empty())
2705 vk.cmdPipelineBarrier(commandBuffer,
2706 getAllPipelineStageFlags(),
2707 getAllPipelineStageFlags(),
2708 (VkDependencyFlags)0,
2709 0, (const VkMemoryBarrier*)DE_NULL,
2710 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
2711 0, (const VkImageMemoryBarrier*)DE_NULL);
2712 }
2713 }
2714
2715 class PixelValue
2716 {
2717 public:
2718 PixelValue (const Maybe<bool>& x = nothing<bool>(),
2719 const Maybe<bool>& y = nothing<bool>(),
2720 const Maybe<bool>& z = nothing<bool>(),
2721 const Maybe<bool>& w = nothing<bool>());
2722
2723 void setUndefined (size_t ndx);
2724 void setValue (size_t ndx, bool value);
2725 Maybe<bool> getValue (size_t ndx) const;
2726
2727 private:
2728 deUint16 m_status;
2729 };
2730
PixelValue(const Maybe<bool> & x,const Maybe<bool> & y,const Maybe<bool> & z,const Maybe<bool> & w)2731 PixelValue::PixelValue (const Maybe<bool>& x,
2732 const Maybe<bool>& y,
2733 const Maybe<bool>& z,
2734 const Maybe<bool>& w)
2735 : m_status (0)
2736 {
2737 const Maybe<bool> values[] =
2738 {
2739 x, y, z, w
2740 };
2741
2742 for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
2743 {
2744 if (values[ndx])
2745 setValue(ndx, *values[ndx]);
2746 else
2747 setUndefined(ndx);
2748 }
2749
2750 DE_ASSERT(m_status <= 0xFFu);
2751 }
2752
setUndefined(size_t ndx)2753 void PixelValue::setUndefined (size_t ndx)
2754 {
2755 DE_ASSERT(ndx < 4);
2756 DE_ASSERT(m_status <= 0xFFu);
2757
2758 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
2759 DE_ASSERT(m_status <= 0xFFu);
2760 }
2761
setValue(size_t ndx,bool value)2762 void PixelValue::setValue (size_t ndx, bool value)
2763 {
2764 DE_ASSERT(ndx < 4);
2765 DE_ASSERT(m_status <= 0xFFu);
2766
2767 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2)));
2768
2769 if (value)
2770 m_status = (deUint16)(m_status | (deUint16)(0x1u << (ndx * 2 + 1)));
2771 else
2772 m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));
2773
2774 DE_ASSERT(m_status <= 0xFFu);
2775 }
2776
getValue(size_t ndx) const2777 Maybe<bool> PixelValue::getValue (size_t ndx) const
2778 {
2779 DE_ASSERT(ndx < 4);
2780 DE_ASSERT(m_status <= 0xFFu);
2781
2782 if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
2783 {
2784 return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
2785 }
2786 else
2787 return nothing<bool>();
2788 }
2789
clearReferenceValues(vector<PixelValue> & values,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size,const BVec4 & mask,const PixelValue & value)2790 void clearReferenceValues (vector<PixelValue>& values,
2791 const UVec2& targetSize,
2792 const UVec2& offset,
2793 const UVec2& size,
2794 const BVec4& mask,
2795 const PixelValue& value)
2796 {
2797 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2798 DE_ASSERT(offset.x() + size.x() <= targetSize.x());
2799 DE_ASSERT(offset.y() + size.y() <= targetSize.y());
2800
2801 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2802 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2803 {
2804 for (int compNdx = 0; compNdx < 4; compNdx++)
2805 {
2806 if (mask[compNdx])
2807 {
2808 if (value.getValue(compNdx))
2809 values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
2810 else
2811 values[x + y * targetSize.x()].setUndefined(compNdx);
2812 }
2813 }
2814 }
2815 }
2816
markUndefined(vector<PixelValue> & values,const BVec4 & mask,const UVec2 & targetSize,const UVec2 & offset,const UVec2 & size)2817 void markUndefined (vector<PixelValue>& values,
2818 const BVec4& mask,
2819 const UVec2& targetSize,
2820 const UVec2& offset,
2821 const UVec2& size)
2822 {
2823 DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
2824
2825 for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
2826 for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
2827 {
2828 for (int compNdx = 0; compNdx < 4; compNdx++)
2829 {
2830 if (mask[compNdx])
2831 values[x + y * targetSize.x()].setUndefined(compNdx);
2832 }
2833 }
2834 }
2835
clearValueToPixelValue(const VkClearValue & value,const tcu::TextureFormat & format)2836 PixelValue clearValueToPixelValue (const VkClearValue& value,
2837 const tcu::TextureFormat& format)
2838 {
2839 const bool isDepthAttachment = hasDepthComponent(format.order);
2840 const bool isStencilAttachment = hasStencilComponent(format.order);
2841 const bool isDepthOrStencilAttachment = isDepthAttachment || isStencilAttachment;
2842 PixelValue pixelValue;
2843
2844 if (isDepthOrStencilAttachment)
2845 {
2846 if (isDepthAttachment)
2847 {
2848 if (value.depthStencil.depth == 1.0f)
2849 pixelValue.setValue(0, true);
2850 else if (value.depthStencil.depth == 0.0f)
2851 pixelValue.setValue(0, false);
2852 else
2853 DE_FATAL("Unknown depth value");
2854 }
2855
2856 if (isStencilAttachment)
2857 {
2858 if (value.depthStencil.stencil == 0xFFu)
2859 pixelValue.setValue(1, true);
2860 else if (value.depthStencil.stencil == 0x0u)
2861 pixelValue.setValue(1, false);
2862 else
2863 DE_FATAL("Unknown stencil value");
2864 }
2865 }
2866 else
2867 {
2868 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
2869 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
2870
2871 switch (channelClass)
2872 {
2873 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2874 for (int i = 0; i < 4; i++)
2875 {
2876 if (channelMask[i])
2877 {
2878 if (value.color.int32[i] == 1)
2879 pixelValue.setValue(i, true);
2880 else if (value.color.int32[i] == 0)
2881 pixelValue.setValue(i, false);
2882 else
2883 DE_FATAL("Unknown clear color value");
2884 }
2885 }
2886 break;
2887
2888 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2889 for (int i = 0; i < 4; i++)
2890 {
2891 if (channelMask[i])
2892 {
2893 if (value.color.uint32[i] == 1u)
2894 pixelValue.setValue(i, true);
2895 else if (value.color.uint32[i] == 0u)
2896 pixelValue.setValue(i, false);
2897 else
2898 DE_FATAL("Unknown clear color value");
2899 }
2900 }
2901 break;
2902
2903 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2904 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2905 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2906 for (int i = 0; i < 4; i++)
2907 {
2908 if (channelMask[i])
2909 {
2910 if (value.color.float32[i] == 1.0f)
2911 pixelValue.setValue(i, true);
2912 else if (value.color.float32[i] == 0.0f)
2913 pixelValue.setValue(i, false);
2914 else
2915 DE_FATAL("Unknown clear color value");
2916 }
2917 }
2918 break;
2919
2920 default:
2921 DE_FATAL("Unknown channel class");
2922 }
2923 }
2924
2925 return pixelValue;
2926 }
2927
renderReferenceValues(vector<vector<PixelValue>> & referenceAttachments,const RenderPass & renderPassInfo,const UVec2 & targetSize,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & renderPos,const UVec2 & renderSize)2928 void renderReferenceValues (vector<vector<PixelValue> >& referenceAttachments,
2929 const RenderPass& renderPassInfo,
2930 const UVec2& targetSize,
2931 const vector<Maybe<VkClearValue> >& imageClearValues,
2932 const vector<Maybe<VkClearValue> >& renderPassClearValues,
2933 const vector<SubpassRenderInfo>& subpassRenderInfo,
2934 const UVec2& renderPos,
2935 const UVec2& renderSize)
2936 {
2937 const vector<Subpass>& subpasses = renderPassInfo.getSubpasses();
2938 vector<bool> attachmentUsed (renderPassInfo.getAttachments().size(), false);
2939
2940 referenceAttachments.resize(renderPassInfo.getAttachments().size());
2941
2942 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
2943 {
2944 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
2945 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2946 vector<PixelValue>& reference = referenceAttachments[attachmentNdx];
2947
2948 reference.resize(targetSize.x() * targetSize.y());
2949
2950 if (imageClearValues[attachmentNdx])
2951 clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
2952 }
2953
2954 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
2955 {
2956 const Subpass& subpass = subpasses[subpassNdx];
2957 const SubpassRenderInfo& renderInfo = subpassRenderInfo[subpassNdx];
2958 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
2959
2960 // Apply load op if attachment was used for the first time
2961 for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
2962 {
2963 const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();
2964
2965 if (!attachmentUsed[attachmentIndex])
2966 {
2967 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2968 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2969 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2970
2971 DE_ASSERT(!tcu::hasDepthComponent(format.order));
2972 DE_ASSERT(!tcu::hasStencilComponent(format.order));
2973
2974 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2975 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2976 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
2977 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
2978
2979 attachmentUsed[attachmentIndex] = true;
2980 }
2981 }
2982
2983 // Apply load op to depth/stencil attachment if it was used for the first time
2984 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
2985 {
2986 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
2987
2988 // Apply load op if attachment was used for the first time
2989 if (!attachmentUsed[attachmentIndex])
2990 {
2991 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
2992 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
2993 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
2994
2995 if (tcu::hasDepthComponent(format.order))
2996 {
2997 if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
2998 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
2999 else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3000 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3001 }
3002
3003 if (tcu::hasStencilComponent(format.order))
3004 {
3005 if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
3006 clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
3007 else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
3008 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3009 }
3010
3011 attachmentUsed[attachmentIndex] = true;
3012 }
3013 }
3014
3015 for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
3016 {
3017 const ColorClear& colorClear = renderInfo.getColorClears()[colorClearNdx];
3018 const UVec2 offset = colorClear.getOffset();
3019 const UVec2 size = colorClear.getSize();
3020 const deUint32 attachmentIndex = subpass.getColorAttachments()[colorClearNdx].getAttachment();
3021 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3022 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3023 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3024 VkClearValue value;
3025
3026 value.color = colorClear.getColor();
3027
3028 clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
3029 }
3030
3031 if (renderInfo.getDepthStencilClear())
3032 {
3033 const DepthStencilClear& dsClear = *renderInfo.getDepthStencilClear();
3034 const UVec2 offset = dsClear.getOffset();
3035 const UVec2 size = dsClear.getSize();
3036 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3037 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3038 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3039 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3040 const bool hasStencil = tcu::hasStencilComponent(format.order)
3041 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR;
3042 const bool hasDepth = tcu::hasDepthComponent(format.order)
3043 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR;
3044 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3045 VkClearValue value;
3046
3047 value.depthStencil.depth = dsClear.getDepth();
3048 value.depthStencil.stencil = dsClear.getStencil();
3049
3050 clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
3051 }
3052
3053 if (renderInfo.getRenderQuad())
3054 {
3055 const RenderQuad& renderQuad = *renderInfo.getRenderQuad();
3056 const Vec2 posA = renderQuad.getCornerA();
3057 const Vec2 posB = renderQuad.getCornerB();
3058 const Vec2 origin = Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3059 const Vec2 p = Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
3060 const IVec2 posAI (deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
3061 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
3062 const IVec2 posBI (deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
3063 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));
3064
3065 DE_ASSERT(posAI.x() < posBI.x());
3066 DE_ASSERT(posAI.y() < posBI.y());
3067
3068 if (subpass.getInputAttachments().empty())
3069 {
3070 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3071 {
3072 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3073 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3074 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3075 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(format);
3076 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3077
3078 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3079 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3080 {
3081 for (int compNdx = 0; compNdx < 4; compNdx++)
3082 {
3083 const size_t index = subpassNdx + attachmentIndex + compNdx;
3084 const BoolOp op = boolOpFromIndex(index);
3085 const bool boolX = x % 2 == (int)(index % 2);
3086 const bool boolY = y % 2 == (int)((index / 2) % 2);
3087
3088 if (channelMask[compNdx])
3089 reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
3090 }
3091 }
3092 }
3093
3094 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
3095 {
3096 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3097 const VkImageLayout layout = subpass.getDepthStencilAttachment().getImageLayout();
3098 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3099 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3100 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3101
3102 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3103 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3104 {
3105 if (tcu::hasDepthComponent(format.order)
3106 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3107 && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3108 {
3109 const size_t index = subpassNdx + 1;
3110 const BoolOp op = boolOpFromIndex(index);
3111 const bool boolX = x % 2 == (int)(index % 2);
3112 const bool boolY = y % 2 == (int)((index / 2) % 2);
3113
3114 reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
3115 }
3116
3117 if (tcu::hasStencilComponent(format.order)
3118 && layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3119 && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3120 {
3121 const size_t index = subpassNdx;
3122 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3123 }
3124 }
3125 }
3126 }
3127 else
3128 {
3129 size_t outputComponentCount = 0;
3130 vector<Maybe<bool> > inputs;
3131
3132 DE_ASSERT(posAI.x() < posBI.x());
3133 DE_ASSERT(posAI.y() < posBI.y());
3134
3135 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3136 {
3137 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3138 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3139 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3140 const int componentCount = tcu::getNumUsedChannels(format.order);
3141
3142 outputComponentCount += (size_t)componentCount;
3143 }
3144
3145 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3146 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3147 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3148 {
3149 const Attachment& attachment (renderPassInfo.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()]);
3150 const tcu::TextureFormat format (mapVkFormat(attachment.getFormat()));
3151
3152 if (tcu::hasDepthComponent(format.order))
3153 outputComponentCount++;
3154 }
3155
3156 if (outputComponentCount > 0)
3157 {
3158 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3159 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3160 {
3161 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
3162 {
3163 const deUint32 attachmentIndex = subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
3164 const VkImageLayout layout = subpass.getInputAttachments()[inputAttachmentNdx].getImageLayout();
3165 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3166 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3167 const int componentCount = tcu::getNumUsedChannels(format.order);
3168
3169 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3170 {
3171 if ((compNdx != 0 || layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3172 && (compNdx != 1 || layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR))
3173 {
3174 inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
3175 }
3176 }
3177 }
3178
3179 const size_t inputsPerOutput = inputs.size() >= outputComponentCount
3180 ? ((inputs.size() / outputComponentCount)
3181 + ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
3182 : 1;
3183
3184 size_t outputValueNdx = 0;
3185
3186 for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
3187 {
3188 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
3189 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3190 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3191 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3192 const int componentCount = tcu::getNumUsedChannels(format.order);
3193
3194 for (int compNdx = 0; compNdx < componentCount; compNdx++)
3195 {
3196 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3197 const BoolOp op = boolOpFromIndex(index);
3198 const bool boolX = x % 2 == (int)(index % 2);
3199 const bool boolY = y % 2 == (int)((index / 2) % 2);
3200 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3201
3202 for (size_t i = 0; i < inputsPerOutput; i++)
3203 {
3204 if (!output)
3205 break;
3206 else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
3207 output = tcu::nothing<bool>();
3208 else
3209 output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
3210 }
3211
3212 if (output)
3213 reference[x + y * targetSize.x()].setValue(compNdx, *output);
3214 else
3215 reference[x + y * targetSize.x()].setUndefined(compNdx);
3216 }
3217
3218 outputValueNdx += componentCount;
3219 }
3220
3221 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3222 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3223 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3224 {
3225 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3226 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3227 const size_t index = subpassNdx + attachmentIndex;
3228 const BoolOp op = boolOpFromIndex(index);
3229 const bool boolX = x % 2 == (int)(index % 2);
3230 const bool boolY = y % 2 == (int)((index / 2) % 2);
3231 Maybe<bool> output = tcu::just(performBoolOp(op, boolX, boolY));
3232
3233 for (size_t i = 0; i < inputsPerOutput; i++)
3234 {
3235 if (!output)
3236 break;
3237 else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
3238 output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
3239 else
3240 output = tcu::nothing<bool>();
3241 }
3242
3243 if (output)
3244 reference[x + y * targetSize.x()].setValue(0, *output);
3245 else
3246 reference[x + y * targetSize.x()].setUndefined(0);
3247 }
3248
3249 inputs.clear();
3250 }
3251 }
3252
3253 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3254 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3255 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3256 {
3257 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3258 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentIndex];
3259 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3260 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3261
3262 if (tcu::hasStencilComponent(format.order))
3263 {
3264 for (int y = posAI.y(); y < (int)posBI.y(); y++)
3265 for (int x = posAI.x(); x < (int)posBI.x(); x++)
3266 {
3267 const size_t index = subpassNdx;
3268 reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
3269 }
3270 }
3271 }
3272 }
3273 }
3274 }
3275
3276 // Mark all attachments that were used but not stored as undefined
3277 for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
3278 {
3279 const Attachment attachment = renderPassInfo.getAttachments()[attachmentIndex];
3280 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3281 vector<PixelValue>& reference = referenceAttachments[attachmentIndex];
3282 const bool isStencilAttachment = hasStencilComponent(format.order);
3283 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || isStencilAttachment;
3284
3285 if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3286 {
3287 if (isDepthOrStencilAttachment)
3288 markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
3289 else
3290 markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
3291 }
3292
3293 if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
3294 markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
3295 }
3296 }
3297
renderReferenceImagesFromValues(vector<tcu::TextureLevel> & referenceImages,const vector<vector<PixelValue>> & referenceValues,const UVec2 & targetSize,const RenderPass & renderPassInfo)3298 void renderReferenceImagesFromValues (vector<tcu::TextureLevel>& referenceImages,
3299 const vector<vector<PixelValue> >& referenceValues,
3300 const UVec2& targetSize,
3301 const RenderPass& renderPassInfo)
3302 {
3303 referenceImages.resize(referenceValues.size());
3304
3305 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3306 {
3307 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3308 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3309 const vector<PixelValue>& reference = referenceValues[attachmentNdx];
3310 const bool hasDepth = tcu::hasDepthComponent(format.order);
3311 const bool hasStencil = tcu::hasStencilComponent(format.order);
3312 const bool hasDepthOrStencil = hasDepth || hasStencil;
3313 tcu::TextureLevel& referenceImage = referenceImages[attachmentNdx];
3314
3315 referenceImage.setStorage(format, targetSize.x(), targetSize.y());
3316
3317 if (hasDepthOrStencil)
3318 {
3319 if (hasDepth)
3320 {
3321 const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));
3322
3323 for (deUint32 y = 0; y < targetSize.y(); y++)
3324 for (deUint32 x = 0; x < targetSize.x(); x++)
3325 {
3326 if (reference[x + y * targetSize.x()].getValue(0))
3327 {
3328 if (*reference[x + y * targetSize.x()].getValue(0))
3329 depthAccess.setPixDepth(1.0f, x, y);
3330 else
3331 depthAccess.setPixDepth(0.0f, x, y);
3332 }
3333 else // Fill with 3x3 grid
3334 depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
3335 }
3336 }
3337
3338 if (hasStencil)
3339 {
3340 const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));
3341
3342 for (deUint32 y = 0; y < targetSize.y(); y++)
3343 for (deUint32 x = 0; x < targetSize.x(); x++)
3344 {
3345 if (reference[x + y * targetSize.x()].getValue(1))
3346 {
3347 if (*reference[x + y * targetSize.x()].getValue(1))
3348 stencilAccess.setPixStencil(0xFFu, x, y);
3349 else
3350 stencilAccess.setPixStencil(0x0u, x, y);
3351 }
3352 else // Fill with 3x3 grid
3353 stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
3354 }
3355 }
3356 }
3357 else
3358 {
3359 for (deUint32 y = 0; y < targetSize.y(); y++)
3360 for (deUint32 x = 0; x < targetSize.x(); x++)
3361 {
3362 tcu::Vec4 color;
3363
3364 for (int compNdx = 0; compNdx < 4; compNdx++)
3365 {
3366 if (reference[x + y * targetSize.x()].getValue(compNdx))
3367 {
3368 if (*reference[x + y * targetSize.x()].getValue(compNdx))
3369 color[compNdx] = 1.0f;
3370 else
3371 color[compNdx] = 0.0f;
3372 }
3373 else // Fill with 3x3 grid
3374 color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
3375 }
3376
3377 referenceImage.getAccess().setPixel(color, x, y);
3378 }
3379 }
3380 }
3381 }
3382
verifyColorAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3383 bool verifyColorAttachment (const vector<PixelValue>& reference,
3384 const ConstPixelBufferAccess& result,
3385 const PixelBufferAccess& errorImage)
3386 {
3387 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3388 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3389 bool ok = true;
3390
3391 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3392 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3393 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3394
3395 for (int y = 0; y < result.getHeight(); y++)
3396 for (int x = 0; x < result.getWidth(); x++)
3397 {
3398 const Vec4 resultColor = result.getPixel(x, y);
3399 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3400 bool pixelOk = true;
3401
3402 for (int compNdx = 0; compNdx < 4; compNdx++)
3403 {
3404 const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);
3405
3406 if (maybeValue)
3407 {
3408 const bool value = *maybeValue;
3409
3410 if ((value && (resultColor[compNdx] != 1.0f))
3411 || (!value && resultColor[compNdx] != 0.0f))
3412 pixelOk = false;
3413 }
3414 }
3415
3416 if (!pixelOk)
3417 {
3418 errorImage.setPixel(red, x, y);
3419 ok = false;
3420 }
3421 else
3422 errorImage.setPixel(green, x, y);
3423 }
3424
3425 return ok;
3426 }
3427
verifyDepthAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3428 bool verifyDepthAttachment (const vector<PixelValue>& reference,
3429 const ConstPixelBufferAccess& result,
3430 const PixelBufferAccess& errorImage)
3431 {
3432 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3433 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3434 bool ok = true;
3435
3436 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3437 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3438 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3439
3440 for (int y = 0; y < result.getHeight(); y++)
3441 for (int x = 0; x < result.getWidth(); x++)
3442 {
3443 bool pixelOk = true;
3444
3445 const float resultDepth = result.getPixDepth(x, y);
3446 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3447 const Maybe<bool> maybeValue = referenceValue.getValue(0);
3448
3449 if (maybeValue)
3450 {
3451 const bool value = *maybeValue;
3452
3453 if ((value && (resultDepth != 1.0f))
3454 || (!value && resultDepth != 0.0f))
3455 pixelOk = false;
3456 }
3457
3458 if (!pixelOk)
3459 {
3460 errorImage.setPixel(red, x, y);
3461 ok = false;
3462 }
3463 else
3464 errorImage.setPixel(green, x, y);
3465 }
3466
3467 return ok;
3468 }
3469
verifyStencilAttachment(const vector<PixelValue> & reference,const ConstPixelBufferAccess & result,const PixelBufferAccess & errorImage)3470 bool verifyStencilAttachment (const vector<PixelValue>& reference,
3471 const ConstPixelBufferAccess& result,
3472 const PixelBufferAccess& errorImage)
3473 {
3474 const Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
3475 const Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3476 bool ok = true;
3477
3478 DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
3479 DE_ASSERT(result.getWidth() == errorImage.getWidth());
3480 DE_ASSERT(result.getHeight() == errorImage.getHeight());
3481
3482 for (int y = 0; y < result.getHeight(); y++)
3483 for (int x = 0; x < result.getWidth(); x++)
3484 {
3485 bool pixelOk = true;
3486
3487 const deUint32 resultStencil = result.getPixStencil(x, y);
3488 const PixelValue& referenceValue = reference[x + y * result.getWidth()];
3489 const Maybe<bool> maybeValue = referenceValue.getValue(1);
3490
3491 if (maybeValue)
3492 {
3493 const bool value = *maybeValue;
3494
3495 if ((value && (resultStencil != 0xFFu))
3496 || (!value && resultStencil != 0x0u))
3497 pixelOk = false;
3498 }
3499
3500 if (!pixelOk)
3501 {
3502 errorImage.setPixel(red, x, y);
3503 ok = false;
3504 }
3505 else
3506 errorImage.setPixel(green, x, y);
3507 }
3508
3509 return ok;
3510 }
3511
logAndVerifyImages(TestLog & log,const DeviceInterface & vk,VkDevice device,const vector<de::SharedPtr<AttachmentResources>> & attachmentResources,const vector<bool> & attachmentIsLazy,const RenderPass & renderPassInfo,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo,const UVec2 & targetSize,const TestConfig & config)3512 bool logAndVerifyImages (TestLog& log,
3513 const DeviceInterface& vk,
3514 VkDevice device,
3515 const vector<de::SharedPtr<AttachmentResources> >& attachmentResources,
3516 const vector<bool>& attachmentIsLazy,
3517 const RenderPass& renderPassInfo,
3518 const vector<Maybe<VkClearValue> >& renderPassClearValues,
3519 const vector<Maybe<VkClearValue> >& imageClearValues,
3520 const vector<SubpassRenderInfo>& subpassRenderInfo,
3521 const UVec2& targetSize,
3522 const TestConfig& config)
3523 {
3524 vector<vector<PixelValue> > referenceValues;
3525 vector<tcu::TextureLevel> referenceAttachments;
3526 bool isOk = true;
3527
3528 log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;
3529
3530 renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
3531 renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);
3532
3533 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
3534 {
3535 if (!attachmentIsLazy[attachmentNdx])
3536 {
3537 const Attachment attachment = renderPassInfo.getAttachments()[attachmentNdx];
3538 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3539
3540 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
3541 {
3542 const tcu::TextureFormat depthFormat = getDepthCopyFormat(attachment.getFormat());
3543 const VkDeviceSize depthBufferSize = targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
3544 void* const depthPtr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3545
3546 const tcu::TextureFormat stencilFormat = getStencilCopyFormat(attachment.getFormat());
3547 const VkDeviceSize stencilBufferSize = targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
3548 void* const stencilPtr = attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();
3549
3550 const VkMappedMemoryRange ranges[] =
3551 {
3552 {
3553 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3554 DE_NULL, // pNext;
3555 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3556 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3557 depthBufferSize // size;
3558 },
3559 {
3560 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3561 DE_NULL, // pNext;
3562 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(), // mem;
3563 attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(), // offset;
3564 stencilBufferSize // size;
3565 }
3566 };
3567 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));
3568
3569 {
3570 const ConstPixelBufferAccess depthAccess (depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
3571 const ConstPixelBufferAccess stencilAccess (stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
3572 tcu::TextureLevel depthErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3573 tcu::TextureLevel stencilErrorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3574
3575 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
3576 log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);
3577
3578 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3579
3580 if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3581 && !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
3582 {
3583 log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
3584 isOk = false;
3585 }
3586
3587 if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
3588 && !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
3589 {
3590 log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
3591 isOk = false;
3592 }
3593 }
3594 }
3595 else
3596 {
3597 const VkDeviceSize bufferSize = targetSize.x() * targetSize.y() * format.getPixelSize();
3598 void* const ptr = attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();
3599
3600 const VkMappedMemoryRange range =
3601 {
3602 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // sType;
3603 DE_NULL, // pNext;
3604 attachmentResources[attachmentNdx]->getResultMemory().getMemory(), // mem;
3605 attachmentResources[attachmentNdx]->getResultMemory().getOffset(), // offset;
3606 bufferSize // size;
3607 };
3608 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3609
3610 if (tcu::hasDepthComponent(format.order))
3611 {
3612 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3613 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3614
3615 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3616 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3617
3618 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3619 && !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3620 {
3621 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3622 isOk = false;
3623 }
3624 }
3625 else if (tcu::hasStencilComponent(format.order))
3626 {
3627 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3628 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3629
3630 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3631 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3632
3633 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3634 && !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3635 {
3636 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3637 isOk = false;
3638 }
3639 }
3640 else
3641 {
3642 const ConstPixelBufferAccess access (format, targetSize.x(), targetSize.y(), 1, ptr);
3643 tcu::TextureLevel errorImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
3644
3645 log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
3646 log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());
3647
3648 if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
3649 && !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
3650 {
3651 log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
3652 isOk = false;
3653 }
3654 }
3655 }
3656 }
3657 }
3658
3659 return isOk;
3660 }
3661
getInputAttachmentType(VkFormat vkFormat)3662 std::string getInputAttachmentType (VkFormat vkFormat)
3663 {
3664 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3665 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3666
3667 switch (channelClass)
3668 {
3669 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3670 return "isubpassInput";
3671
3672 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3673 return "usubpassInput";
3674
3675 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3676 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3677 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3678 return "subpassInput";
3679
3680 default:
3681 DE_FATAL("Unknown channel class");
3682 return "";
3683 }
3684 }
3685
getAttachmentType(VkFormat vkFormat)3686 std::string getAttachmentType (VkFormat vkFormat)
3687 {
3688 const tcu::TextureFormat format = mapVkFormat(vkFormat);
3689 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3690
3691 switch (channelClass)
3692 {
3693 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
3694 return "ivec4";
3695
3696 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
3697 return "uvec4";
3698
3699 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
3700 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
3701 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
3702 return "vec4";
3703
3704 default:
3705 DE_FATAL("Unknown channel class");
3706 return "";
3707 }
3708 }
3709
createTestShaders(SourceCollections & dst,TestConfig config)3710 void createTestShaders (SourceCollections& dst, TestConfig config)
3711 {
3712 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
3713 {
3714 const vector<Subpass>& subpasses = config.renderPass.getSubpasses();
3715
3716 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
3717 {
3718 const Subpass& subpass = subpasses[subpassNdx];
3719 deUint32 inputAttachmentBinding = 0;
3720 std::ostringstream vertexShader;
3721 std::ostringstream fragmentShader;
3722
3723 vertexShader << "#version 310 es\n"
3724 << "layout(location = 0) in highp vec2 a_position;\n"
3725 << "void main (void) {\n"
3726 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
3727 << "}\n";
3728
3729 fragmentShader << "#version 310 es\n"
3730 << "precision highp float;\n";
3731
3732 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3733 {
3734 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3735 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
3736 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3737 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3738 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3739 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3740
3741 if (isDepthFormat || isStencilFormat)
3742 {
3743 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3744 {
3745 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
3746 inputAttachmentBinding++;
3747 }
3748
3749 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3750 {
3751 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
3752 inputAttachmentBinding++;
3753 }
3754 }
3755 else
3756 {
3757 const std::string attachmentType = getInputAttachmentType(attachment.getFormat());
3758
3759 fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
3760 inputAttachmentBinding++;
3761 }
3762 }
3763
3764 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3765 {
3766 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
3767 fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
3768 }
3769
3770 fragmentShader << "void main (void) {\n";
3771
3772 if (subpass.getInputAttachments().empty())
3773 {
3774 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3775 {
3776 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3777 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3778
3779 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";
3780
3781 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3782 {
3783 const size_t index = subpassNdx + attachmentIndex + compNdx;
3784 const BoolOp op = boolOpFromIndex(index);
3785
3786 if (compNdx > 0)
3787 fragmentShader << ",\n\t\t";
3788
3789 fragmentShader << "((int(gl_FragCoord.x) % 2 == " << (index % 2)
3790 << ") " << boolOpToString(op) << " ("
3791 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3792 << ") ? 1.0 : 0.0)";
3793 }
3794
3795 fragmentShader << "));\n";
3796 }
3797
3798 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3799 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3800 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3801 {
3802 const size_t index = subpassNdx + 1;
3803 const BoolOp op = boolOpFromIndex(index);
3804
3805 fragmentShader << "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
3806 << ") " << boolOpToString(op) << " ("
3807 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3808 << ") ? 1.0 : 0.0);\n";
3809 }
3810 }
3811 else
3812 {
3813 size_t inputComponentCount = 0;
3814 size_t outputComponentCount = 0;
3815
3816 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3817 {
3818 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3819 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
3820 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3821 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3822 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3823
3824 if (layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3825 inputComponentCount += 1;
3826 else if (layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3827 inputComponentCount += 1;
3828 else
3829 inputComponentCount += componentCount;
3830 }
3831
3832 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3833 {
3834 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3835 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3836 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3837 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3838
3839 outputComponentCount += componentCount;
3840 }
3841
3842 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3843 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3844 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3845 {
3846 outputComponentCount++;
3847 }
3848
3849 if (outputComponentCount > 0)
3850 {
3851 const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
3852 ? ((inputComponentCount / outputComponentCount)
3853 + ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
3854 : 1;
3855
3856 fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n";
3857
3858 if (outputComponentCount > 0)
3859 fragmentShader << "\tbool outputs[" << outputComponentCount << "];\n";
3860
3861 size_t inputValueNdx = 0;
3862
3863 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
3864 {
3865 const char* const components[] =
3866 {
3867 "x", "y", "z", "w"
3868 };
3869 const deUint32 attachmentIndex = subpass.getInputAttachments()[attachmentNdx].getAttachment();
3870 const VkImageLayout layout = subpass.getInputAttachments()[attachmentNdx].getImageLayout();
3871 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3872 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3873 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3874 const bool isDepthFormat = tcu::hasDepthComponent(format.order);
3875 const bool isStencilFormat = tcu::hasStencilComponent(format.order);
3876
3877 if (isDepthFormat || isStencilFormat)
3878 {
3879 if (isDepthFormat && layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
3880 {
3881 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
3882 inputValueNdx++;
3883 }
3884
3885 if (isStencilFormat && layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3886 {
3887 fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
3888 inputValueNdx++;
3889 }
3890 }
3891 else
3892 {
3893 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3894 {
3895 fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
3896 inputValueNdx++;
3897 }
3898 }
3899 }
3900
3901 size_t outputValueNdx = 0;
3902
3903 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
3904 {
3905 const deUint32 attachmentIndex = subpass.getColorAttachments()[attachmentNdx].getAttachment();
3906 const Attachment attachment = config.renderPass.getAttachments()[attachmentIndex];
3907 const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
3908 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
3909 const size_t componentCount = (size_t)tcu::getNumUsedChannels(format.order);
3910
3911 for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
3912 {
3913 const size_t index = subpassNdx + attachmentIndex + outputValueNdx;
3914 const BoolOp op = boolOpFromIndex(index);
3915
3916 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
3917 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3918 << ") " << boolOpToString(op) << " ("
3919 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3920 << ");\n";
3921
3922 for (size_t i = 0; i < inputsPerOutput; i++)
3923 fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" << ((outputValueNdx + compNdx) * inputsPerOutput + i) % inputComponentCount << "];\n";
3924 }
3925
3926 fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";
3927
3928 for (size_t compNdx = 0; compNdx < 4; compNdx++)
3929 {
3930 if (compNdx > 0)
3931 fragmentShader << ", ";
3932
3933 if (compNdx < componentCount)
3934 fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
3935 else
3936 fragmentShader << "0";
3937 }
3938
3939 outputValueNdx += componentCount;
3940
3941 fragmentShader << ");\n";
3942 }
3943
3944 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED
3945 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
3946 && subpass.getDepthStencilAttachment().getImageLayout() != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
3947 {
3948 const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();
3949 const size_t index = subpassNdx + attachmentIndex;
3950 const BoolOp op = boolOpFromIndex(index);
3951
3952 fragmentShader << "\toutputs[" << outputValueNdx << "] = "
3953 << "(int(gl_FragCoord.x) % 2 == " << (index % 2)
3954 << ") " << boolOpToString(op) << " ("
3955 << "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
3956 << ");\n";
3957
3958 for (size_t i = 0; i < inputsPerOutput; i++)
3959 fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" << (outputValueNdx * inputsPerOutput + i) % inputComponentCount << "];\n";
3960
3961 fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
3962 }
3963 }
3964 }
3965
3966 fragmentShader << "}\n";
3967
3968 dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
3969 dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
3970 }
3971 }
3972 }
3973
initializeAttachmentIsLazy(vector<bool> & attachmentIsLazy,const vector<Attachment> & attachments,TestConfig::ImageMemory imageMemory)3974 void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
3975 {
3976 bool lastAttachmentWasLazy = false;
3977
3978 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
3979 {
3980 if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3981 && attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
3982 && attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
3983 && attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
3984 {
3985 if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
3986 {
3987 attachmentIsLazy.push_back(true);
3988
3989 lastAttachmentWasLazy = true;
3990 }
3991 else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
3992 {
3993 attachmentIsLazy.push_back(false);
3994 lastAttachmentWasLazy = false;
3995 }
3996 else
3997 DE_FATAL("Unknown imageMemory");
3998 }
3999 else
4000 attachmentIsLazy.push_back(false);
4001 }
4002 }
4003
4004 enum AttachmentRefType
4005 {
4006 ATTACHMENTREFTYPE_COLOR,
4007 ATTACHMENTREFTYPE_DEPTH_STENCIL,
4008 ATTACHMENTREFTYPE_INPUT,
4009 ATTACHMENTREFTYPE_RESOLVE,
4010 };
4011
getImageUsageFromLayout(VkImageLayout layout)4012 VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
4013 {
4014 switch (layout)
4015 {
4016 case VK_IMAGE_LAYOUT_GENERAL:
4017 case VK_IMAGE_LAYOUT_PREINITIALIZED:
4018 return 0;
4019
4020 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
4021 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4022
4023 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
4024 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
4025 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4026
4027 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
4028 return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4029
4030 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4031 return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4032
4033 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4034 return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4035
4036 default:
4037 DE_FATAL("Unexpected image layout");
4038 return 0;
4039 }
4040 }
4041
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,size_t count,const AttachmentReference * references)4042 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
4043 {
4044 for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
4045 {
4046 const deUint32 attachment = references[referenceNdx].getAttachment();
4047
4048 if (attachment != VK_ATTACHMENT_UNUSED)
4049 {
4050 VkImageUsageFlags usage;
4051
4052 switch (refType)
4053 {
4054 case ATTACHMENTREFTYPE_COLOR:
4055 case ATTACHMENTREFTYPE_RESOLVE:
4056 usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4057 break;
4058
4059 case ATTACHMENTREFTYPE_DEPTH_STENCIL:
4060 usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4061 break;
4062
4063 case ATTACHMENTREFTYPE_INPUT:
4064 usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4065 break;
4066
4067 default:
4068 DE_FATAL("Unexpected attachment reference type");
4069 usage = 0;
4070 break;
4071 }
4072
4073 attachmentImageUsage[attachment] |= usage;
4074 }
4075 }
4076 }
4077
getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags> & attachmentImageUsage,AttachmentRefType refType,const vector<AttachmentReference> & references)4078 void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
4079 {
4080 if (!references.empty())
4081 {
4082 getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
4083 }
4084 }
4085
initializeAttachmentImageUsage(Context & context,vector<VkImageUsageFlags> & attachmentImageUsage,const RenderPass & renderPassInfo,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & clearValues)4086 void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
4087 {
4088 attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));
4089
4090 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
4091 {
4092 const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];
4093
4094 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
4095 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
4096 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
4097 getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
4098 }
4099
4100 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4101 {
4102 const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
4103 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
4104 const VkFormatFeatureFlags supportedFeatures = formatProperties.optimalTilingFeatures;
4105
4106 if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4107 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;
4108
4109 if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4110 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;
4111
4112 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
4113 attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());
4114
4115 if (!attachmentIsLazy[attachmentNdx])
4116 {
4117 if (clearValues[attachmentNdx])
4118 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4119
4120 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4121 }
4122 else
4123 {
4124 const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
4125
4126 attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
4127 attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
4128 }
4129 }
4130 }
4131
initializeSubpassIsSecondary(vector<bool> & subpassIsSecondary,const vector<Subpass> & subpasses,TestConfig::CommandBufferTypes commandBuffer)4132 void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
4133 {
4134 bool lastSubpassWasSecondary = false;
4135
4136 for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
4137 {
4138 if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
4139 {
4140 subpassIsSecondary.push_back(true);
4141 lastSubpassWasSecondary = true;
4142 }
4143 else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
4144 {
4145 subpassIsSecondary.push_back(false);
4146 lastSubpassWasSecondary = false;
4147 }
4148 else
4149 DE_FATAL("Unknown commandBuffer");
4150 }
4151 }
4152
initializeImageClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments,const vector<bool> & isLazy)4153 void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
4154 {
4155 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4156 {
4157 if (!isLazy[attachmentNdx])
4158 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4159 else
4160 clearValues.push_back(nothing<VkClearValue>());
4161 }
4162 }
4163
initializeRenderPassClearValues(de::Random & rng,vector<Maybe<VkClearValue>> & clearValues,const vector<Attachment> & attachments)4164 void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
4165 {
4166 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4167 {
4168 if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
4169 || attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
4170 {
4171 clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
4172 }
4173 else
4174 clearValues.push_back(nothing<VkClearValue>());
4175 }
4176 }
4177
initializeSubpassClearValues(de::Random & rng,vector<vector<VkClearColorValue>> & clearValues,const RenderPass & renderPass)4178 void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
4179 {
4180 clearValues.resize(renderPass.getSubpasses().size());
4181
4182 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4183 {
4184 const Subpass& subpass = renderPass.getSubpasses()[subpassNdx];
4185 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4186
4187 clearValues[subpassNdx].resize(colorAttachments.size());
4188
4189 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4190 {
4191 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4192 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4193
4194 clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
4195 }
4196 }
4197 }
4198
logSubpassRenderInfo(TestLog & log,const SubpassRenderInfo & info)4199 void logSubpassRenderInfo (TestLog& log,
4200 const SubpassRenderInfo& info)
4201 {
4202 log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;
4203
4204 if (info.isSecondary())
4205 log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
4206 else
4207 log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;
4208
4209 for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
4210 {
4211 const ColorClear& colorClear = info.getColorClears()[attachmentNdx];
4212
4213 log << TestLog::Message << "Clearing color attachment " << attachmentNdx
4214 << ". Offset: " << colorClear.getOffset()
4215 << ", Size: " << colorClear.getSize()
4216 << ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
4217 }
4218
4219 if (info.getDepthStencilClear())
4220 {
4221 const DepthStencilClear& depthStencilClear = *info.getDepthStencilClear();
4222
4223 log << TestLog::Message << "Clearing depth stencil attachment"
4224 << ". Offset: " << depthStencilClear.getOffset()
4225 << ", Size: " << depthStencilClear.getSize()
4226 << ", Depth: " << depthStencilClear.getDepth()
4227 << ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
4228 }
4229
4230 if (info.getRenderQuad())
4231 {
4232 const RenderQuad& renderQuad = *info.getRenderQuad();
4233
4234 log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
4235 }
4236 }
4237
logTestCaseInfo(TestLog & log,const TestConfig & config,const vector<bool> & attachmentIsLazy,const vector<Maybe<VkClearValue>> & imageClearValues,const vector<Maybe<VkClearValue>> & renderPassClearValues,const vector<SubpassRenderInfo> & subpassRenderInfo)4238 void logTestCaseInfo (TestLog& log,
4239 const TestConfig& config,
4240 const vector<bool>& attachmentIsLazy,
4241 const vector<Maybe<VkClearValue> >& imageClearValues,
4242 const vector<Maybe<VkClearValue> >& renderPassClearValues,
4243 const vector<SubpassRenderInfo>& subpassRenderInfo)
4244 {
4245 const RenderPass& renderPass = config.renderPass;
4246
4247 logRenderPassInfo(log, renderPass);
4248
4249 DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
4250 DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
4251 DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());
4252
4253 log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
4254 log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;
4255
4256 for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
4257 {
4258 const tcu::ScopedLogSection section (log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
4259
4260 if (attachmentIsLazy[attachmentNdx])
4261 log << TestLog::Message << "Is lazy." << TestLog::EndMessage;
4262
4263 if (imageClearValues[attachmentNdx])
4264 log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;
4265
4266 if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
4267 log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
4268 }
4269
4270 for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
4271 {
4272 const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
4273
4274 logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
4275 }
4276 }
4277
roundToViewport(float x,deUint32 offset,deUint32 size)4278 float roundToViewport (float x, deUint32 offset, deUint32 size)
4279 {
4280 const float origin = (float)(offset) + ((float(size) / 2.0f));
4281 const float p = (float)(size) / 2.0f;
4282 const deInt32 xi = deRoundFloatToInt32(origin + (p * x));
4283
4284 return (((float)xi) - origin) / p;
4285 }
4286
initializeSubpassRenderInfo(vector<SubpassRenderInfo> & renderInfos,de::Random & rng,const RenderPass & renderPass,const TestConfig & config)4287 void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
4288 {
4289 const TestConfig::CommandBufferTypes commandBuffer = config.commandBufferTypes;
4290 const vector<Subpass>& subpasses = renderPass.getSubpasses();
4291 bool lastSubpassWasSecondary = false;
4292
4293 for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
4294 {
4295 const Subpass& subpass = subpasses[subpassNdx];
4296 const bool subpassIsSecondary = commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
4297 || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
4298 const UVec2 viewportSize ((config.renderSize * UVec2(2)) / UVec2(3));
4299 const UVec2 viewportOffset (config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
4300 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));
4301
4302 vector<ColorClear> colorClears;
4303 Maybe<DepthStencilClear> depthStencilClear;
4304 Maybe<RenderQuad> renderQuad;
4305
4306 lastSubpassWasSecondary = subpassIsSecondary;
4307
4308 if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
4309 {
4310 const vector<AttachmentReference>& colorAttachments = subpass.getColorAttachments();
4311
4312 for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
4313 {
4314 const AttachmentReference& attachmentRef = colorAttachments[attachmentRefNdx];
4315 const Attachment& attachment = renderPass.getAttachments()[attachmentRef.getAttachment()];
4316 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4317 const UVec2 offset (viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
4318 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
4319 const VkClearColorValue color = randomColorClearValue(attachment, rng);
4320
4321 colorClears.push_back(ColorClear(offset, size, color));
4322 }
4323
4324 if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
4325 {
4326 const Attachment& attachment = renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
4327 const UVec2 size ((viewportSize * UVec2(2)) / UVec2(3));
4328 const UVec2 offset (viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
4329 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
4330 const VkClearValue value = randomClearValue(attachment, rng);
4331
4332 depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
4333 }
4334 }
4335
4336 if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
4337 {
4338 const float w = (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
4339 const float h = (subpassNdx % 2) == 0 ? 1.25f : 1.0f;
4340
4341 const float x0 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
4342 const float x1 = roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());
4343
4344 const float y0 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
4345 const float y1 = roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());
4346
4347 renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
4348 }
4349
4350 renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
4351 }
4352 }
4353
checkTextureFormatSupport(TestLog & log,const InstanceInterface & vk,VkPhysicalDevice device,const vector<Attachment> & attachments)4354 void checkTextureFormatSupport (TestLog& log,
4355 const InstanceInterface& vk,
4356 VkPhysicalDevice device,
4357 const vector<Attachment>& attachments)
4358 {
4359 bool supported = true;
4360
4361 for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
4362 {
4363 const Attachment& attachment = attachments[attachmentNdx];
4364 const tcu::TextureFormat format = mapVkFormat(attachment.getFormat());
4365 const bool isDepthOrStencilAttachment = hasDepthComponent(format.order) || hasStencilComponent(format.order);
4366 const VkFormatFeatureFlags flags = isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
4367 VkFormatProperties properties;
4368
4369 vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);
4370
4371 if ((properties.optimalTilingFeatures & flags) != flags)
4372 {
4373 supported = false;
4374 log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
4375 }
4376 }
4377
4378 if (!supported)
4379 TCU_THROW(NotSupportedError, "Format not supported");
4380 }
4381
renderPassTest(Context & context,TestConfig config)4382 tcu::TestStatus renderPassTest (Context& context, TestConfig config)
4383 {
4384 const UVec2 targetSize = config.targetSize;
4385 const UVec2 renderPos = config.renderPos;
4386 const UVec2 renderSize = config.renderSize;
4387 const RenderPass& renderPassInfo = config.renderPass;
4388
4389 TestLog& log = context.getTestContext().getLog();
4390 de::Random rng (config.seed);
4391
4392 vector<bool> attachmentIsLazy;
4393 vector<VkImageUsageFlags> attachmentImageUsage;
4394 vector<Maybe<VkClearValue> > imageClearValues;
4395 vector<Maybe<VkClearValue> > renderPassClearValues;
4396
4397 vector<bool> subpassIsSecondary;
4398 vector<SubpassRenderInfo> subpassRenderInfo;
4399 vector<vector<VkClearColorValue> > subpassColorClearValues;
4400
4401 if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
4402 {
4403 const std::string extensionName("VK_KHR_dedicated_allocation");
4404
4405 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
4406 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
4407 }
4408
4409 if (!renderPassInfo.getInputAspects().empty())
4410 {
4411 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2")))
4412 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported.");
4413 }
4414
4415 {
4416 bool requireDepthStencilLayout = false;
4417
4418 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4419 {
4420 if (renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4421 || renderPassInfo.getAttachments()[attachmentNdx].getInitialLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR
4422 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4423 || renderPassInfo.getAttachments()[attachmentNdx].getFinalLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
4424 {
4425 requireDepthStencilLayout = true;
4426 break;
4427 }
4428 }
4429
4430 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size() && !requireDepthStencilLayout; subpassNdx++)
4431 {
4432 const Subpass& subpass (renderPassInfo.getSubpasses()[subpassNdx]);
4433
4434 for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
4435 {
4436 if (subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4437 || subpass.getColorAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
4438 {
4439 requireDepthStencilLayout = true;
4440 break;
4441 }
4442 }
4443
4444 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
4445 {
4446 if (subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4447 || subpass.getInputAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
4448 {
4449 requireDepthStencilLayout = true;
4450 break;
4451 }
4452 }
4453
4454 for (size_t attachmentNdx = 0; !requireDepthStencilLayout && attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
4455 {
4456 if (subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4457 || subpass.getResolveAttachments()[attachmentNdx].getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
4458 {
4459 requireDepthStencilLayout = true;
4460 break;
4461 }
4462 }
4463
4464 if (subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR
4465 || subpass.getDepthStencilAttachment().getImageLayout() == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)
4466 {
4467 requireDepthStencilLayout = true;
4468 break;
4469 }
4470 }
4471
4472 if (requireDepthStencilLayout && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_maintenance2")))
4473 TCU_THROW(NotSupportedError, "VK_KHR_maintenance2 is not supported");
4474 }
4475
4476 initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
4477 initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
4478 initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
4479 initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());
4480
4481 initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
4482 initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
4483 initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);
4484
4485 logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);
4486
4487 checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());
4488
4489 {
4490 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());
4491
4492 log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;
4493
4494 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4495 {
4496 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
4497 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
4498 }
4499 }
4500
4501 {
4502 const InstanceInterface& vki = context.getInstanceInterface();
4503 const VkPhysicalDevice& physDevice = context.getPhysicalDevice();
4504 const VkDevice device = context.getDevice();
4505 const DeviceInterface& vk = context.getDeviceInterface();
4506 const VkQueue queue = context.getUniversalQueue();
4507 const deUint32 queueIndex = context.getUniversalQueueFamilyIndex();
4508 Allocator& allocator = context.getDefaultAllocator();
4509
4510 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, renderPassInfo));
4511 const Unique<VkCommandPool> commandBufferPool (createCommandPool(vk, device, queueIndex, 0));
4512 const Unique<VkCommandBuffer> initializeImagesCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4513 const Unique<VkCommandBuffer> renderCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4514 const Unique<VkCommandBuffer> readImagesToBuffersCommandBuffer (allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4515
4516 vector<de::SharedPtr<AttachmentResources> > attachmentResources;
4517 vector<de::SharedPtr<SubpassRenderer> > subpassRenderers;
4518 vector<VkImage> attachmentImages;
4519 vector<VkImageView> attachmentViews;
4520 vector<pair<VkImageView, VkImageView> > inputAttachmentViews;
4521
4522 for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
4523 {
4524 const Attachment& attachmentInfo = renderPassInfo.getAttachments()[attachmentNdx];
4525
4526 attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
4527 attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
4528 attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());
4529
4530 inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
4531 }
4532
4533 beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4534 pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
4535 endCommandBuffer(vk, *initializeImagesCommandBuffer);
4536
4537 {
4538 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));
4539
4540 for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
4541 subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments(), config.allocationKind)));
4542
4543 beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4544 pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
4545 endCommandBuffer(vk, *renderCommandBuffer);
4546
4547 beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
4548 pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
4549 endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
4550 {
4551 const VkCommandBuffer commandBuffers[] =
4552 {
4553 *initializeImagesCommandBuffer,
4554 *renderCommandBuffer,
4555 *readImagesToBuffersCommandBuffer
4556 };
4557 const Unique<VkFence> fence (createFence(vk, device, 0u));
4558
4559 queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
4560 waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
4561 }
4562 }
4563
4564 if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
4565 return tcu::TestStatus::pass("Pass");
4566 else
4567 return tcu::TestStatus::fail("Result verification failed");
4568 }
4569 }
4570
4571 static const VkFormat s_coreColorFormats[] =
4572 {
4573 VK_FORMAT_R5G6B5_UNORM_PACK16,
4574 VK_FORMAT_R8_UNORM,
4575 VK_FORMAT_R8_SNORM,
4576 VK_FORMAT_R8_UINT,
4577 VK_FORMAT_R8_SINT,
4578 VK_FORMAT_R8G8_UNORM,
4579 VK_FORMAT_R8G8_SNORM,
4580 VK_FORMAT_R8G8_UINT,
4581 VK_FORMAT_R8G8_SINT,
4582 VK_FORMAT_R8G8B8A8_UNORM,
4583 VK_FORMAT_R8G8B8A8_SNORM,
4584 VK_FORMAT_R8G8B8A8_UINT,
4585 VK_FORMAT_R8G8B8A8_SINT,
4586 VK_FORMAT_R8G8B8A8_SRGB,
4587 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4588 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4589 VK_FORMAT_A8B8G8R8_UINT_PACK32,
4590 VK_FORMAT_A8B8G8R8_SINT_PACK32,
4591 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4592 VK_FORMAT_B8G8R8A8_UNORM,
4593 VK_FORMAT_B8G8R8A8_SRGB,
4594 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4595 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4596 VK_FORMAT_A2B10G10R10_UINT_PACK32,
4597 VK_FORMAT_R16_UNORM,
4598 VK_FORMAT_R16_SNORM,
4599 VK_FORMAT_R16_UINT,
4600 VK_FORMAT_R16_SINT,
4601 VK_FORMAT_R16_SFLOAT,
4602 VK_FORMAT_R16G16_UNORM,
4603 VK_FORMAT_R16G16_SNORM,
4604 VK_FORMAT_R16G16_UINT,
4605 VK_FORMAT_R16G16_SINT,
4606 VK_FORMAT_R16G16_SFLOAT,
4607 VK_FORMAT_R16G16B16A16_UNORM,
4608 VK_FORMAT_R16G16B16A16_SNORM,
4609 VK_FORMAT_R16G16B16A16_UINT,
4610 VK_FORMAT_R16G16B16A16_SINT,
4611 VK_FORMAT_R16G16B16A16_SFLOAT,
4612 VK_FORMAT_R32_UINT,
4613 VK_FORMAT_R32_SINT,
4614 VK_FORMAT_R32_SFLOAT,
4615 VK_FORMAT_R32G32_UINT,
4616 VK_FORMAT_R32G32_SINT,
4617 VK_FORMAT_R32G32_SFLOAT,
4618 VK_FORMAT_R32G32B32A32_UINT,
4619 VK_FORMAT_R32G32B32A32_SINT,
4620 VK_FORMAT_R32G32B32A32_SFLOAT
4621 };
4622
4623 static const VkFormat s_coreDepthStencilFormats[] =
4624 {
4625 VK_FORMAT_D16_UNORM,
4626
4627 VK_FORMAT_X8_D24_UNORM_PACK32,
4628 VK_FORMAT_D32_SFLOAT,
4629
4630 VK_FORMAT_D24_UNORM_S8_UINT,
4631 VK_FORMAT_D32_SFLOAT_S8_UINT
4632 };
4633
addAttachmentTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4634 void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4635 {
4636 const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
4637 const VkAttachmentLoadOp loadOps[] =
4638 {
4639 VK_ATTACHMENT_LOAD_OP_LOAD,
4640 VK_ATTACHMENT_LOAD_OP_CLEAR,
4641 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4642 };
4643
4644 const VkAttachmentStoreOp storeOps[] =
4645 {
4646 VK_ATTACHMENT_STORE_OP_STORE,
4647 VK_ATTACHMENT_STORE_OP_DONT_CARE
4648 };
4649
4650 const VkImageLayout initialAndFinalColorLayouts[] =
4651 {
4652 VK_IMAGE_LAYOUT_GENERAL,
4653 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4654 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4655 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4656 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4657 };
4658
4659 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4660 {
4661 VK_IMAGE_LAYOUT_GENERAL,
4662 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4663 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4664 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4665 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4666 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4667 };
4668
4669 const VkImageLayout subpassLayouts[] =
4670 {
4671 VK_IMAGE_LAYOUT_GENERAL,
4672 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
4673 };
4674
4675 const VkImageLayout depthStencilLayouts[] =
4676 {
4677 VK_IMAGE_LAYOUT_GENERAL,
4678 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
4679 };
4680
4681 const TestConfig::RenderTypes renderCommands[] =
4682 {
4683 TestConfig::RENDERTYPES_NONE,
4684 TestConfig::RENDERTYPES_CLEAR,
4685 TestConfig::RENDERTYPES_DRAW,
4686 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4687 };
4688
4689 const TestConfig::CommandBufferTypes commandBuffers[] =
4690 {
4691 TestConfig::COMMANDBUFFERTYPES_INLINE,
4692 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4693 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4694 };
4695
4696 const TestConfig::ImageMemory imageMemories[] =
4697 {
4698 TestConfig::IMAGEMEMORY_STRICT,
4699 TestConfig::IMAGEMEMORY_LAZY,
4700 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4701 };
4702
4703 const UVec2 targetSizes[] =
4704 {
4705 UVec2(64, 64),
4706 UVec2(63, 65)
4707 };
4708
4709 const UVec2 renderPositions[] =
4710 {
4711 UVec2(0, 0),
4712 UVec2(3, 17)
4713 };
4714
4715 const UVec2 renderSizes[] =
4716 {
4717 UVec2(32, 32),
4718 UVec2(60, 47)
4719 };
4720
4721 tcu::TestContext& testCtx = group->getTestContext();
4722 de::Random rng (1433774382u);
4723
4724 for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
4725 {
4726 const deUint32 attachmentCount = attachmentCounts[attachmentCountNdx];
4727 const deUint32 testCaseCount = (attachmentCount == 1 ? 100 : 200);
4728 de::MovePtr<tcu::TestCaseGroup> attachmentCountGroup (new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));
4729
4730 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4731 {
4732 const bool useDepthStencil = rng.getBool();
4733 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_GENERAL;
4734 vector<Attachment> attachments;
4735 vector<AttachmentReference> colorAttachmentReferences;
4736
4737 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4738 {
4739 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4740 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4741 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4742 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4743
4744 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4745 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4746 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
4747
4748 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4749 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4750
4751 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4752 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
4753 }
4754
4755 if (useDepthStencil)
4756 {
4757 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4758 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4759 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4760 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4761
4762 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4763 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
4764
4765 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4766 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4767
4768 depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
4769 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4770 }
4771
4772 {
4773 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
4774 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
4775 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
4776 const vector<Subpass> subpasses (1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
4777 const vector<SubpassDependency> deps;
4778
4779 const string testCaseName = de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
4780 const RenderPass renderPass (attachments, subpasses, deps);
4781 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
4782 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
4783 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
4784
4785 addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind));
4786 }
4787 }
4788
4789 group->addChild(attachmentCountGroup.release());
4790 }
4791 }
4792
4793 template<typename T>
chooseRandom(de::Random & rng,const set<T> & values)4794 T chooseRandom (de::Random& rng, const set<T>& values)
4795 {
4796 size_t ndx = ((size_t)rng.getUint32()) % values.size();
4797 typename set<T>::const_iterator iter = values.begin();
4798
4799 for (; ndx > 0; ndx--)
4800 iter++;
4801
4802 return *iter;
4803 }
4804
addAttachmentAllocationTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4805 void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4806 {
4807 const deUint32 attachmentCounts[] = { 4, 8 };
4808 const VkAttachmentLoadOp loadOps[] =
4809 {
4810 VK_ATTACHMENT_LOAD_OP_LOAD,
4811 VK_ATTACHMENT_LOAD_OP_CLEAR,
4812 VK_ATTACHMENT_LOAD_OP_DONT_CARE
4813 };
4814
4815 const VkAttachmentStoreOp storeOps[] =
4816 {
4817 VK_ATTACHMENT_STORE_OP_STORE,
4818 VK_ATTACHMENT_STORE_OP_DONT_CARE
4819 };
4820
4821 const VkImageLayout initialAndFinalColorLayouts[] =
4822 {
4823 VK_IMAGE_LAYOUT_GENERAL,
4824 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4825 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4826 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4827 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4828 };
4829
4830 const VkImageLayout initialAndFinalDepthStencilLayouts[] =
4831 {
4832 VK_IMAGE_LAYOUT_GENERAL,
4833 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4834 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4835 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
4836 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4837 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
4838 };
4839
4840 const VkImageLayout subpassLayouts[] =
4841 {
4842 VK_IMAGE_LAYOUT_GENERAL,
4843 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
4844 };
4845
4846 enum AllocationType
4847 {
4848 // Each pass uses one more attachmen than previous one
4849 ALLOCATIONTYPE_GROW,
4850 // Each pass uses one less attachment than previous one
4851 ALLOCATIONTYPE_SHRINK,
4852 // Each pass drops one attachment and picks up new one
4853 ALLOCATIONTYPE_ROLL,
4854 // Start by growing and end by shrinking
4855 ALLOCATIONTYPE_GROW_SHRINK,
4856 // Each subpass has single input and single output attachment
4857 ALLOCATIONTYPE_IO_CHAIN,
4858 // Each subpass has multiple inputs and multiple outputs attachment
4859 ALLOCATIONTYPE_IO_GENERIC
4860 };
4861
4862 const AllocationType allocationTypes[] =
4863 {
4864 ALLOCATIONTYPE_GROW,
4865 ALLOCATIONTYPE_SHRINK,
4866 ALLOCATIONTYPE_ROLL,
4867 ALLOCATIONTYPE_GROW_SHRINK,
4868 ALLOCATIONTYPE_IO_CHAIN,
4869 ALLOCATIONTYPE_IO_GENERIC
4870 };
4871
4872 const char* const allocationTypeStr[] =
4873 {
4874 "grow",
4875 "shrink",
4876 "roll",
4877 "grow_shrink",
4878 "input_output_chain",
4879 "input_output",
4880 };
4881
4882 const TestConfig::RenderTypes renderCommands[] =
4883 {
4884 TestConfig::RENDERTYPES_NONE,
4885 TestConfig::RENDERTYPES_CLEAR,
4886 TestConfig::RENDERTYPES_DRAW,
4887 TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
4888 };
4889
4890 const TestConfig::CommandBufferTypes commandBuffers[] =
4891 {
4892 TestConfig::COMMANDBUFFERTYPES_INLINE,
4893 TestConfig::COMMANDBUFFERTYPES_SECONDARY,
4894 TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
4895 };
4896
4897 const TestConfig::ImageMemory imageMemories[] =
4898 {
4899 TestConfig::IMAGEMEMORY_STRICT,
4900 TestConfig::IMAGEMEMORY_LAZY,
4901 TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
4902 };
4903
4904 const UVec2 targetSizes[] =
4905 {
4906 UVec2(64, 64),
4907 UVec2(63, 65)
4908 };
4909
4910 const UVec2 renderPositions[] =
4911 {
4912 UVec2(0, 0),
4913 UVec2(3, 17)
4914 };
4915
4916 const UVec2 renderSizes[] =
4917 {
4918 UVec2(32, 32),
4919 UVec2(60, 47)
4920 };
4921
4922 tcu::TestContext& testCtx = group->getTestContext();
4923 de::Random rng (3700649827u);
4924
4925 for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
4926 {
4927 const AllocationType allocationType = allocationTypes[allocationTypeNdx];
4928 const size_t testCaseCount = 100;
4929 de::MovePtr<tcu::TestCaseGroup> allocationTypeGroup (new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));
4930
4931 for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
4932 {
4933 if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
4934 {
4935 const deUint32 attachmentCount = 4u + rng.getUint32() % 31u;
4936 const deUint32 subpassCount = 4u + rng.getUint32() % 31u;
4937 vector<Attachment> attachments;
4938
4939 set<deUint32> definedAttachments;
4940
4941 vector<Subpass> subpasses;
4942 set<deUint32> colorAttachments;
4943 set<deUint32> depthStencilAttachments;
4944
4945 for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
4946 {
4947 const bool isDepthStencilAttachment = rng.getFloat() < 0.01f;
4948 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4949 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4950 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4951
4952 const VkImageLayout initialLayout = isDepthStencilAttachment
4953 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4954 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4955 const VkImageLayout finalizeLayout = isDepthStencilAttachment
4956 ? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
4957 : rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
4958
4959 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
4960 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
4961
4962 if (isDepthStencilAttachment)
4963 {
4964 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
4965
4966 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
4967 || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4968 definedAttachments.insert(attachmentIndex);
4969
4970 depthStencilAttachments.insert(attachmentIndex);
4971
4972 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4973 }
4974 else
4975 {
4976 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
4977
4978 if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
4979 definedAttachments.insert(attachmentIndex);
4980
4981 colorAttachments.insert(attachmentIndex);
4982
4983 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
4984 }
4985 }
4986 vector<Maybe<deUint32> > lastUseOfAttachment (attachments.size(), nothing<deUint32>());
4987 vector<SubpassDependency> deps;
4988
4989 for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
4990 {
4991 const deUint32 colorAttachmentCount = depthStencilAttachments.empty()
4992 ? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
4993 : rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
4994 const deUint32 inputAttachmentCount = rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
4995 const bool useDepthStencilAttachment = !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
4996 std::vector<deUint32> subpassColorAttachments (colorAttachmentCount);
4997 std::vector<deUint32> subpassInputAttachments (inputAttachmentCount);
4998 Maybe<deUint32> depthStencilAttachment (useDepthStencilAttachment
4999 ? just(chooseRandom(rng, depthStencilAttachments))
5000 : nothing<deUint32>());
5001 std::vector<deUint32> subpassPreserveAttachments;
5002
5003 rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
5004 rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);
5005
5006 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5007 definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);
5008
5009 if (depthStencilAttachment)
5010 definedAttachments.insert(*depthStencilAttachment);
5011
5012 {
5013 std::vector<AttachmentReference> inputAttachmentReferences;
5014 std::vector<AttachmentReference> colorAttachmentReferences;
5015 AttachmentReference depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5016
5017 for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
5018 {
5019 const deUint32 colorAttachmentIndex = subpassColorAttachments[colorAttachmentNdx];
5020 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
5021 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
5022
5023 if (lastUseOfAttachment[colorAttachmentIndex])
5024 {
5025 const bool byRegion = rng.getBool();
5026
5027 deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
5028 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5029 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5030 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5031 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5032
5033 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5034 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5035 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5036 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5037
5038 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5039 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5040
5041 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5042 }
5043
5044 lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);
5045
5046 colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
5047 }
5048
5049 for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
5050 {
5051 const deUint32 inputAttachmentIndex = subpassInputAttachments[inputAttachmentNdx];
5052 // \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
5053 const VkImageLayout subpassLayout = VK_IMAGE_LAYOUT_GENERAL;
5054
5055 if(lastUseOfAttachment[inputAttachmentIndex])
5056 {
5057 if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
5058 {
5059 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
5060 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5061 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5062 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5063 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5064
5065 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5066 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5067 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5068 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5069
5070 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5071 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5072
5073 VK_DEPENDENCY_BY_REGION_BIT));
5074 }
5075 else
5076 {
5077 const bool byRegion = rng.getBool();
5078
5079 deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
5080 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5081 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5082 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5083 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5084
5085 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5086 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5087 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5088 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5089
5090 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5091 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5092
5093 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5094 }
5095
5096 lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);
5097
5098 inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
5099 }
5100 }
5101
5102 if (depthStencilAttachment)
5103 {
5104 // \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
5105 if (lastUseOfAttachment[*depthStencilAttachment])
5106 {
5107 if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
5108 {
5109 deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
5110 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5111 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5112 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5113 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5114
5115 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5116 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5117 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5118 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5119
5120 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5121 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5122
5123 VK_DEPENDENCY_BY_REGION_BIT));
5124 }
5125 else
5126 {
5127 const bool byRegion = rng.getBool();
5128
5129 deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
5130 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5131 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5132 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5133 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5134
5135 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5136 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5137 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5138 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5139
5140 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
5141 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5142
5143 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5144 }
5145 }
5146
5147 lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
5148 depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
5149 }
5150 else
5151 depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);
5152
5153 vector<deUint32> preserveAttachments;
5154 for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
5155 {
5156 if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
5157 preserveAttachments.push_back(attachmentIndex);
5158 }
5159
5160 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5161 inputAttachmentReferences,
5162 colorAttachmentReferences,
5163 vector<AttachmentReference>(),
5164 depthStencilAttachmentReference,
5165 preserveAttachments));
5166 }
5167 }
5168 {
5169 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5170 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5171 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5172
5173 const string testCaseName = de::toString(testCaseNdx);
5174 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5175 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5176 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5177
5178 const RenderPass renderPass (attachments, subpasses, deps);
5179
5180 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
5181 }
5182 }
5183 else
5184 {
5185 const deUint32 attachmentCount = rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
5186 vector<Attachment> attachments;
5187 vector<Subpass> subpasses;
5188
5189 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
5190 {
5191 const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
5192 const VkFormat format = rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
5193 const VkAttachmentLoadOp loadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5194 const VkAttachmentStoreOp storeOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5195
5196 const VkImageLayout initialLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5197 const VkImageLayout finalizeLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
5198
5199 const VkAttachmentLoadOp stencilLoadOp = rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
5200 const VkAttachmentStoreOp stencilStoreOp = rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));
5201
5202 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
5203 }
5204
5205 if (allocationType == ALLOCATIONTYPE_GROW)
5206 {
5207 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5208 {
5209 vector<AttachmentReference> colorAttachmentReferences;
5210
5211 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5212 {
5213 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5214
5215 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5216 }
5217
5218 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5219 vector<AttachmentReference>(),
5220 colorAttachmentReferences,
5221 vector<AttachmentReference>(),
5222 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5223 vector<deUint32>()));
5224 }
5225 }
5226 else if (allocationType == ALLOCATIONTYPE_SHRINK)
5227 {
5228 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5229 {
5230 vector<AttachmentReference> colorAttachmentReferences;
5231
5232 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5233 {
5234 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5235
5236 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5237 }
5238
5239 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5240 vector<AttachmentReference>(),
5241 colorAttachmentReferences,
5242 vector<AttachmentReference>(),
5243 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5244 vector<deUint32>()));
5245 }
5246 }
5247 else if (allocationType == ALLOCATIONTYPE_ROLL)
5248 {
5249 for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
5250 {
5251 vector<AttachmentReference> colorAttachmentReferences;
5252
5253 for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
5254 {
5255 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5256
5257 colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
5258 }
5259
5260 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5261 vector<AttachmentReference>(),
5262 colorAttachmentReferences,
5263 vector<AttachmentReference>(),
5264 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5265 vector<deUint32>()));
5266 }
5267 }
5268 else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
5269 {
5270 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5271 {
5272 vector<AttachmentReference> colorAttachmentReferences;
5273
5274 for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
5275 {
5276 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5277
5278 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5279 }
5280
5281 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5282 vector<AttachmentReference>(),
5283 colorAttachmentReferences,
5284 vector<AttachmentReference>(),
5285 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5286 vector<deUint32>()));
5287 }
5288
5289 for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
5290 {
5291 vector<AttachmentReference> colorAttachmentReferences;
5292
5293 for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
5294 {
5295 const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));
5296
5297 colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
5298 }
5299
5300 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5301 vector<AttachmentReference>(),
5302 colorAttachmentReferences,
5303 vector<AttachmentReference>(),
5304 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5305 vector<deUint32>()));
5306 }
5307 }
5308 else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
5309 {
5310 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5311 vector<AttachmentReference>(),
5312 vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5313 vector<AttachmentReference>(),
5314 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5315 vector<deUint32>()));
5316
5317 for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
5318 {
5319 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
5320 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5321 vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
5322 vector<AttachmentReference>(),
5323 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5324 vector<deUint32>()));
5325 }
5326 }
5327 else
5328 DE_FATAL("Unknown allocation type");
5329
5330 {
5331 const TestConfig::RenderTypes render = rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
5332 const TestConfig::CommandBufferTypes commandBuffer = rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
5333 const TestConfig::ImageMemory imageMemory = rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
5334
5335 const string testCaseName = de::toString(testCaseNdx);
5336 const UVec2 targetSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
5337 const UVec2 renderPos = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
5338 const UVec2 renderSize = rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));
5339
5340 vector<SubpassDependency> deps;
5341
5342 for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
5343 {
5344 const bool byRegion = rng.getBool();
5345 deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
5346 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5347 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5348 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5349 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5350
5351 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
5352 | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
5353 | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
5354 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
5355
5356 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5357 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
5358
5359 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
5360 }
5361
5362 const RenderPass renderPass (attachments, subpasses, deps);
5363
5364 addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
5365 }
5366 }
5367 }
5368 group->addChild(allocationTypeGroup.release());
5369 }
5370 }
5371
addSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5372 void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5373 {
5374 const UVec2 targetSize (64, 64);
5375 const UVec2 renderPos (0, 0);
5376 const UVec2 renderSize (64, 64);
5377
5378 // color
5379 {
5380 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5381 VK_SAMPLE_COUNT_1_BIT,
5382 VK_ATTACHMENT_LOAD_OP_CLEAR,
5383 VK_ATTACHMENT_STORE_OP_STORE,
5384 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5385 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5386 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5387 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5388 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5389 0u,
5390 vector<AttachmentReference>(),
5391 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5392 vector<AttachmentReference>(),
5393 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5394 vector<deUint32>())),
5395 vector<SubpassDependency>());
5396
5397 addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5398 }
5399
5400 // depth
5401 {
5402 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5403 VK_SAMPLE_COUNT_1_BIT,
5404 VK_ATTACHMENT_LOAD_OP_CLEAR,
5405 VK_ATTACHMENT_STORE_OP_STORE,
5406 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5407 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5408 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5409 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5410 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5411 0u,
5412 vector<AttachmentReference>(),
5413 vector<AttachmentReference>(),
5414 vector<AttachmentReference>(),
5415 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5416 vector<deUint32>())),
5417 vector<SubpassDependency>());
5418
5419 addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5420 }
5421
5422 // stencil
5423 {
5424 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
5425 VK_SAMPLE_COUNT_1_BIT,
5426 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5427 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5428 VK_ATTACHMENT_LOAD_OP_CLEAR,
5429 VK_ATTACHMENT_STORE_OP_STORE,
5430 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5431 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5432 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5433 0u,
5434 vector<AttachmentReference>(),
5435 vector<AttachmentReference>(),
5436 vector<AttachmentReference>(),
5437 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5438 vector<deUint32>())),
5439 vector<SubpassDependency>());
5440
5441 addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5442 }
5443
5444 // depth_stencil
5445 {
5446 const RenderPass renderPass (vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5447 VK_SAMPLE_COUNT_1_BIT,
5448 VK_ATTACHMENT_LOAD_OP_CLEAR,
5449 VK_ATTACHMENT_STORE_OP_STORE,
5450 VK_ATTACHMENT_LOAD_OP_CLEAR,
5451 VK_ATTACHMENT_STORE_OP_STORE,
5452 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5453 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5454 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5455 0u,
5456 vector<AttachmentReference>(),
5457 vector<AttachmentReference>(),
5458 vector<AttachmentReference>(),
5459 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5460 vector<deUint32>())),
5461 vector<SubpassDependency>());
5462
5463 addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5464 }
5465
5466 // color_depth
5467 {
5468 const Attachment attachments[] =
5469 {
5470 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5471 VK_SAMPLE_COUNT_1_BIT,
5472 VK_ATTACHMENT_LOAD_OP_CLEAR,
5473 VK_ATTACHMENT_STORE_OP_STORE,
5474 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5475 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5476 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5477 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5478 Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
5479 VK_SAMPLE_COUNT_1_BIT,
5480 VK_ATTACHMENT_LOAD_OP_CLEAR,
5481 VK_ATTACHMENT_STORE_OP_STORE,
5482 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5483 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5484 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5485 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5486 };
5487
5488 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5489 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5490 0u,
5491 vector<AttachmentReference>(),
5492 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5493 vector<AttachmentReference>(),
5494 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5495 vector<deUint32>())),
5496 vector<SubpassDependency>());
5497
5498 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5499 }
5500
5501 // color_stencil
5502 {
5503 const Attachment attachments[] =
5504 {
5505 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5506 VK_SAMPLE_COUNT_1_BIT,
5507 VK_ATTACHMENT_LOAD_OP_CLEAR,
5508 VK_ATTACHMENT_STORE_OP_STORE,
5509 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5510 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5511 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5512 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5513 Attachment(VK_FORMAT_S8_UINT,
5514 VK_SAMPLE_COUNT_1_BIT,
5515 VK_ATTACHMENT_LOAD_OP_CLEAR,
5516 VK_ATTACHMENT_STORE_OP_STORE,
5517 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5518 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5519 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5520 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5521 };
5522
5523 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5524 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5525 0u,
5526 vector<AttachmentReference>(),
5527 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5528 vector<AttachmentReference>(),
5529 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5530 vector<deUint32>())),
5531 vector<SubpassDependency>());
5532
5533
5534 addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5535 }
5536
5537 // color_depth_stencil
5538 {
5539 const Attachment attachments[] =
5540 {
5541 Attachment(VK_FORMAT_R8G8B8A8_UNORM,
5542 VK_SAMPLE_COUNT_1_BIT,
5543 VK_ATTACHMENT_LOAD_OP_CLEAR,
5544 VK_ATTACHMENT_STORE_OP_STORE,
5545 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5546 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5547 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5548 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
5549 Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
5550 VK_SAMPLE_COUNT_1_BIT,
5551 VK_ATTACHMENT_LOAD_OP_CLEAR,
5552 VK_ATTACHMENT_STORE_OP_STORE,
5553 VK_ATTACHMENT_LOAD_OP_CLEAR,
5554 VK_ATTACHMENT_STORE_OP_STORE,
5555 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5556 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5557 };
5558
5559 const RenderPass renderPass (vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
5560 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5561 0u,
5562 vector<AttachmentReference>(),
5563 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5564 vector<AttachmentReference>(),
5565 AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5566 vector<deUint32>())),
5567 vector<SubpassDependency>());
5568
5569 addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5570 }
5571 }
5572
formatToName(VkFormat format)5573 std::string formatToName (VkFormat format)
5574 {
5575 const std::string formatStr = de::toString(format);
5576 const std::string prefix = "VK_FORMAT_";
5577
5578 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
5579
5580 return de::toLower(formatStr.substr(prefix.length()));
5581 }
5582
addFormatTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5583 void addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5584 {
5585 tcu::TestContext& testCtx = group->getTestContext();
5586
5587 const UVec2 targetSize (64, 64);
5588 const UVec2 renderPos (0, 0);
5589 const UVec2 renderSize (64, 64);
5590
5591 const struct
5592 {
5593 const char* const str;
5594 const VkAttachmentStoreOp op;
5595 } storeOps[] =
5596 {
5597 { "store", VK_ATTACHMENT_STORE_OP_STORE },
5598 { "dont_care", VK_ATTACHMENT_STORE_OP_DONT_CARE }
5599 };
5600
5601 const struct
5602 {
5603 const char* const str;
5604 const VkAttachmentLoadOp op;
5605 } loadOps[] =
5606 {
5607 { "clear", VK_ATTACHMENT_LOAD_OP_CLEAR },
5608 { "load", VK_ATTACHMENT_LOAD_OP_LOAD },
5609 { "dont_care", VK_ATTACHMENT_LOAD_OP_DONT_CARE }
5610 };
5611
5612 const struct
5613 {
5614 const char* const str;
5615 const TestConfig::RenderTypes types;
5616 } renderTypes[] =
5617 {
5618 { "clear", TestConfig::RENDERTYPES_CLEAR },
5619 { "draw", TestConfig::RENDERTYPES_DRAW },
5620 { "clear_draw", TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW }
5621 };
5622
5623 // Color formats
5624 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
5625 {
5626 const VkFormat format = s_coreColorFormats[formatNdx];
5627 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));
5628
5629 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5630 {
5631 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5632 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5633
5634 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5635 {
5636 const RenderPass renderPass (vector<Attachment>(1, Attachment(format,
5637 VK_SAMPLE_COUNT_1_BIT,
5638 loadOp,
5639 VK_ATTACHMENT_STORE_OP_STORE,
5640 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5641 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5642 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5643 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5644 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5645 0u,
5646 vector<AttachmentReference>(),
5647 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5648 vector<AttachmentReference>(),
5649 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5650 vector<deUint32>())),
5651 vector<SubpassDependency>());
5652
5653 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5654 }
5655
5656 formatGroup->addChild(loadOpGroup.release());
5657 }
5658
5659 {
5660 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5661
5662 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5663 {
5664 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5665 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5666
5667 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5668 {
5669 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5670 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5671
5672 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
5673 {
5674 const bool useInputAspect = useInputAspectNdx != 0;
5675
5676 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5677 {
5678 {
5679 vector<Attachment> attachments;
5680 vector<Subpass> subpasses;
5681 vector<SubpassDependency> deps;
5682 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5683
5684 attachments.push_back(Attachment(format,
5685 VK_SAMPLE_COUNT_1_BIT,
5686 loadOp,
5687 storeOp,
5688 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5689 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5690 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5691 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5692
5693 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5694 VK_SAMPLE_COUNT_1_BIT,
5695 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5696 VK_ATTACHMENT_STORE_OP_STORE,
5697 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5698 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5699 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5700 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5701
5702 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5703 0u,
5704 vector<AttachmentReference>(),
5705 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5706 vector<AttachmentReference>(),
5707 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5708 vector<deUint32>()));
5709 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5710 0u,
5711 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5712 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5713 vector<AttachmentReference>(),
5714 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5715 vector<deUint32>()));
5716
5717 deps.push_back(SubpassDependency(0, 1,
5718
5719 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5720 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5721
5722 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5723 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5724 vk::VK_DEPENDENCY_BY_REGION_BIT));
5725
5726 if (useInputAspect)
5727 {
5728 const VkInputAttachmentAspectReferenceKHR inputAspect =
5729 {
5730 0u,
5731 0u,
5732 VK_IMAGE_ASPECT_COLOR_BIT
5733 };
5734
5735 inputAspects.push_back(inputAspect);
5736 }
5737
5738 {
5739 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5740
5741 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5742 }
5743 }
5744 {
5745 vector<Attachment> attachments;
5746 vector<Subpass> subpasses;
5747 vector<SubpassDependency> deps;
5748 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5749
5750 attachments.push_back(Attachment(format,
5751 VK_SAMPLE_COUNT_1_BIT,
5752 loadOp,
5753 storeOp,
5754 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5755 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5756 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5757 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5758
5759 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5760 0u,
5761 vector<AttachmentReference>(),
5762 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5763 vector<AttachmentReference>(),
5764 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5765 vector<deUint32>()));
5766 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5767 0u,
5768 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5769 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
5770 vector<AttachmentReference>(),
5771 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5772 vector<deUint32>()));
5773
5774 deps.push_back(SubpassDependency(0, 1,
5775 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5776 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5777
5778 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5779 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5780 vk::VK_DEPENDENCY_BY_REGION_BIT));
5781
5782 if (useInputAspect)
5783 {
5784 const VkInputAttachmentAspectReferenceKHR inputAspect =
5785 {
5786 0u,
5787 0u,
5788 VK_IMAGE_ASPECT_COLOR_BIT
5789 };
5790
5791 inputAspects.push_back(inputAspect);
5792 }
5793
5794 {
5795 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5796
5797 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5798 }
5799 }
5800 }
5801 }
5802
5803 loadOpGroup->addChild(storeOpGroup.release());
5804 }
5805
5806 inputGroup->addChild(loadOpGroup.release());
5807 }
5808
5809 formatGroup->addChild(inputGroup.release());
5810 }
5811
5812 group->addChild(formatGroup.release());
5813 }
5814
5815 // Depth stencil formats
5816 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
5817 {
5818 const VkFormat vkFormat = s_coreDepthStencilFormats[formatNdx];
5819 const tcu::TextureFormat format = mapVkFormat(vkFormat);
5820 const bool isStencilAttachment = hasStencilComponent(format.order);
5821 const bool isDepthAttachment = hasDepthComponent(format.order);
5822 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));
5823
5824 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5825 {
5826 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5827 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5828
5829 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5830 {
5831 {
5832 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5833 VK_SAMPLE_COUNT_1_BIT,
5834 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5835 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5836 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5837 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5838 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5839 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5840 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5841 0u,
5842 vector<AttachmentReference>(),
5843 vector<AttachmentReference>(),
5844 vector<AttachmentReference>(),
5845 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5846 vector<deUint32>())),
5847 vector<SubpassDependency>());
5848
5849 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5850 }
5851
5852 if (isStencilAttachment && isDepthAttachment)
5853 {
5854 {
5855 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5856 VK_SAMPLE_COUNT_1_BIT,
5857 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5858 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5859 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5860 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5861 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5862 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5863 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5864 0u,
5865 vector<AttachmentReference>(),
5866 vector<AttachmentReference>(),
5867 vector<AttachmentReference>(),
5868 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR),
5869 vector<deUint32>())),
5870 vector<SubpassDependency>());
5871
5872 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), string(renderTypes[renderTypeNdx].str) + "_depth_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5873 }
5874
5875 {
5876 const RenderPass renderPass (vector<Attachment>(1, Attachment(vkFormat,
5877 VK_SAMPLE_COUNT_1_BIT,
5878 isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5879 isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5880 isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5881 isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
5882 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5883 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
5884 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5885 0u,
5886 vector<AttachmentReference>(),
5887 vector<AttachmentReference>(),
5888 vector<AttachmentReference>(),
5889 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR),
5890 vector<deUint32>())),
5891 vector<SubpassDependency>());
5892
5893 addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), string(renderTypes[renderTypeNdx].str) + "_stencil_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
5894 }
5895 }
5896 }
5897
5898 formatGroup->addChild(loadOpGroup.release());
5899 }
5900
5901 {
5902 de::MovePtr<tcu::TestCaseGroup> inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));
5903
5904 for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
5905 {
5906 const VkAttachmentLoadOp loadOp = loadOps[loadOpNdx].op;
5907 de::MovePtr<tcu::TestCaseGroup> loadOpGroup (new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));
5908
5909 for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
5910 {
5911 const VkAttachmentStoreOp storeOp = storeOps[storeOpNdx].op;
5912 de::MovePtr<tcu::TestCaseGroup> storeOpGroup (new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));
5913
5914 for (size_t useInputAspectNdx = 0; useInputAspectNdx < 2; useInputAspectNdx++)
5915 {
5916 const bool useInputAspect = useInputAspectNdx != 0;
5917
5918 for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
5919 {
5920 {
5921 vector<Attachment> attachments;
5922 vector<Subpass> subpasses;
5923 vector<SubpassDependency> deps;
5924 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5925
5926 attachments.push_back(Attachment(vkFormat,
5927 VK_SAMPLE_COUNT_1_BIT,
5928 loadOp,
5929 storeOp,
5930 loadOp,
5931 storeOp,
5932 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5933 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
5934
5935 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
5936 VK_SAMPLE_COUNT_1_BIT,
5937 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5938 VK_ATTACHMENT_STORE_OP_STORE,
5939 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5940 VK_ATTACHMENT_STORE_OP_DONT_CARE,
5941 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5942 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
5943
5944 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5945 0u,
5946 vector<AttachmentReference>(),
5947 vector<AttachmentReference>(),
5948 vector<AttachmentReference>(),
5949 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
5950 vector<deUint32>()));
5951 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
5952 0u,
5953 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
5954 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
5955 vector<AttachmentReference>(),
5956 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
5957 vector<deUint32>()));
5958
5959 deps.push_back(SubpassDependency(0, 1,
5960 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5961 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5962
5963 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5964 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5965 0u));
5966
5967 deps.push_back(SubpassDependency(1, 1,
5968 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
5969 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
5970
5971 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
5972 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
5973 vk::VK_DEPENDENCY_BY_REGION_BIT));
5974
5975 if (useInputAspect)
5976 {
5977 const VkInputAttachmentAspectReferenceKHR inputAspect =
5978 {
5979 0u,
5980 0u,
5981 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
5982 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
5983 };
5984
5985 inputAspects.push_back(inputAspect);
5986 }
5987
5988 {
5989 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
5990
5991 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : ""), renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
5992 }
5993 }
5994 {
5995 vector<Attachment> attachments;
5996 vector<Subpass> subpasses;
5997 vector<SubpassDependency> deps;
5998 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
5999
6000 attachments.push_back(Attachment(vkFormat,
6001 VK_SAMPLE_COUNT_1_BIT,
6002 loadOp,
6003 storeOp,
6004 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6005 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6006 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6007 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6008
6009 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6010 0u,
6011 vector<AttachmentReference>(),
6012 vector<AttachmentReference>(),
6013 vector<AttachmentReference>(),
6014 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6015 vector<deUint32>()));
6016 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6017 0u,
6018 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
6019 vector<AttachmentReference>(),
6020 vector<AttachmentReference>(),
6021 AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL),
6022 vector<deUint32>()));
6023
6024 deps.push_back(SubpassDependency(0, 1,
6025 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6026 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6027
6028 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6029 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6030 vk::VK_DEPENDENCY_BY_REGION_BIT));
6031
6032
6033 if (useInputAspect)
6034 {
6035 const VkInputAttachmentAspectReferenceKHR inputAspect =
6036 {
6037 0u,
6038 0u,
6039
6040 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6041 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6042 };
6043
6044 inputAspects.push_back(inputAspect);
6045 }
6046
6047 {
6048 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6049
6050 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : ""), string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
6051 }
6052 }
6053
6054 if (isStencilAttachment && isDepthAttachment)
6055 {
6056 // Depth read only
6057 {
6058 vector<Attachment> attachments;
6059 vector<Subpass> subpasses;
6060 vector<SubpassDependency> deps;
6061 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
6062
6063 attachments.push_back(Attachment(vkFormat,
6064 VK_SAMPLE_COUNT_1_BIT,
6065 loadOp,
6066 storeOp,
6067 loadOp,
6068 storeOp,
6069 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6070 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6071
6072 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6073 VK_SAMPLE_COUNT_1_BIT,
6074 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6075 VK_ATTACHMENT_STORE_OP_STORE,
6076 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6077 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6078 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6079 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6080
6081 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6082 0u,
6083 vector<AttachmentReference>(),
6084 vector<AttachmentReference>(),
6085 vector<AttachmentReference>(),
6086 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6087 vector<deUint32>()));
6088 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6089 0u,
6090 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)),
6091 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6092 vector<AttachmentReference>(),
6093 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6094 vector<deUint32>()));
6095
6096 deps.push_back(SubpassDependency(0, 1,
6097 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6098 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6099
6100 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6101 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6102 0u));
6103
6104 if (useInputAspect)
6105 {
6106 const VkInputAttachmentAspectReferenceKHR inputAspect =
6107 {
6108 0u,
6109 0u,
6110
6111 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6112 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6113 };
6114
6115 inputAspects.push_back(inputAspect);
6116 }
6117
6118 {
6119 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6120
6121 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
6122 }
6123 }
6124 {
6125 vector<Attachment> attachments;
6126 vector<Subpass> subpasses;
6127 vector<SubpassDependency> deps;
6128 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
6129
6130 attachments.push_back(Attachment(vkFormat,
6131 VK_SAMPLE_COUNT_1_BIT,
6132 loadOp,
6133 storeOp,
6134 loadOp,
6135 storeOp,
6136 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6137 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6138
6139 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6140 0u,
6141 vector<AttachmentReference>(),
6142 vector<AttachmentReference>(),
6143 vector<AttachmentReference>(),
6144 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6145 vector<deUint32>()));
6146 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6147 0u,
6148 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR)),
6149 vector<AttachmentReference>(),
6150 vector<AttachmentReference>(),
6151 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR),
6152 vector<deUint32>()));
6153
6154 deps.push_back(SubpassDependency(0, 1,
6155 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6156 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6157
6158 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6159 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6160 vk::VK_DEPENDENCY_BY_REGION_BIT));
6161
6162 deps.push_back(SubpassDependency(1, 1,
6163 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6164 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6165
6166 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6167 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6168 vk::VK_DEPENDENCY_BY_REGION_BIT));
6169
6170
6171 if (useInputAspect)
6172 {
6173 const VkInputAttachmentAspectReferenceKHR inputAspect =
6174 {
6175 0u,
6176 0u,
6177
6178 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6179 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6180 };
6181
6182 inputAspects.push_back(inputAspect);
6183 }
6184
6185 {
6186 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6187
6188 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_depth_read_only", string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
6189 }
6190 }
6191 // Stencil read only
6192 {
6193 vector<Attachment> attachments;
6194 vector<Subpass> subpasses;
6195 vector<SubpassDependency> deps;
6196 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
6197
6198 attachments.push_back(Attachment(vkFormat,
6199 VK_SAMPLE_COUNT_1_BIT,
6200 loadOp,
6201 storeOp,
6202 loadOp,
6203 storeOp,
6204 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6205 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6206
6207 attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
6208 VK_SAMPLE_COUNT_1_BIT,
6209 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6210 VK_ATTACHMENT_STORE_OP_STORE,
6211 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
6212 VK_ATTACHMENT_STORE_OP_DONT_CARE,
6213 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
6214 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
6215
6216 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6217 0u,
6218 vector<AttachmentReference>(),
6219 vector<AttachmentReference>(),
6220 vector<AttachmentReference>(),
6221 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6222 vector<deUint32>()));
6223 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6224 0u,
6225 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)),
6226 vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
6227 vector<AttachmentReference>(),
6228 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
6229 vector<deUint32>()));
6230
6231 deps.push_back(SubpassDependency(0, 1,
6232 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6233 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6234
6235 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6236 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6237 0u));
6238
6239 if (useInputAspect)
6240 {
6241 const VkInputAttachmentAspectReferenceKHR inputAspect =
6242 {
6243 0u,
6244 0u,
6245
6246 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6247 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6248 };
6249
6250 inputAspects.push_back(inputAspect);
6251 }
6252
6253 {
6254 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6255
6256 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str + string(useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only", renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
6257 }
6258 }
6259 {
6260 vector<Attachment> attachments;
6261 vector<Subpass> subpasses;
6262 vector<SubpassDependency> deps;
6263 vector<VkInputAttachmentAspectReferenceKHR> inputAspects;
6264
6265 attachments.push_back(Attachment(vkFormat,
6266 VK_SAMPLE_COUNT_1_BIT,
6267 loadOp,
6268 storeOp,
6269 loadOp,
6270 storeOp,
6271 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
6272 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
6273
6274 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6275 0u,
6276 vector<AttachmentReference>(),
6277 vector<AttachmentReference>(),
6278 vector<AttachmentReference>(),
6279 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
6280 vector<deUint32>()));
6281 subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
6282 0u,
6283 vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)),
6284 vector<AttachmentReference>(),
6285 vector<AttachmentReference>(),
6286 AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR),
6287 vector<deUint32>()));
6288
6289 deps.push_back(SubpassDependency(0, 1,
6290 vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
6291 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6292
6293 vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
6294 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6295 vk::VK_DEPENDENCY_BY_REGION_BIT));
6296
6297 deps.push_back(SubpassDependency(1, 1,
6298 vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6299 vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
6300
6301 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
6302 vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
6303 vk::VK_DEPENDENCY_BY_REGION_BIT));
6304
6305
6306 if (useInputAspect)
6307 {
6308 const VkInputAttachmentAspectReferenceKHR inputAspect =
6309 {
6310 0u,
6311 0u,
6312
6313 (isDepthAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
6314 | (isStencilAttachment ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u)
6315 };
6316
6317 inputAspects.push_back(inputAspect);
6318 }
6319
6320 {
6321 const RenderPass renderPass (attachments, subpasses, deps, inputAspects);
6322
6323 addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str + (useInputAspect ? "_use_input_aspect" : "") + "_stencil_read_only", string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
6324 }
6325 }
6326 }
6327 }
6328 }
6329
6330 loadOpGroup->addChild(storeOpGroup.release());
6331 }
6332
6333 inputGroup->addChild(loadOpGroup.release());
6334 }
6335
6336 formatGroup->addChild(inputGroup.release());
6337 }
6338
6339 group->addChild(formatGroup.release());
6340 }
6341 }
6342
addRenderPassTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6343 void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6344 {
6345 addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind);
6346 addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind);
6347 addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind);
6348 addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind);
6349 }
6350
createSuballocationTests(tcu::TestContext & testCtx)6351 de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx)
6352 {
6353 de::MovePtr<tcu::TestCaseGroup> suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));
6354
6355 addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED);
6356
6357 return suballocationTestsGroup;
6358 }
6359
createDedicatedAllocationTests(tcu::TestContext & testCtx)6360 de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx)
6361 {
6362 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));
6363
6364 addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED);
6365
6366 return dedicatedAllocationTestsGroup;
6367 }
6368
6369 } // anonymous
6370
createRenderPassTests(tcu::TestContext & testCtx)6371 tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
6372 {
6373 de::MovePtr<tcu::TestCaseGroup> renderpassTests (new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
6374 de::MovePtr<tcu::TestCaseGroup> suballocationTestGroup = createSuballocationTests(testCtx);
6375 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocationTestGroup = createDedicatedAllocationTests(testCtx);
6376
6377 suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
6378 suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx));
6379
6380 renderpassTests->addChild(suballocationTestGroup.release());
6381 renderpassTests->addChild(dedicatedAllocationTestGroup.release());
6382
6383 return renderpassTests.release();
6384 }
6385
6386 } // vkt
6387