1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group Inc.
6 * Copyright (c) 2020 ARM Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief VK_ARM_rasterization_order_attachment_access tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "deDefs.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuResource.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkDefs.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkMemUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkPlatform.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkRef.hpp"
43 #include "vkRefUtil.hpp"
44 #include "vktRasterizationOrderAttachmentAccessTests.hpp"
45 #include "vktRasterizationTests.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50
51 using namespace vk;
52 using namespace std;
53 using namespace vkt;
54 using de::MovePtr;
55
56 namespace vkt
57 {
58
59 namespace rasterization
60 {
61
62 namespace
63 {
64
65 class AttachmentAccessOrderTestCase : public TestCase
66 {
67 public:
68 enum
69 {
70 ELEM_NUM = 6
71 };
72
73 AttachmentAccessOrderTestCase( tcu::TestContext& context, const std::string& name, const std::string& description,
74 bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
75 VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat);
76 virtual ~AttachmentAccessOrderTestCase (void);
77
78 virtual void initPrograms (SourceCollections& programCollection) const;
79 virtual TestInstance* createInstance (Context& context) const;
80 virtual void checkSupport (Context& context) const;
81
82 virtual deUint32 getInputAttachmentNum() const = 0;
83 virtual deUint32 getColorAttachmentNum() const = 0;
84 virtual bool hasDepthStencil() const = 0;
85 virtual VkImageAspectFlagBits getDSAspect() const = 0;
86
87
88
89
90 deUint32 m_inputAttachmentNum;
91 const bool m_explicitSync;
92 const bool m_overlapDraws;
93 const bool m_overlapPrimitives;
94 const bool m_overlapInstances;
95 VkSampleCountFlagBits m_sampleCount;
96 const deUint32 m_sampleNum;
97 const bool m_integerFormat;
98 static deUint32 getSampleNum(VkSampleCountFlagBits sampleCount);
99
getColorFormat() const100 VkFormat getColorFormat() const
101 {
102 return m_integerFormat ? VK_FORMAT_R32G32_UINT : VK_FORMAT_R32G32_SFLOAT;
103 }
104
105 VkFormat checkAndGetDSFormat (Context& context) const;
106
getColorImageType()107 static VkImageType getColorImageType ()
108 {
109 return VK_IMAGE_TYPE_2D;
110 }
111
getColorImageTiling()112 static VkImageTiling getColorImageTiling ()
113 {
114 return VK_IMAGE_TILING_OPTIMAL;
115 }
116
getColorImageUsageFlags()117 static VkImageUsageFlags getColorImageUsageFlags ()
118 {
119 return
120 ( VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
121 | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
122 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
123 | VK_IMAGE_USAGE_TRANSFER_DST_BIT
124 );
125 }
126
getDSImageUsageFlags()127 static VkImageUsageFlags getDSImageUsageFlags ()
128 {
129 return
130 ( VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
131 | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
132 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
133 | VK_IMAGE_USAGE_TRANSFER_DST_BIT
134 );
135 }
136
getBlendStateFlags() const137 VkPipelineColorBlendStateCreateFlags getBlendStateFlags() const
138 {
139 return m_explicitSync ? 0 : VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM;
140 }
getDSStateFlags() const141 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
142 {
143 return 0;
144 }
hasDepth() const145 virtual bool hasDepth() const
146 {
147 return false;
148 }
hasStencil() const149 virtual bool hasStencil() const
150 {
151 return false;
152 }
153
154 protected:
155 virtual void addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const = 0;
156 void addSimpleVertexShader(SourceCollections& programCollection, const std::string &dest) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const157 virtual void checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
158 {
159 // unused parameter
160 DE_UNREF(rasterizationAccess);
161 }
162 };
163
164 class AttachmentAccessOrderColorTestCase : public AttachmentAccessOrderTestCase
165 {
166 public:
AttachmentAccessOrderColorTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,deUint32 inputAttachmentNum,bool integerFormat)167 AttachmentAccessOrderColorTestCase( tcu::TestContext& context, const std::string& name, const std::string& description,
168 bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
169 VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat)
170 :AttachmentAccessOrderTestCase( context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
171 inputAttachmentNum, integerFormat)
172 {}
173
getInputAttachmentNum() const174 virtual deUint32 getInputAttachmentNum() const
175 {
176 return m_inputAttachmentNum;
177 }
178
getColorAttachmentNum() const179 virtual deUint32 getColorAttachmentNum() const
180 {
181 return m_inputAttachmentNum;
182 }
183
hasDepthStencil() const184 virtual bool hasDepthStencil() const
185 {
186 return false;
187 }
188
getDSAspect() const189 virtual VkImageAspectFlagBits getDSAspect() const
190 {
191 /* not relevant, this return value will not be used */
192 return VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
193 }
194 protected:
195 virtual void addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const;
196 };
197
198 class AttachmentAccessOrderDepthTestCase : public AttachmentAccessOrderTestCase
199 {
200 public:
AttachmentAccessOrderDepthTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)201 AttachmentAccessOrderDepthTestCase( tcu::TestContext& context, const std::string& name, const std::string& description,
202 bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
203 VkSampleCountFlagBits sampleCount)
204 :AttachmentAccessOrderTestCase( context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
205 1, false)
206 {}
getInputAttachmentNum() const207 virtual deUint32 getInputAttachmentNum() const
208 {
209 return m_inputAttachmentNum + 1;
210 }
211
getColorAttachmentNum() const212 virtual deUint32 getColorAttachmentNum() const
213 {
214 return m_inputAttachmentNum;
215 }
216
hasDepth() const217 virtual bool hasDepth() const
218 {
219 return true;
220 }
hasDepthStencil() const221 virtual bool hasDepthStencil() const
222 {
223 return true;
224 }
225
getDSAspect() const226 virtual VkImageAspectFlagBits getDSAspect() const
227 {
228 return VK_IMAGE_ASPECT_DEPTH_BIT;
229 }
getDSStateFlags() const230 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
231 {
232 return m_explicitSync ? 0 : VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
233 }
234 protected:
235 virtual void addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const236 virtual void checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
237 {
238 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderDepthAttachmentAccess)
239 {
240 TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for depth attachments");
241 }
242 }
243 };
244
245 class AttachmentAccessOrderStencilTestCase : public AttachmentAccessOrderTestCase
246 {
247 public:
AttachmentAccessOrderStencilTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)248 AttachmentAccessOrderStencilTestCase( tcu::TestContext& context, const std::string& name, const std::string& description,
249 bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
250 VkSampleCountFlagBits sampleCount)
251 :AttachmentAccessOrderTestCase( context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
252 1, true)
253 {}
getInputAttachmentNum() const254 virtual deUint32 getInputAttachmentNum() const
255 {
256 return m_inputAttachmentNum + 1;
257 }
258
getColorAttachmentNum() const259 virtual deUint32 getColorAttachmentNum() const
260 {
261 return m_inputAttachmentNum;
262 }
263
hasStencil() const264 virtual bool hasStencil() const
265 {
266 return true;
267 }
hasDepthStencil() const268 virtual bool hasDepthStencil() const
269 {
270 return true;
271 }
272
getDSAspect() const273 virtual VkImageAspectFlagBits getDSAspect() const
274 {
275 return VK_IMAGE_ASPECT_STENCIL_BIT;
276 }
getDSStateFlags() const277 virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
278 {
279 return m_explicitSync ? 0 : VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
280 }
281 protected:
282 virtual void addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const283 virtual void checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
284 {
285 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderStencilAttachmentAccess)
286 {
287 TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for stencil attachments");
288 }
289 }
290 };
291
292
293 class AttachmentAccessOrderTestInstance : public TestInstance
294 {
295 public:
296 AttachmentAccessOrderTestInstance (Context& context, const AttachmentAccessOrderTestCase *testCase);
297 virtual ~AttachmentAccessOrderTestInstance (void);
298 virtual tcu::TestStatus iterate (void);
299 protected:
300 class RenderSubpass
301 {
302 public:
303 const AttachmentAccessOrderTestCase *m_testCase;
304 deUint32 m_subpass;
305 VkSampleCountFlagBits m_sampleCount;
306 Move<VkPipeline> m_pipeline;
307 Move<VkPipelineLayout> m_pipelineLayout;
308 deUint32 m_colorAttNum;
309 std::vector<Move<VkImage> > m_inputAtt;
310 std::vector<MovePtr<Allocation> > m_inputAttMemory;
311 std::vector<Move<VkImageView> > m_inputAttView;
312 std::vector<VkAttachmentReference> m_attachmentReferences;
313
314 void createAttachments( int subpass, deUint32 inputAttachmentNum, deUint32 colorAttachmentNum, VkSampleCountFlagBits sampleCount,
315 Context &context, vector<VkImageView> &views, VkDescriptorSetLayout *pDsetLayout, const AttachmentAccessOrderTestCase *tc);
316 void createPipeline(VkRenderPass renderPass, Context &context);
317
getColorAttachmentNum()318 deUint32 getColorAttachmentNum()
319 {
320 return m_colorAttNum;
321 }
getInputAttachmentNum()322 deUint32 getInputAttachmentNum()
323 {
324 return static_cast<deUint32>(m_inputAtt.size());
325 }
getDepthStencilAttachment()326 VkAttachmentReference* getDepthStencilAttachment()
327 {
328 return (getColorAttachmentNum() == getInputAttachmentNum()) ? DE_NULL : &m_attachmentReferences[m_colorAttNum];
329 }
330 };
331 void addPipelineBarrier( VkCommandBuffer cmdBuffer,
332 VkImage image,
333 VkImageLayout oldLayout,
334 VkImageLayout newLayout,
335 VkAccessFlags srcAccessMask,
336 VkAccessFlags dstAccessMask,
337 VkPipelineStageFlags srcStageMask,
338 VkPipelineStageFlags dstStageMask,
339 VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT);
340
341 void addClearColor(VkCommandBuffer cmdBuffer, VkImage image);
342 void addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image);
343
344 void writeDescriptorSets();
345 Move<VkRenderPass> createRenderPass(VkFormat attFormat);
346 void createVertexBuffer();
347 void createResultBuffer();
348 void addDependency( vector<VkSubpassDependency> &dependencies, deUint32 source, deUint32 dst,
349 VkPipelineStageFlags pipelineFlags, VkAccessFlags accessFlags);
350
351 tcu::TestStatus validateResults(deUint32 numDraws, deUint32 numPrimitives, deUint32 numInstances);
352
353 const AttachmentAccessOrderTestCase *m_testCase;
354
355
356 const DeviceInterface& m_vk;
357 vector<RenderSubpass> m_subpasses;
358 Move<VkRenderPass> m_renderPass;
359 Move<VkFramebuffer> m_framebuffer;
360 Move<VkBuffer> m_vertexBuffer;
361 MovePtr<Allocation> m_vertexBufferMemory;
362 Move<VkCommandPool> m_cmdPool;
363 Move<VkCommandBuffer> m_cmdBuffer;
364 Move<VkSampler> m_sampler;
365 Move<VkDescriptorSetLayout> m_descSetLayout;
366 Move<VkDescriptorPool> m_descPool;
367 Move<VkDescriptorSet> m_descSet;
368
369 Move<VkBuffer> m_resultBuffer;
370 MovePtr<Allocation> m_resultBufferMemory;
371
372 enum
373 {
374 WIDTH = 8,
375 HEIGHT = 8,
376 };
377 };
378
AttachmentAccessOrderTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,deUint32 inputAttachmentNum,bool integerFormat)379 AttachmentAccessOrderTestCase::AttachmentAccessOrderTestCase ( tcu::TestContext& context, const std::string& name, const std::string& description,
380 bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
381 VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat)
382 : TestCase(context, name, description)
383 , m_inputAttachmentNum(inputAttachmentNum)
384 , m_explicitSync(explicitSync)
385 , m_overlapDraws(overlapDraws)
386 , m_overlapPrimitives(overlapPrimitives)
387 , m_overlapInstances(overlapInstances)
388 , m_sampleCount(sampleCount)
389 , m_sampleNum(getSampleNum(sampleCount))
390 , m_integerFormat(integerFormat)
391 {
392 }
393
~AttachmentAccessOrderTestCase(void)394 AttachmentAccessOrderTestCase::~AttachmentAccessOrderTestCase (void)
395 {
396 }
addSimpleVertexShader(SourceCollections & programCollection,const std::string & dest) const397 void AttachmentAccessOrderTestCase::addSimpleVertexShader(SourceCollections& programCollection, const std::string &dest) const
398 {
399 /*
400 * The "prim_id" variable here (and in other tests below) is emulating gl_PrimitiveID.
401 * This is done to avoid having this test dependon the geometry shader feature.
402 * Note that this emulation only works because the draw calls used in the tests are
403 * non-indexed independent triangles.
404 */
405 std::stringstream vertShader;
406 vertShader << "#version 310 es\n"
407 << "layout(location = 0) in highp vec2 v_position;\n"
408 << "layout(location = 1) flat out int prim_id;\n"
409 << "void main ()\n"
410 << "{\n"
411 << " prim_id = gl_VertexIndex / 3;\n"
412 << " gl_Position = vec4(v_position, float(gl_InstanceIndex)/256.0, 1);\n"
413 << "}\n";
414
415 programCollection.glslSources.add(dest) << glu::VertexSource(vertShader.str());
416 }
417
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const418 void AttachmentAccessOrderColorTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const
419 {
420 addSimpleVertexShader(programCollection, "vert1");
421 addSimpleVertexShader(programCollection, "vert2");
422
423 std::stringstream fragShader;
424 fragShader << "#version 450\n"
425 << "precision highp ${SCALAR_NAME};\n"
426 << "precision highp ${SUBPASS_INPUT};\n";
427 for (deUint32 i=0; i < m_inputAttachmentNum; i++)
428 {
429 fragShader << "layout( set = 0, binding = " << i << ", input_attachment_index = " << i << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n"
430 << "layout( location = " << i << " ) out ${VEC_NAME}2 out" << i << ";\n";
431 }
432
433 fragShader << "layout( push_constant ) uniform ConstBlock\n"
434 << "{\n"
435 << " uint drawCur;\n"
436 << "};\n"
437 << "layout(location = 1) flat in int prim_id;\n"
438 << "void main()\n"
439 << "{\n"
440 << " uint instanceCur = uint(round(gl_FragCoord.z * 256.0));\n"
441 << " uint primitiveCur = uint(prim_id) / 2u;\n"
442 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
443 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
444 << " uint drawNum = ${DRAW_NUM}u;\n"
445 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
446 << " uint total = drawNum * instanceNum * primitiveNum;\n"
447 << " uint zero = curIndex / total;\n"
448 << " uint index;\n"
449 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
450 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
451 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
452 << " {\n"
453 << " zero = uint(sin(float(zero)));\n"
454 << " }\n"
455 << " ${VEC_NAME}2 previous[${ATT_NUM}];\n";
456
457 for (deUint32 i=0; i < m_inputAttachmentNum; i++)
458 {
459 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
460 {
461 fragShader << " previous[" << i << "] = subpassLoad( in" << i << ").xy;\n";
462 }
463 else
464 {
465 fragShader << " previous[" << i << "] = subpassLoad( in" << i << ", gl_SampleID).xy;\n";
466 }
467 }
468 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
469 << " {\n"
470 << " zero = uint(sin(float(zero)));\n"
471 << " }\n";
472 for (deUint32 i=0; i < m_inputAttachmentNum; i++)
473 {
474 fragShader << " if (previous[" << i << "].y == 0 && curIndex == 0)\n"
475 << " {\n"
476 << " out" << i << ".y = previous[" << i << "].y + (1u + zero + gl_SampleID + " << i << "u);\n"
477 << " out" << i << ".x = previous[" << i << "].x;\n"
478 << " }\n"
479 << " else if (previous[" << i << "].y == curIndex + gl_SampleID + " << i << ")\n"
480 << " {\n"
481 << " out" << i << ".y = previous[" << i << "].y + 1 + zero;\n"
482 << " out" << i << ".x = previous[" << i << "].x;\n"
483 << " }\n"
484 << " else\n"
485 << " {\n"
486 << " out" << i << ".y = 0u;\n"
487 << " out" << i << ".x = 1u;\n"
488 << " }\n";
489 }
490 fragShader << "}\n";
491
492 tcu::StringTemplate fragShaderTpl(fragShader.str());
493
494 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
495 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const496 void AttachmentAccessOrderDepthTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const
497 {
498 std::stringstream vertShader;
499 vertShader << "#version 460\n"
500 << "layout(location = 0) in highp vec2 v_position;\n"
501 << "layout(location = 1) flat out uint instance_index;\n"
502 << "layout(location = 2) flat out int prim_id;\n"
503 << "layout( push_constant ) uniform ConstBlock\n"
504 << "{\n"
505 << " uint drawCur;\n"
506 << "};\n"
507 << "void main ()\n"
508 << "{\n"
509 << " uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
510 << " prim_id = gl_VertexIndex / 3;\n"
511 << " uint instanceNum = ${INSTANCE_NUM};\n"
512 << " uint primitiveNum = ${PRIMITIVE_NUM};\n"
513 << " uint drawNum = ${DRAW_NUM};\n"
514 << " uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + primitiveCur;\n"
515 << " uint indexNum = drawNum * instanceNum * primitiveNum;\n"
516 << " instance_index = gl_InstanceIndex;\n"
517 << " gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
518 << "}\n";
519
520 tcu::StringTemplate vertShaderTpl(vertShader.str());
521 programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
522 addSimpleVertexShader(programCollection, "vert2");
523
524 std::stringstream fragShader;
525 fragShader << "#version 450\n"
526 << "precision highp ${SCALAR_NAME};\n"
527 << "precision highp ${SUBPASS_INPUT};\n"
528 << "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
529 << "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
530 << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
531 << "layout( location = 1 ) flat in uint instance_index;\n"
532 << "layout( location = 2 ) flat in int prim_id;\n"
533 << "layout( push_constant ) uniform ConstBlock\n"
534 << "{\n"
535 << " uint drawCur;\n"
536 << "};\n"
537 << "void main()\n"
538 << "{\n"
539 << " uint instanceCur = instance_index;\n"
540 << " uint primitiveCur = uint(prim_id) / 2u;\n"
541 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
542 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
543 << " uint drawNum = ${DRAW_NUM}u;\n"
544 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
545 << " uint total = drawNum * instanceNum * primitiveNum;\n"
546 << " uint zero = curIndex / total;\n"
547 << " uint index;\n"
548 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
549 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
550 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
551 << " {\n"
552 << " zero = uint(sin(float(zero)));\n"
553 << " }\n";
554 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
555 {
556 fragShader << " vec2 ds = subpassLoad( in_ds ).xy;\n"
557 << " ${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
558 }
559 else
560 {
561 fragShader << " vec2 ds = subpassLoad( in_ds, gl_SampleID ).xy;\n"
562 << " ${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID ).xy;\n";
563 }
564 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
565 << " {\n"
566 << " zero = uint(sin(float(zero)));\n"
567 << " }\n"
568 << " if (curIndex == 0 && ds.x == 0)\n"
569 << " {\n"
570 << " out0.x = color.x;\n"
571 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n";
572 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
573 {
574 fragShader << " gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
575 }
576 fragShader << " }\n"
577 << " else\n"
578 << " {\n"
579 << " const float expected = 0.125 * float(curIndex - 1) / float(total) + gl_SampleID / 128.0;\n"
580 << " const float threshold = 0.0000001;\n"
581 << " if (ds.x >= expected - threshold && ds.x <= expected + threshold)\n"
582 << " {\n"
583 << " out0.x = color.x;\n"
584 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n";
585 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
586 {
587 fragShader << " gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
588 }
589 fragShader << " }\n"
590 << " else\n"
591 << " {\n"
592 << " out0.y = 0;\n"
593 << " out0.x = 1u;\n"
594 << " }\n"
595 << " }\n"
596 << "}\n";
597
598 tcu::StringTemplate fragShaderTpl(fragShader.str());
599
600 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
601 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const602 void AttachmentAccessOrderStencilTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> ¶ms) const
603 {
604 std::stringstream vertShader;
605 vertShader << "#version 460\n"
606 << "layout(location = 0) in highp vec2 v_position;\n"
607 << "layout(location = 1) flat out uint instance_index;"
608 << "layout(location = 2) flat out int prim_id;\n"
609 << "layout( push_constant ) uniform ConstBlock\n"
610 << "{\n"
611 << " uint drawCur;\n"
612 << "};\n"
613 << "void main ()\n"
614 << "{\n"
615 << " uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
616 << " prim_id = gl_VertexIndex / 3;\n"
617 << " uint instanceNum = ${INSTANCE_NUM};\n"
618 << " uint primitiveNum = ${PRIMITIVE_NUM};\n"
619 << " uint drawNum = ${DRAW_NUM};\n"
620 << " uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + primitiveCur;\n"
621 << " uint indexNum = drawNum * instanceNum * primitiveNum;\n"
622 << " instance_index = gl_InstanceIndex;\n"
623 << " gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
624 << "}\n";
625
626 tcu::StringTemplate vertShaderTpl(vertShader.str());
627 programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
628 addSimpleVertexShader(programCollection, "vert2");
629
630 std::stringstream fragShader;
631 fragShader << "#version 450\n"
632 << "precision highp ${SCALAR_NAME};\n"
633 << "precision highp ${SUBPASS_INPUT};\n"
634 << "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
635 << "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
636 << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
637 << "layout( location = 1 ) flat in uint instance_index;\n"
638 << "layout( location = 2 ) flat in int prim_id;\n"
639 << "layout( push_constant ) uniform ConstBlock\n"
640 << "{\n"
641 << " uint drawCur;\n"
642 << "};\n"
643 << "void main()\n"
644 << "{\n"
645 << " uint instanceCur = instance_index;\n"
646 << " uint primitiveCur = uint(prim_id) / 2u;\n"
647 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
648 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
649 << " uint drawNum = ${DRAW_NUM}u;\n"
650 << " uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
651 << " uint total = drawNum * instanceNum * primitiveNum;\n"
652 << " uint zero = curIndex / total;\n"
653 << " uint index;\n"
654 << " uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
655 << " uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
656 << " for(index = 0u; index < pre_fetch_loop; index++)\n"
657 << " {\n"
658 << " zero = uint(sin(float(zero)));\n"
659 << " }\n";
660 if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
661 {
662 fragShader << " ${VEC_NAME}2 ds = subpassLoad( in_ds ).xy;\n"
663 << " ${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
664 }
665 else
666 {
667 fragShader << " ${VEC_NAME}2 ds = subpassLoad( in_ds, gl_SampleID).xy;\n"
668 << " ${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID).xy;\n";
669 }
670 fragShader << " for(index = 0u; index < post_fetch_loop; index++)\n"
671 << " {\n"
672 << " zero = uint(sin(float(zero)));\n"
673 << " }\n"
674 << " if (ds.x == curIndex)\n"
675 << " {\n"
676 << " out0.x = color.x;\n"
677 << " out0.y = curIndex + 1 + gl_SampleID + zero;\n"
678 << " }\n"
679 << " else\n"
680 << " {\n"
681 << " out0.y = 0;\n"
682 << " out0.x = 1u;\n"
683 << " }\n"
684 << "}\n";
685
686 tcu::StringTemplate fragShaderTpl(fragShader.str());
687
688 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
689 }
690
initPrograms(SourceCollections & programCollection) const691 void AttachmentAccessOrderTestCase::initPrograms (SourceCollections& programCollection) const
692 {
693 std::map<std::string, std::string> params;
694
695 params["PRIMITIVE_NUM"] = std::to_string(m_overlapPrimitives?ELEM_NUM:1);
696 params["INSTANCE_NUM"] = std::to_string(m_overlapInstances?ELEM_NUM:1);
697 params["DRAW_NUM"] = std::to_string(m_overlapDraws?ELEM_NUM:1);
698 params["ATT_NUM"] = std::to_string(m_inputAttachmentNum);
699 params["SAMPLE_NUM"] = std::to_string(m_sampleNum);
700
701 if (m_integerFormat)
702 {
703 params["SUBPASS_INPUT"] = "usubpassInput";
704 params["SCALAR_NAME"] = "int";
705 params["VEC_NAME"] = "uvec";
706 }
707 else
708 {
709 params["SUBPASS_INPUT"] = "subpassInput";
710 params["SCALAR_NAME"] = "float";
711 params["VEC_NAME"] = "vec";
712 }
713 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
714 {
715 params["SUBPASS_INPUT"] = params["SUBPASS_INPUT"] + "MS";
716 }
717
718 /* add the vertex (for both renderpasses) and fragment shaders for first renderpass */
719 addShadersInternal(programCollection, params);
720
721 std::stringstream fragShaderResolve;
722 fragShaderResolve << "#version 450\n"
723 << "precision highp ${SCALAR_NAME};\n"
724 << "precision highp ${SUBPASS_INPUT};\n";
725 for (deUint32 i=0; i < m_inputAttachmentNum; i++)
726 {
727 fragShaderResolve << "layout( set = 0, binding = " << i << ", input_attachment_index = " << i << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n";
728 }
729 fragShaderResolve << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n";
730
731 fragShaderResolve << "void main()\n"
732 << "{\n"
733 << " uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
734 << " uint instanceNum = ${INSTANCE_NUM}u;\n"
735 << " uint drawNum = ${DRAW_NUM}u;\n"
736 << " uint sampleNum = ${SAMPLE_NUM}u;\n"
737 << " uint totalNum = primitiveNum * instanceNum * drawNum;\n"
738 << " out0.y = totalNum;\n"
739 << " out0.x = 0u;\n"
740 << " ${VEC_NAME}2 val;\n"
741 << " int i;\n";
742
743 for (deUint32 i=0; i < m_inputAttachmentNum; i++)
744 {
745 if (m_sampleNum == 1)
746 {
747 fragShaderResolve << " val = subpassLoad(in" << i << ").xy;\n"
748 << " if (val.x != 0u || val.y != totalNum + " << i << "){\n"
749 << " out0.y = val.y;\n"
750 << " out0.x = val.x;\n"
751 << " }\n";
752 }
753 else
754 {
755 fragShaderResolve << " for (i = 0; i < sampleNum; i++) {\n"
756 << " val = subpassLoad(in" << i << ", i).xy;\n"
757 << " if (val.x != 0u || val.y != totalNum + i + " << i << "){\n"
758 << " out0.y = val.y;\n"
759 << " out0.x = val.x;\n"
760 << " }\n"
761 << " }\n";
762 }
763 }
764
765 fragShaderResolve << "}\n";
766
767 tcu::StringTemplate fragShaderResolveTpl(fragShaderResolve.str());
768
769 programCollection.glslSources.add("frag_resolve") << glu::FragmentSource(fragShaderResolveTpl.specialize(params));
770 }
771
772
createInstance(Context & context) const773 TestInstance* AttachmentAccessOrderTestCase::createInstance (Context& context) const
774 {
775 return new AttachmentAccessOrderTestInstance(context, this);
776 }
777
checkAndGetDSFormat(Context & context) const778 VkFormat AttachmentAccessOrderTestCase::checkAndGetDSFormat (Context& context) const
779 {
780 const auto& vki = context.getInstanceInterface();
781 const auto physicalDevice = context.getPhysicalDevice();
782 const auto imageType = getColorImageType();
783 const auto imageTiling = getColorImageTiling();
784 const auto imageUsage = getDSImageUsageFlags();
785
786 const std::vector<VkFormat> dsFormats { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
787 VkFormat supportedFormat = VK_FORMAT_UNDEFINED;
788 VkImageFormatProperties formatProperties;
789
790 for (const auto& dsFormat : dsFormats)
791 {
792 const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, dsFormat, imageType, imageTiling, imageUsage, 0u, &formatProperties);
793
794 if (result == VK_SUCCESS)
795 {
796 if ((formatProperties.sampleCounts & m_sampleCount) != 0)
797 {
798 supportedFormat = dsFormat;
799 break;
800 }
801 }
802 else if (result != VK_ERROR_FORMAT_NOT_SUPPORTED)
803 TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
804 }
805
806 return supportedFormat;
807 }
808
checkSupport(Context & context) const809 void AttachmentAccessOrderTestCase::checkSupport (Context& context) const
810 {
811 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
812
813 // When explicit synchronization is used, there's no need for the extension.
814 if (!m_explicitSync)
815 if (!context.isDeviceFunctionalitySupported("VK_ARM_rasterization_order_attachment_access") && !context.isDeviceFunctionalitySupported("VK_EXT_rasterization_order_attachment_access"))
816 TCU_THROW(NotSupportedError, "Neither VK_ARM_rasterization_order_attachment_access nor VK_EXT_rasterization_order_attachment_access is supported");
817
818 const auto& vki = context.getInstanceInterface();
819 const auto physicalDevice = context.getPhysicalDevice();
820
821 VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterizationAccess = initVulkanStructure();
822 VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(m_explicitSync ? nullptr : &rasterizationAccess);
823
824 vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
825
826 VkPhysicalDeviceProperties2 properties2 = initVulkanStructure();
827
828 vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
829
830 if (m_integerFormat)
831 {
832 const auto format = getColorFormat();
833 const auto imageType = getColorImageType();
834 const auto imageTiling = getColorImageTiling();
835 const auto imageUsage = getColorImageUsageFlags();
836
837 VkImageFormatProperties formatProperties;
838
839 const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, imageType, imageTiling, imageUsage, 0u, &formatProperties);
840 if (result != VK_SUCCESS)
841 {
842 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
843 TCU_THROW(NotSupportedError, "Error: format " + de::toString(format) + " does not support the required features");
844 else
845 TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
846 }
847
848 if ((formatProperties.sampleCounts & m_sampleCount) == 0 ||
849 (properties2.properties.limits.sampledImageIntegerSampleCounts & m_sampleCount) == 0)
850 {
851 TCU_THROW(NotSupportedError, "Sample count not supported");
852 }
853 }
854 else
855 {
856 if ((properties2.properties.limits.framebufferColorSampleCounts & m_sampleCount) == 0 ||
857 (properties2.properties.limits.sampledImageColorSampleCounts & m_sampleCount) == 0)
858 {
859 TCU_THROW(NotSupportedError , "Sample count not supported");
860 }
861 }
862
863 // Check depth/stencil format support if needed.
864 if (getInputAttachmentNum() > getColorAttachmentNum())
865 {
866 const auto format = checkAndGetDSFormat(context);
867 if (format == VK_FORMAT_UNDEFINED)
868 TCU_THROW(NotSupportedError, "No support for any of the required depth/stencil formats");
869 }
870
871 /* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */
872 if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT && !features2.features.sampleRateShading)
873 {
874 TCU_THROW(NotSupportedError , "sampleRateShading feature not supported");
875 }
876
877 if (properties2.properties.limits.maxFragmentOutputAttachments < m_inputAttachmentNum ||
878 properties2.properties.limits.maxPerStageDescriptorInputAttachments < m_inputAttachmentNum)
879 {
880 TCU_THROW(NotSupportedError , "Feedback attachment number not supported");
881 }
882
883 if (!m_explicitSync && !rasterizationAccess.rasterizationOrderColorAttachmentAccess)
884 {
885 TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for color attachments");
886 }
887
888 checkAdditionalRasterizationFlags(rasterizationAccess);
889 }
890
getSampleNum(VkSampleCountFlagBits sampleCount)891 deUint32 AttachmentAccessOrderTestCase::getSampleNum(VkSampleCountFlagBits sampleCount)
892 {
893 deUint32 ret = 0;
894 switch(sampleCount)
895 {
896 case VK_SAMPLE_COUNT_1_BIT: ret = 1; break;
897 case VK_SAMPLE_COUNT_2_BIT: ret = 2; break;
898 case VK_SAMPLE_COUNT_4_BIT: ret = 4; break;
899 case VK_SAMPLE_COUNT_8_BIT: ret = 8; break;
900 case VK_SAMPLE_COUNT_16_BIT: ret = 16; break;
901 case VK_SAMPLE_COUNT_32_BIT: ret = 32; break;
902 case VK_SAMPLE_COUNT_64_BIT: ret = 64; break;
903 default: DE_ASSERT(false);
904 };
905 return ret;
906 }
907
createAttachments(int subpass,deUint32 inputAttachmentNum,deUint32 colorAttachmentNum,VkSampleCountFlagBits sampleCount,Context & context,vector<VkImageView> & views,VkDescriptorSetLayout * pDsetLayout,const AttachmentAccessOrderTestCase * tc)908 void AttachmentAccessOrderTestInstance::RenderSubpass::createAttachments( int subpass, deUint32 inputAttachmentNum, deUint32 colorAttachmentNum,
909 VkSampleCountFlagBits sampleCount,
910 Context &context, vector<VkImageView> &views, VkDescriptorSetLayout *pDsetLayout,
911 const AttachmentAccessOrderTestCase *tc)
912 {
913 m_testCase = tc;
914 m_subpass = subpass;
915 m_sampleCount = sampleCount;
916 m_colorAttNum = colorAttachmentNum;
917 const DeviceInterface& vk = context.getDeviceInterface();
918 const VkDevice device = context.getDevice();
919 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
920 Allocator& allocator = context.getDefaultAllocator();
921
922 // Pipeline Layout
923 {
924 VkPushConstantRange pushConstantsInfo =
925 {
926 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
927 0, // uint32_t offset;
928 4, // uint32_t size;
929 };
930 if (m_testCase->hasDepthStencil())
931 {
932 pushConstantsInfo.stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
933 }
934 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
935 {
936 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
937 DE_NULL, // const void* pNext;
938 0u, // VkPipelineLayoutCreateFlags flags;
939 1u, // deUint32 descriptorSetCount;
940 pDsetLayout, // const VkDescriptorSetLayout* pSetLayouts;
941 m_subpass == 0 ? 1u : 0u, // deUint32 pushConstantRangeCount;
942 m_subpass == 0 ? &pushConstantsInfo : nullptr // const VkPushConstantRange* pPushConstantRanges;
943 };
944 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
945 }
946 VkFormat attFormat = m_testCase->getColorFormat();
947
948 /* Same create info for all the color attachments */
949 const auto imageType = AttachmentAccessOrderTestCase::getColorImageType();
950 const auto imageTiling = AttachmentAccessOrderTestCase::getColorImageTiling();
951 const auto imageUsage = AttachmentAccessOrderTestCase::getColorImageUsageFlags();
952
953 VkImageCreateInfo colorImageCreateInfo =
954 {
955 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
956 DE_NULL, // const void* pNext;
957 0u, // VkImageCreateFlags flags;
958 imageType, // VkImageType imageType;
959 attFormat, // VkFormat format;
960 { WIDTH, HEIGHT, 1u }, // VkExtent3D extent;
961 1u, // deUint32 mipLevels;
962 1u, // deUint32 arrayLayers;
963 sampleCount, // VkSampleCountFlagBits samples;
964 imageTiling, // VkImageTiling tiling;
965 imageUsage, // VkImageUsageFlags usage;
966 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
967 1u, // deUint32 queueFamilyIndexCount;
968 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
969 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
970 };
971
972 for (deUint32 i = 0; i < inputAttachmentNum; i++)
973 {
974 VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
975
976 /* Image for the DS attachment */
977 if (i >= colorAttachmentNum)
978 {
979 attFormat = m_testCase->checkAndGetDSFormat(context);
980 DE_ASSERT(attFormat != VK_FORMAT_UNDEFINED);
981 colorImageCreateInfo.format = attFormat;
982 colorImageCreateInfo.usage = AttachmentAccessOrderTestCase::getDSImageUsageFlags();
983 aspect = m_testCase->getDSAspect();
984 }
985
986 m_inputAtt.push_back(createImage(vk, device, &colorImageCreateInfo, DE_NULL));
987 VkImageViewCreateInfo colorTargetViewInfo =
988 {
989 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
990 DE_NULL, // const void* pNext;
991 0u, // VkImageViewCreateFlags flags;
992 *m_inputAtt.back(), // VkImage image;
993 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
994 attFormat, // VkFormat format;
995 makeComponentMappingRGBA(), // VkComponentMapping components;
996 {
997 aspect, // VkImageAspectFlags aspectMask;
998 0u, // deUint32 baseMipLevel;
999 1u, // deUint32 mipLevels;
1000 0u, // deUint32 baseArrayLayer;
1001 1u, // deUint32 arraySize;
1002 }, // VkImageSubresourceRange subresourceRange;
1003 };
1004 m_inputAttMemory.push_back(allocator.allocate(getImageMemoryRequirements(vk, device, *m_inputAtt.back()), MemoryRequirement::Any));
1005 VK_CHECK(vk.bindImageMemory(device, *m_inputAtt.back(), m_inputAttMemory.back()->getMemory(), m_inputAttMemory.back()->getOffset()));
1006 m_inputAttView.push_back(createImageView(vk, device, &colorTargetViewInfo));
1007
1008 m_attachmentReferences.push_back({(deUint32)views.size(), VK_IMAGE_LAYOUT_GENERAL});
1009 views.push_back(*m_inputAttView.back());
1010 }
1011 }
1012
createPipeline(VkRenderPass renderPass,Context & context)1013 void AttachmentAccessOrderTestInstance::RenderSubpass::createPipeline(VkRenderPass renderPass, Context &context)
1014 {
1015
1016 const DeviceInterface& vk = context.getDeviceInterface();
1017 const VkDevice device = context.getDevice();
1018 const Unique<VkShaderModule> vs(createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "vert1" : "vert2"), 0));
1019 const Unique<VkShaderModule> fs(createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "frag" : "frag_resolve"), 0));
1020
1021 const VkVertexInputBindingDescription vertexInputBindingDescription =
1022 {
1023 0, // deUint32 binding;
1024 sizeof(tcu::Vec2), // deUint32 strideInBytes;
1025 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputStepRate stepRate;
1026 };
1027
1028 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1029 {
1030 0u, // deUint32 location;
1031 0u, // deUint32 binding;
1032 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1033 0u, // deUint32 offsetInBytes;
1034 };
1035
1036 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1037 {
1038 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1039 DE_NULL, // const void* pNext;
1040 0, // VkPipelineVertexInputStateCreateFlags flags;
1041 1u, // deUint32 bindingCount;
1042 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1043 1u, // deUint32 attributeCount;
1044 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1045 };
1046
1047 const std::vector<VkViewport> viewports(1, {0, 0, WIDTH, HEIGHT, 0, 1});
1048 const std::vector<VkRect2D> scissors(1, { {0, 0}, {WIDTH, HEIGHT} });
1049 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
1050 {
1051 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1052 DE_NULL, // const void* pNext;
1053 0u, // VkPipelineRasterizationStateCreateFlags flags;
1054 VK_FALSE, // VkBool32 depthClampEnable;
1055 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1056 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1057 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1058 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1059 VK_FALSE, // VkBool32 depthBiasEnable;
1060 0.0f, // float depthBiasConstantFactor;
1061 0.0f, // float depthBiasClamp;
1062 0.0f, // float depthBiasSlopeFactor;
1063 1.0f, // float lineWidth;
1064 };
1065 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1066 {
1067 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1068 DE_NULL, // const void* pNext;
1069 0u, // VkPipelineMultisampleStateCreateFlags flags;
1070 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1071 VK_TRUE, // VkBool32 sampleShadingEnable;
1072 1.0f, // float minSampleShading;
1073 DE_NULL, // const VkSampleMask* pSampleMask;
1074 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1075 VK_FALSE // VkBool32 alphaToOneEnable;
1076 };
1077 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(m_colorAttNum,
1078 {
1079 false, // VkBool32 blendEnable;
1080 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1081 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1082 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1083 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1084 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1085 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1086 (VK_COLOR_COMPONENT_R_BIT |
1087 VK_COLOR_COMPONENT_G_BIT) // VkChannelFlags channelWriteMask;
1088 });
1089
1090 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1091 {
1092 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1093 DE_NULL, // const void* pNext;
1094 /* always needed */
1095 m_testCase->getBlendStateFlags(), // VkPipelineColorBlendStateCreateFlags flags;
1096 false, // VkBool32 logicOpEnable;
1097 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1098 (deUint32)colorBlendAttachmentState.size(), // deUint32 attachmentCount;
1099 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
1100 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1101 };
1102
1103 VkStencilOpState stencilOpState =
1104 {
1105 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
1106 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp passOp;
1107 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp depthFailOp;
1108 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1109 0xff, // uint32_t compareMask;
1110 0xff, // uint32_t writeMask;
1111 0, // uint32_t reference;
1112 };
1113 VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1114 {
1115 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1116 // VkStructureType sType;
1117 DE_NULL, // const void* pNext;
1118 m_testCase->getDSStateFlags(),
1119 // VkPipelineDepthStencilStateCreateFlags flags;
1120 VK_TRUE, // VkBool32 depthTestEnable;
1121 VK_TRUE, // VkBool32 depthWriteEnable;
1122 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1123 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1124 VK_TRUE, // VkBool32 stencilTestEnable;
1125 stencilOpState, // VkStencilOpState front;
1126 stencilOpState, // VkStencilOpState back;
1127 0.0f, // float minDepthBounds;
1128 1.0f, // float maxDepthBounds;
1129 };
1130
1131
1132 m_pipeline = makeGraphicsPipeline( vk, // const DeviceInterface& vk
1133 device, // const VkDevice device
1134 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
1135 *vs, // const VkShaderModule vertexShaderModule
1136 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1137 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1138 DE_NULL, // const VkShaderModule geometryShaderModule
1139 *fs, // const VkShaderModule fragmentShaderModule
1140 renderPass, // const VkRenderPass renderPass
1141 viewports, // const std::vector<VkViewport>& viewports
1142 scissors, // const std::vector<VkRect2D>& scissors
1143 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,// const VkPrimitiveTopology topology
1144 m_subpass, // const deUint32 subpass
1145 0u, // const deUint32 patchControlPoints
1146 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1147 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1148 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1149 &depthStencilStateCreateInfo, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
1150 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo,
1151 DE_NULL); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
1152 }
1153
makeSampler(const DeviceInterface & vk,const VkDevice & device)1154 static Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
1155 {
1156 const VkSamplerCreateInfo createInfo =
1157 {
1158 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
1159 DE_NULL, // const void* pNext;
1160 0u, // VkSamplerCreateFlags flags;
1161 VK_FILTER_NEAREST, // VkFilter magFilter;
1162 VK_FILTER_NEAREST, // VkFilter minFilter;
1163 VK_SAMPLER_MIPMAP_MODE_LINEAR, // VkSamplerMipmapMode mipmapMode;
1164 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
1165 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
1166 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
1167 0.0f, // float mipLodBias;
1168 VK_FALSE, // VkBool32 anisotropyEnable;
1169 1.0f, // float maxAnisotropy;
1170 VK_FALSE, // VkBool32 compareEnable;
1171 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1172 0.0f, // float minLod;
1173 0.0f, // float maxLod;
1174 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor borderColor;
1175 VK_FALSE // VkBool32 unnormalizedCoordinates;
1176 };
1177
1178 return createSampler(vk, device, &createInfo);
1179 }
1180
makeDescriptorSetLayout(const DeviceInterface & vk,const VkDevice device,deUint32 attNum)1181 static Move<VkDescriptorSetLayout> makeDescriptorSetLayout(const DeviceInterface &vk, const VkDevice device, deUint32 attNum)
1182 {
1183 vector<VkDescriptorSetLayoutBinding> bindings(attNum,
1184 {
1185 0, // binding
1186 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // descriptorType
1187 1u, // descriptorCount
1188 VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
1189 DE_NULL, // pImmutableSamplers
1190 });
1191 for (deUint32 i = 0; i < attNum; i++)
1192 {
1193 bindings[i].binding = i;
1194 }
1195
1196 const VkDescriptorSetLayoutCreateInfo layoutCreateInfo =
1197 {
1198 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1199 DE_NULL, // pNext
1200 0u, // flags
1201 attNum, // bindingCount
1202 bindings.data(), // pBindings
1203 };
1204
1205 return vk::createDescriptorSetLayout(vk, device, &layoutCreateInfo);
1206 }
writeDescriptorSets()1207 void AttachmentAccessOrderTestInstance::writeDescriptorSets()
1208 {
1209 deUint32 attNum = m_testCase->getInputAttachmentNum();
1210 for (deUint32 i = 0 ; i < attNum ; i++ )
1211 {
1212 VkDescriptorImageInfo img_info = {};
1213 img_info.sampler = *m_sampler;
1214 img_info.imageView = *m_subpasses[0].m_inputAttView[i];
1215 img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1216
1217 VkWriteDescriptorSet write = {};
1218 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1219 write.dstSet = *m_descSet;
1220 write.dstBinding = i;
1221 write.dstArrayElement = 0;
1222 write.descriptorCount = 1;
1223 write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1224 write.pImageInfo = &img_info;
1225
1226 m_vk.updateDescriptorSets(m_context.getDevice(), 1u, &write, 0u, DE_NULL);
1227 }
1228 }
1229
addDependency(vector<VkSubpassDependency> & dependencies,deUint32 source,deUint32 dst,VkPipelineStageFlags pipelineFlags,VkAccessFlags accessFlags)1230 void AttachmentAccessOrderTestInstance::addDependency( vector<VkSubpassDependency> &dependencies, deUint32 source, deUint32 dst,
1231 VkPipelineStageFlags pipelineFlags, VkAccessFlags accessFlags)
1232 {
1233 dependencies.push_back({
1234 source, //uint32_t srcSubpass;
1235 dst, //uint32_t dstSubpass;
1236 pipelineFlags, //VkPipelineStageFlags srcStageMask;
1237 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, //VkPipelineStageFlags dstStageMask;
1238 accessFlags, //VkAccessFlags srcAccessMask;
1239 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, //VkAccessFlags dstAccessMask;
1240 VK_DEPENDENCY_BY_REGION_BIT, //VkDependencyFlags dependencyFlags;
1241 });
1242 }
createRenderPass(VkFormat attFormat)1243 Move<VkRenderPass> AttachmentAccessOrderTestInstance::createRenderPass(VkFormat attFormat)
1244 {
1245 const VkDevice device = m_context.getDevice();
1246 vector<VkAttachmentDescription> attachmentDescs;
1247 for (deUint32 subpass = 0; subpass < 2; subpass ++)
1248 {
1249 for (deUint32 i = 0 ; i < m_subpasses[subpass].getInputAttachmentNum(); i++)
1250 {
1251 VkFormat format = attFormat;
1252 if (i >= m_subpasses[subpass].getColorAttachmentNum())
1253 {
1254 format = m_testCase->checkAndGetDSFormat(m_context);
1255 DE_ASSERT(format != VK_FORMAT_UNDEFINED);
1256 }
1257 attachmentDescs.push_back({
1258 0, // VkAttachmentDescriptionFlags flags;
1259 format, // VkFormat format;
1260 m_subpasses[subpass].m_sampleCount, // VkSampleCountFlagBits samples;
1261 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1262 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1263 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1264 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1265 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1266 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout finalLayout;
1267 });
1268 }
1269 }
1270
1271 std::vector<VkSubpassDescription> subpasses(2, VkSubpassDescription{});
1272
1273 subpasses[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1274 subpasses[0].inputAttachmentCount = m_subpasses[0].getInputAttachmentNum();
1275 subpasses[0].pInputAttachments = m_subpasses[0].m_attachmentReferences.data();
1276 subpasses[0].colorAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1277 subpasses[0].pColorAttachments = m_subpasses[0].m_attachmentReferences.data();
1278 subpasses[0].pDepthStencilAttachment = m_subpasses[0].getDepthStencilAttachment();
1279
1280 subpasses[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1281 subpasses[1].inputAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1282 subpasses[1].pInputAttachments = m_subpasses[0].m_attachmentReferences.data();
1283 subpasses[1].colorAttachmentCount = m_subpasses[1].getColorAttachmentNum();
1284 subpasses[1].pColorAttachments = m_subpasses[1].m_attachmentReferences.data();
1285
1286 /* self dependency for subpass 0 and dependency from subpass 0 to 1 */
1287 vector<VkSubpassDependency> dependencies;
1288 addDependency(dependencies, 0, 1, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1289 if (m_testCase->m_explicitSync)
1290 {
1291 addDependency(dependencies, 0, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1292 if (m_testCase->hasDepthStencil())
1293 {
1294 const auto fragTests = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1295 addDependency(dependencies, 0, 0, fragTests, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1296 }
1297 }
1298 else
1299 {
1300 subpasses[0].flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM;
1301 if (m_testCase->hasDepth())
1302 {
1303 subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1304 }
1305 else if (m_testCase->hasStencil())
1306 {
1307 subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1308 }
1309 }
1310
1311 VkRenderPassCreateInfo renderPassCreateInfo =
1312 {
1313 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1314 NULL, // const void* pNext;
1315 0, // VkRenderPassCreateFlags flags;
1316 (deUint32)attachmentDescs.size(), // uint32_t attachmentCount;
1317 attachmentDescs.data(), // const VkAttachmentDescription* pAttachments;
1318 (deUint32)subpasses.size(), // uint32_t subpassCount;
1319 subpasses.data(), // const VkSubpassDescription* pSubpasses;
1320 (deUint32)dependencies.size(), // uint32_t dependencyCount;
1321 dependencies.data(), // const VkSubpassDependency* pDependencies;
1322 };
1323
1324 return ::createRenderPass(m_vk, device, &renderPassCreateInfo);
1325 }
1326
createVertexBuffer()1327 void AttachmentAccessOrderTestInstance::createVertexBuffer()
1328 {
1329 deUint32 primitiveNum = m_testCase->m_overlapPrimitives ? AttachmentAccessOrderTestCase::ELEM_NUM * 2: 2;
1330 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1331 const VkDevice device = m_context.getDevice();
1332 Allocator& allocator = m_context.getDefaultAllocator();
1333 std::vector<tcu::Vec2> vbo(3*primitiveNum);
1334 for (deUint32 i=0; i < primitiveNum/2; i++)
1335 {
1336 vbo[i*6 + 0] = {-1, -1};
1337 vbo[i*6 + 1] = { 1, -1};
1338 vbo[i*6 + 2] = {-1, 1};
1339 vbo[i*6 + 3] = { 1, 1};
1340 vbo[i*6 + 4] = {-1, 1};
1341 vbo[i*6 + 5] = { 1, -1};
1342 }
1343
1344 const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1345 {
1346 const VkBufferCreateInfo vertexBufferParams =
1347 {
1348 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1349 DE_NULL, // const void* pNext;
1350 0u, // VkBufferCreateFlags flags;
1351 dataSize, // VkDeviceSize size;
1352 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1353 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1354 1u, // deUint32 queueFamilyCount;
1355 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1356 };
1357 m_vertexBuffer = createBuffer(m_vk, device, &vertexBufferParams);
1358 m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(m_vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1359
1360 VK_CHECK(m_vk.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
1361 }
1362
1363 /* Load vertices into vertex buffer */
1364 deMemcpy(m_vertexBufferMemory->getHostPtr(), vbo.data(), dataSize);
1365 flushAlloc(m_vk, device, *m_vertexBufferMemory);
1366 }
1367
createResultBuffer()1368 void AttachmentAccessOrderTestInstance::createResultBuffer()
1369 {
1370 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1371 const VkDevice device = m_context.getDevice();
1372 Allocator& allocator = m_context.getDefaultAllocator();
1373 /* result buffer */
1374 const VkBufferCreateInfo resultBufferInfo =
1375 {
1376 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1377 DE_NULL, // const void* pNext;
1378 0u, // VkBufferCreateFlags flags;
1379 WIDTH * HEIGHT * sizeof(tcu::UVec2), // VkDeviceSize size;
1380 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1381 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1382 1u, // deUint32 queueFamilyCount;
1383 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1384 };
1385 m_resultBuffer = createBuffer(m_vk, device, &resultBufferInfo);
1386 m_resultBufferMemory = allocator.allocate( getBufferMemoryRequirements(m_vk, device, *m_resultBuffer), MemoryRequirement::HostVisible);
1387
1388 VK_CHECK(m_vk.bindBufferMemory(device, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
1389 }
1390
AttachmentAccessOrderTestInstance(Context & context,const AttachmentAccessOrderTestCase * testCase)1391 AttachmentAccessOrderTestInstance::AttachmentAccessOrderTestInstance( Context& context, const AttachmentAccessOrderTestCase *testCase)
1392 : TestInstance(context)
1393 , m_testCase (testCase)
1394 , m_vk (m_context.getDeviceInterface())
1395 , m_subpasses(2)
1396 {
1397 const VkDevice device = m_context.getDevice();
1398 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1399
1400 m_descSetLayout = makeDescriptorSetLayout(m_vk, device, m_testCase->getInputAttachmentNum());
1401
1402 m_descPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_testCase->getInputAttachmentNum())
1403 .build(m_vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1404
1405 m_descSet = makeDescriptorSet(m_vk, device, *m_descPool, *m_descSetLayout, nullptr);
1406
1407 vector<VkImageView> attachmentHandles;
1408 VkDescriptorSetLayout dsetLayout = *m_descSetLayout;
1409
1410 m_subpasses[0].createAttachments( 0, m_testCase->getInputAttachmentNum(), m_testCase->getColorAttachmentNum(), m_testCase->m_sampleCount,
1411 m_context, attachmentHandles, &dsetLayout, m_testCase);
1412 m_subpasses[1].createAttachments(1, 1, 1, VK_SAMPLE_COUNT_1_BIT, m_context, attachmentHandles, &dsetLayout, m_testCase);
1413
1414 m_sampler = makeSampler(m_vk, device);
1415
1416 writeDescriptorSets();
1417 m_renderPass = createRenderPass(m_testCase->getColorFormat());
1418
1419 m_framebuffer = makeFramebuffer(m_vk, device, *m_renderPass, (deUint32)attachmentHandles.size(), attachmentHandles.data(), WIDTH, HEIGHT, 1);
1420
1421 m_subpasses[0].createPipeline(*m_renderPass, m_context);
1422 m_subpasses[1].createPipeline(*m_renderPass, m_context);
1423
1424 createVertexBuffer();
1425
1426 createResultBuffer();
1427
1428 m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1429 m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1430 }
1431
~AttachmentAccessOrderTestInstance(void)1432 AttachmentAccessOrderTestInstance::~AttachmentAccessOrderTestInstance (void)
1433 {
1434 }
1435
addPipelineBarrier(VkCommandBuffer cmdBuffer,VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkImageAspectFlags aspect)1436 void AttachmentAccessOrderTestInstance::addPipelineBarrier( VkCommandBuffer cmdBuffer,
1437 VkImage image,
1438 VkImageLayout oldLayout,
1439 VkImageLayout newLayout,
1440 VkAccessFlags srcAccessMask,
1441 VkAccessFlags dstAccessMask,
1442 VkPipelineStageFlags srcStageMask,
1443 VkPipelineStageFlags dstStageMask,
1444 VkImageAspectFlags aspect)
1445 {
1446 VkImageMemoryBarrier barrier =
1447 {
1448 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1449 DE_NULL, // const void* pNext;
1450 srcAccessMask, // VkAccessFlags srcAccessMask;
1451 dstAccessMask, // VkAccessFlags dstAccessMask;
1452 oldLayout, // VkImageLayout oldLayout;
1453 newLayout, // VkImageLayout newLayout;
1454 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1455 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1456 image, // VkImage image;
1457 {
1458 aspect, //VkImageAspectFlags aspectMask;
1459 0u, //uint32_t baseMipLevel;
1460 1u, //uint32_t levelCount;
1461 0u, //uint32_t baseArrayLayer;
1462 1u, //uint32_t layerCount;
1463 }, // VkImageSubresourceRange subresourceRange;
1464 };
1465
1466 m_vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, VK_DEPENDENCY_BY_REGION_BIT,
1467 0, nullptr, 0, nullptr, 1, &barrier);
1468 }
addClearColor(VkCommandBuffer cmdBuffer,VkImage image)1469 void AttachmentAccessOrderTestInstance::addClearColor(VkCommandBuffer cmdBuffer, VkImage image)
1470 {
1471 VkClearColorValue clearColor;
1472 clearColor.float32[0] = 0.0;
1473 clearColor.float32[1] = 0.0;
1474 clearColor.float32[2] = 0.0;
1475 clearColor.float32[3] = 1.0;
1476
1477 const VkImageSubresourceRange subresourceRange =
1478 {
1479 VK_IMAGE_ASPECT_COLOR_BIT, //VkImageAspectFlags aspectMask;
1480 0u, //uint32_t baseMipLevel;
1481 1u, //uint32_t levelCount;
1482 0u, //uint32_t baseArrayLayer;
1483 1u, //uint32_t layerCount;
1484 };
1485
1486 m_vk.cmdClearColorImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
1487 }
1488
addClearDepthStencil(VkCommandBuffer cmdBuffer,VkImage image)1489 void AttachmentAccessOrderTestInstance::addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image)
1490 {
1491 VkClearDepthStencilValue clearValue;
1492 clearValue.depth = 0.0;
1493 clearValue.stencil = 0;
1494
1495 const VkImageSubresourceRange subresourceRange =
1496 {
1497 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, //VkImageAspectFlags aspectMask;
1498 0u, //uint32_t baseMipLevel;
1499 1u, //uint32_t levelCount;
1500 0u, //uint32_t baseArrayLayer;
1501 1u, //uint32_t layerCount;
1502 };
1503
1504 m_vk.cmdClearDepthStencilImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &subresourceRange);
1505 }
1506
1507
iterate(void)1508 tcu::TestStatus AttachmentAccessOrderTestInstance::iterate (void)
1509 {
1510 const VkQueue queue = m_context.getUniversalQueue();
1511 const VkDevice device = m_context.getDevice();
1512
1513 beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
1514
1515 for (deUint32 i=0; i < m_subpasses.size(); i++)
1516 {
1517 for (deUint32 j=0; j < m_subpasses[i].getColorAttachmentNum(); j++)
1518 {
1519 addPipelineBarrier( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1520 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1521
1522 addClearColor( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1523 }
1524 for (deUint32 j=m_subpasses[i].getColorAttachmentNum(); j < m_subpasses[i].getInputAttachmentNum(); j++)
1525 {
1526 addPipelineBarrier( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1527 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1528 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1529 addClearDepthStencil( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1530 }
1531 }
1532
1533 const VkMemoryBarrier memBarrier =
1534 {
1535 VK_STRUCTURE_TYPE_MEMORY_BARRIER,
1536 DE_NULL,
1537 VK_ACCESS_TRANSFER_WRITE_BIT,
1538 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1539 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
1540 };
1541
1542 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1543 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1544
1545 const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
1546 beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
1547
1548 const VkDeviceSize vertexBufferOffset = 0;
1549 const VkBuffer vertexBuffer = *m_vertexBuffer;
1550
1551 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1552 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipeline);
1553 VkDescriptorSet dset = *m_descSet;
1554 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1555
1556 deUint32 numDraws = m_testCase->m_overlapDraws ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1557 deUint32 numPrimitives = m_testCase->m_overlapPrimitives ? 2 * AttachmentAccessOrderTestCase::ELEM_NUM : 2;
1558 deUint32 numInstances = m_testCase->m_overlapInstances ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1559
1560 for (deUint32 i=0; i < numDraws; i++)
1561 {
1562 m_vk.cmdPushConstants( *m_cmdBuffer, *m_subpasses[0].m_pipelineLayout,
1563 VK_SHADER_STAGE_FRAGMENT_BIT | (m_testCase->hasDepthStencil() ? VK_SHADER_STAGE_VERTEX_BIT : 0),
1564 0, 4, &i);
1565 for (deUint32 j = 0; m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getColorAttachmentNum(); j++)
1566 {
1567 addPipelineBarrier( *m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1568 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1569 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1570 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1571 }
1572 for (deUint32 j = m_subpasses[0].getColorAttachmentNum(); m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getInputAttachmentNum(); j++)
1573 {
1574 const auto fragTests = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1575 addPipelineBarrier( *m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1576 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1577 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1578 fragTests, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1579 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1580 }
1581 m_vk.cmdDraw(*m_cmdBuffer, numPrimitives * 3, numInstances, 0, 0);
1582 }
1583
1584
1585 m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1586
1587 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipeline);
1588
1589 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1590
1591 m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 0, 0);
1592
1593 endRenderPass(m_vk, *m_cmdBuffer);
1594
1595 copyImageToBuffer( m_vk, *m_cmdBuffer, *m_subpasses[1].m_inputAtt[0], *m_resultBuffer, tcu::IVec2(WIDTH, HEIGHT), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1596 VK_IMAGE_LAYOUT_GENERAL);
1597
1598 endCommandBuffer(m_vk, *m_cmdBuffer);
1599
1600 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1601
1602 return validateResults(numDraws, numPrimitives, numInstances);
1603 }
1604
validateResults(deUint32 numDraws,deUint32 numPrimitives,deUint32 numInstances)1605 tcu::TestStatus AttachmentAccessOrderTestInstance::validateResults(deUint32 numDraws, deUint32 numPrimitives, deUint32 numInstances)
1606 {
1607 const VkDevice device = m_context.getDevice();
1608 qpTestResult res = QP_TEST_RESULT_PASS;
1609
1610 invalidateAlloc(m_vk, device, *m_resultBufferMemory);
1611 if (m_testCase->m_integerFormat)
1612 {
1613 tcu::UVec2 *resBuf = static_cast<tcu::UVec2 *> (m_resultBufferMemory->getHostPtr());
1614
1615 for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1616 {
1617 for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1618 {
1619 tcu::UVec2 pixel = resBuf[y * WIDTH + x];
1620 if (pixel[0] != 0 || pixel[1] != numDraws * numPrimitives/2 * numInstances)
1621 {
1622 res = QP_TEST_RESULT_FAIL;
1623 }
1624 }
1625 }
1626 }
1627 else
1628 {
1629 tcu::Vec2 *resBuf = static_cast<tcu::Vec2 *> (m_resultBufferMemory->getHostPtr());
1630
1631 for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1632 {
1633 for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1634 {
1635 tcu::Vec2 pixel = resBuf[y * WIDTH + x];
1636 if (pixel[0] != 0 || pixel[1] != (float)(numDraws * numPrimitives/2 * numInstances))
1637 {
1638 res = QP_TEST_RESULT_FAIL;
1639 }
1640 }
1641 }
1642 }
1643
1644 return tcu::TestStatus(res, qpGetTestResultName(res));
1645 }
1646
1647
1648 } // anonymous ns
1649
1650
createRasterizationOrderAttachmentAccessTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,const string & prefix_name,const string & prefix_desc,deUint32 inputNum,bool integerFormat,bool depth,bool stencil)1651 static void createRasterizationOrderAttachmentAccessTestVariations( tcu::TestContext& testCtx, tcu::TestCaseGroup *gr,
1652 const string &prefix_name, const string &prefix_desc,
1653 deUint32 inputNum, bool integerFormat, bool depth, bool stencil)
1654 {
1655 const struct
1656 {
1657 const std::string name;
1658 const std::string description;
1659 bool explicitSync;
1660 bool overlapDraws;
1661 bool overlapPrimitives;
1662 bool overlapInstances;
1663 } leafTestCreateParams[] =
1664 {
1665 { "multi_draw_barriers", "Basic test with overlapping draw commands with barriers", true, true, false, false, },
1666 { "multi_draw", "Test with overlapping draw commands without barriers", false, true, false, false, },
1667 { "multi_primitives", "Test with a draw command with overlapping primitives", false, false, true, false, },
1668 { "multi_instances", "Test with a draw command with overlapping instances", false, false, false, true, },
1669 { "all", "Test with overlapping draw commands, each with overlapping primitives and instances", false, true, true, true, },
1670 };
1671 constexpr deUint32 leafTestCreateParamsNum = sizeof(leafTestCreateParams) / sizeof(leafTestCreateParams[0]);
1672
1673 VkSampleCountFlagBits sampleCountValues[] =
1674 {
1675 VK_SAMPLE_COUNT_1_BIT,
1676 VK_SAMPLE_COUNT_2_BIT,
1677 VK_SAMPLE_COUNT_4_BIT,
1678 VK_SAMPLE_COUNT_8_BIT,
1679 VK_SAMPLE_COUNT_16_BIT,
1680 VK_SAMPLE_COUNT_32_BIT,
1681 VK_SAMPLE_COUNT_64_BIT,
1682 };
1683 constexpr deUint32 sampleCountValuesNum = sizeof(sampleCountValues) / sizeof(sampleCountValues[0]);
1684
1685 for (deUint32 i = 0; i < sampleCountValuesNum ; i++)
1686 {
1687 stringstream name;
1688 stringstream desc;
1689 name << prefix_name << "samples_" << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]);
1690 desc << prefix_desc << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]) << " samples per pixel";
1691 tcu::TestCaseGroup *subgr = new tcu::TestCaseGroup(testCtx, name.str().c_str(), desc.str().c_str());
1692
1693 for (deUint32 k = 0; k < leafTestCreateParamsNum; k++)
1694 {
1695 if (depth)
1696 {
1697 subgr->addChild(new AttachmentAccessOrderDepthTestCase( testCtx, leafTestCreateParams[k].name,
1698 leafTestCreateParams[k].description,
1699 leafTestCreateParams[k].explicitSync,
1700 leafTestCreateParams[k].overlapDraws,
1701 leafTestCreateParams[k].overlapPrimitives,
1702 leafTestCreateParams[k].overlapInstances,
1703 sampleCountValues[i]));
1704 }
1705 else if (stencil)
1706 {
1707 subgr->addChild(new AttachmentAccessOrderStencilTestCase( testCtx, leafTestCreateParams[k].name,
1708 leafTestCreateParams[k].description,
1709 leafTestCreateParams[k].explicitSync,
1710 leafTestCreateParams[k].overlapDraws,
1711 leafTestCreateParams[k].overlapPrimitives,
1712 leafTestCreateParams[k].overlapInstances,
1713 sampleCountValues[i]));
1714 }
1715 else
1716 {
1717 subgr->addChild(new AttachmentAccessOrderColorTestCase( testCtx, leafTestCreateParams[k].name,
1718 leafTestCreateParams[k].description,
1719 leafTestCreateParams[k].explicitSync,
1720 leafTestCreateParams[k].overlapDraws,
1721 leafTestCreateParams[k].overlapPrimitives,
1722 leafTestCreateParams[k].overlapInstances,
1723 sampleCountValues[i], inputNum, integerFormat));
1724 }
1725 }
1726 gr->addChild(subgr);
1727 }
1728 }
1729
createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,bool integerFormat)1730 static void createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *gr, bool integerFormat)
1731 {
1732 const deUint32 inputNum[] = {1, 4, 8};
1733 const deUint32 inputNumSize = sizeof(inputNum) / sizeof(inputNum[0]);
1734
1735 tcu::TestCaseGroup *formatGr;
1736
1737 if (integerFormat)
1738 {
1739 formatGr = new tcu::TestCaseGroup(testCtx, "format_integer", "Tests with an integer format" );
1740 }
1741 else
1742 {
1743 formatGr = new tcu::TestCaseGroup(testCtx, "format_float", "Tests with an float format" );
1744 }
1745
1746 for (deUint32 i = 0; i < inputNumSize; i++)
1747 {
1748 stringstream numName;
1749 stringstream numDesc;
1750 numName << "attachments_" << inputNum[i] << "_";
1751 numDesc << "Tests with " << inputNum[i] << " attachments and ";
1752 createRasterizationOrderAttachmentAccessTestVariations(testCtx, formatGr, numName.str(), numDesc.str(), inputNum[i], integerFormat, false, false);
1753 }
1754 gr->addChild(formatGr);
1755 }
1756
createRasterizationOrderAttachmentAccessTests(tcu::TestContext & testCtx)1757 tcu::TestCaseGroup* createRasterizationOrderAttachmentAccessTests(tcu::TestContext& testCtx)
1758 {
1759 /* Add the color tests */
1760 tcu::TestCaseGroup *gr = new tcu::TestCaseGroup(testCtx, "rasterization_order_attachment_access", "Rasterization Order Attachment access tests");
1761 createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, false);
1762 createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, true);
1763
1764 /* Add the D/S tests */
1765 tcu::TestCaseGroup *depth_gr = new tcu::TestCaseGroup(testCtx, "depth", "Tests depth rasterization order" );
1766 tcu::TestCaseGroup *stencil_gr = new tcu::TestCaseGroup(testCtx, "stencil", "Tests stencil rasterization order" );
1767 string name_prefix = "";
1768 string desc_prefix = "Tests with ";
1769 createRasterizationOrderAttachmentAccessTestVariations(testCtx, depth_gr, name_prefix, desc_prefix, 1, false, true, false);
1770 createRasterizationOrderAttachmentAccessTestVariations(testCtx, stencil_gr, name_prefix, desc_prefix, 1, false, false, true);
1771 gr->addChild(depth_gr);
1772 gr->addChild(stencil_gr);
1773
1774 return gr;
1775 }
1776
1777 } // rasterization
1778 } // vkt
1779