1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2022 The Khronos Group Inc.
6 * Copyright (c) 2022 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_EXT_shader_tile_image tests.
23 *//*--------------------------------------------------------------------*/
24
25 // Draw overwrapped patches with incremental value. The last value should be the patch count.
26 // Decision is made with comparing between simulated value and result value.
27 // All multi sample tests run with per sample shading property except MsaaSampleMask test case.
28 // There are several variants.
29 // - Color
30 // - Depth
31 // - Stencil
32 // - Msaa
33 // - Formats
34 // - Draw Count
35 // - Patch Count per Draw
36 // - Coherent Mode
37 // ...
38
39 #include "vktShaderTileImageTests.hpp"
40 #include "deDefs.hpp"
41 #include "deSharedPtr.hpp"
42 #include "deUniquePtr.hpp"
43 #include "draw/vktDrawBufferObjectUtil.hpp"
44 #include "tcuCommandLine.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuResource.hpp"
47 #include "tcuStringTemplate.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "vkBuilderUtil.hpp"
51 #include "vkCmdUtil.hpp"
52 #include "vkDefs.hpp"
53 #include "vkImageUtil.hpp"
54 #include "vkMemUtil.hpp"
55 #include "vkObjUtil.hpp"
56 #include "vkPrograms.hpp"
57 #include "vkQueryUtil.hpp"
58 #include "vkRef.hpp"
59 #include "vkRefUtil.hpp"
60 #include "vkTypeUtil.hpp"
61 #include "vktRasterizationTests.hpp"
62 #include "vktTestCase.hpp"
63
64 using namespace vk;
65 using de::MovePtr;
66 using de::SharedPtr;
67
68 namespace vkt
69 {
70
71 namespace rasterization
72 {
73
74 namespace
75 {
76
77 constexpr deUint32 kImageSize = 4; // power of 2 for helper test
78 constexpr deUint32 kMultiDrawElementCount = 3;
79 constexpr deUint32 kMultiPatchElementCount = 3;
80 constexpr deUint32 kMRTCount = 2;
81 constexpr uint32_t kDerivative0 = 1; // derivative 0 + offset 1
82 constexpr uint32_t kDerivative1 = 2; // derivative 1 + offset 1
83
84 enum class TestType
85 {
86 Color,
87 MultiRenderTarget,
88 MultiRenderTargetDynamicIndex,
89 MsaaSampleMask,
90 HelperClassColor,
91 HelperClassDepth,
92 HelperClassStencil,
93 Depth,
94 Stencil
95 };
96
97 struct TestParam
98 {
99 bool coherent;
100 TestType testType;
101 VkFormat colorFormat;
102 VkFormat depthStencilFormat;
103 VkSampleCountFlagBits m_sampleCount;
104 bool multipleDrawCalls;
105 bool multiplePatchesPerDraw;
106 deUint32 frameBufferSize;
107 };
108
isHelperClassTest(TestType testType)109 bool isHelperClassTest(TestType testType)
110 {
111 const bool helperClass = (testType == TestType::HelperClassColor) || (testType == TestType::HelperClassDepth) ||
112 (testType == TestType::HelperClassStencil);
113 return helperClass;
114 }
115
getSampleCount(VkSampleCountFlagBits sampleCount)116 deUint32 getSampleCount(VkSampleCountFlagBits sampleCount)
117 {
118 deUint32 ret = 0;
119 switch (sampleCount)
120 {
121 case VK_SAMPLE_COUNT_1_BIT:
122 ret = 1;
123 break;
124 case VK_SAMPLE_COUNT_2_BIT:
125 ret = 2;
126 break;
127 case VK_SAMPLE_COUNT_4_BIT:
128 ret = 4;
129 break;
130 case VK_SAMPLE_COUNT_8_BIT:
131 ret = 8;
132 break;
133 case VK_SAMPLE_COUNT_16_BIT:
134 ret = 16;
135 break;
136 case VK_SAMPLE_COUNT_32_BIT:
137 ret = 32;
138 break;
139 case VK_SAMPLE_COUNT_64_BIT:
140 ret = 64;
141 break;
142 default:
143 DE_ASSERT(false);
144 };
145 return ret;
146 }
147
getSampleMask(TestType testType)148 deUint32 getSampleMask(TestType testType)
149 {
150 return (testType == TestType::MsaaSampleMask) ? 0xaaaaaaaa : 0;
151 }
152
getColorAttachmentCount(TestType testType)153 deUint32 getColorAttachmentCount(TestType testType)
154 {
155 switch (testType)
156 {
157 case TestType::MultiRenderTargetDynamicIndex:
158 case TestType::MultiRenderTarget:
159 case TestType::HelperClassColor:
160 case TestType::HelperClassDepth:
161 case TestType::HelperClassStencil:
162 return kMRTCount;
163 default:
164 return 1;
165 }
166 return 1;
167 }
168
getVertexCountPerPatch(const TestParam * testParam)169 deUint32 getVertexCountPerPatch(const TestParam* testParam)
170 {
171 return (testParam->testType == TestType::MsaaSampleMask) ? 3 : 6;
172 }
173
getPatchesPerDrawCount(bool multiplePatchesPerDraw)174 deUint32 getPatchesPerDrawCount(bool multiplePatchesPerDraw)
175 {
176 return multiplePatchesPerDraw ? kMultiPatchElementCount : 1;
177 }
178
getDrawCallCount(const TestParam * testParam)179 deUint32 getDrawCallCount(const TestParam* testParam)
180 {
181 if (isHelperClassTest(testParam->testType))
182 {
183 // helper class use two draw calls, but it is similar to single draw call
184 DE_ASSERT(!testParam->multipleDrawCalls);
185 return 2;
186 }
187
188 return testParam->multipleDrawCalls ? kMultiDrawElementCount : 1;
189 }
190
isNormalizedColorFormat(VkFormat format)191 bool isNormalizedColorFormat(VkFormat format)
192 {
193 const tcu::TextureFormat colorFormat(mapVkFormat(format));
194 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
195 const bool normalizedColorFormat = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
196 channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT);
197 return normalizedColorFormat;
198 }
199
addOverhead(std::stringstream & shaderStream)200 void addOverhead(std::stringstream& shaderStream)
201 {
202 shaderStream << "{\n"
203 << " uint overheadLoop = uint(gl_FragCoord.x) * uint(${TOTAL_PATCH_COUNT} + 1);\n"
204 << " zero = patchIndex / (${TOTAL_PATCH_COUNT} + 1);\n"
205 << " for(uint index = 0u; index < overheadLoop; index++)\n"
206 << " {\n"
207 << " zero = uint(sin(float(zero)));\n"
208 << " }\n"
209 << "}\n";
210 }
211
transition2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageAspectFlags aspectMask,vk::VkImageLayout oldLayout,vk::VkImageLayout newLayout,vk::VkAccessFlags srcAccessMask,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags srcStageMask,vk::VkPipelineStageFlags dstStageMask)212 void transition2DImage(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
213 vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout,
214 vk::VkAccessFlags srcAccessMask, vk::VkAccessFlags dstAccessMask,
215 vk::VkPipelineStageFlags srcStageMask, vk::VkPipelineStageFlags dstStageMask)
216 {
217 vk::VkImageMemoryBarrier barrier;
218 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
219 barrier.pNext = DE_NULL;
220 barrier.srcAccessMask = srcAccessMask;
221 barrier.dstAccessMask = dstAccessMask;
222 barrier.oldLayout = oldLayout;
223 barrier.newLayout = newLayout;
224 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
225 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
226 barrier.image = image;
227 barrier.subresourceRange.aspectMask = aspectMask;
228 barrier.subresourceRange.baseMipLevel = 0;
229 barrier.subresourceRange.levelCount = 1;
230 barrier.subresourceRange.baseArrayLayer = 0;
231 barrier.subresourceRange.layerCount = 1;
232
233 vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0,
234 (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1,
235 &barrier);
236 }
237
238 class ShaderTileImageTestCase : public TestCase
239 {
240 public:
241 ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam);
242 ~ShaderTileImageTestCase() override = default;
243 TestInstance* createInstance(Context& context) const override;
244
245 protected:
246 void initPrograms(SourceCollections& programCollection) const override;
247 void checkSupport(Context& context) const override;
248
249 void addVS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
250 void addFS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
251 void addCS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
252
253 void getColorTestTypeFS(std::stringstream& fragShader) const;
254 void getHelperClassTestTypeFS(std::stringstream& fragShader) const;
255 void getSampleMaskTypeFS(std::stringstream& fragShader) const;
256 void getDepthTestTypeFS(std::stringstream& fragShader) const;
257 void getStencilTestTypeFS(std::stringstream& fragShader) const;
258
259 protected:
260 const TestParam m_testParam;
261 };
262
263 class ShaderTileImageTestInstance : public TestInstance
264 {
265 public:
266 ShaderTileImageTestInstance(Context& context, const TestParam* testParam);
267 ~ShaderTileImageTestInstance() override = default;
268 tcu::TestStatus iterate() override;
269
270 protected:
271 void initialize();
272 void generateCmdBuffer();
273 void generateVertexBuffer();
274 void generateAttachments();
275 Move<VkPipeline> generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite,
276 bool disableStencilWrite);
277 void generateComputePipeline();
278 void rendering();
279 deUint32 getResultValue(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const;
280 deUint32 simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const;
281 tcu::TestStatus checkResult() const;
282
283 protected:
284 const TestParam* m_testParam;
285
286 const DeviceInterface& m_vk;
287 SharedPtr<Draw::Buffer> m_vertexBuffer;
288
289 Move<VkCommandPool> m_cmdPool;
290 Move<VkCommandBuffer> m_cmdBuffer;
291 Move<vk::VkDescriptorPool> m_descriptorPool;
292 Move<vk::VkDescriptorSet> m_descriptorSets[kMRTCount];
293 Move<VkPipelineLayout> m_graphicsPipelineLayout;
294 Move<VkPipeline> m_graphicsPipeline;
295 Move<VkPipeline> m_graphicsPipelineForHelperClass;
296 Move<vk::VkDescriptorSetLayout> m_computeDescriptorSetLayout;
297 Move<VkPipelineLayout> m_computePipelineLayout;
298 Move<VkPipeline> m_computePipeline;
299 Move<VkShaderModule> m_vertexModule;
300 Move<VkShaderModule> m_fragmentModule;
301 Move<VkImage> m_imageColor[kMRTCount];
302 MovePtr<Allocation> m_imageColorAlloc[kMRTCount];
303 deUint32* m_imageColorBufferHostPtr;
304 Move<VkImageView> m_imageColorView[kMRTCount];
305 SharedPtr<Draw::Buffer> m_imageBuffer[kMRTCount];
306 Move<VkImage> m_imageDepthStencil;
307 MovePtr<Allocation> m_imageDepthStencilAlloc;
308 Move<VkImageView> m_imageDepthStencilView;
309 };
310
ShaderTileImageTestCase(tcu::TestContext & context,const std::string & name,const TestParam & testParam)311 ShaderTileImageTestCase::ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam)
312 : TestCase(context, name), m_testParam(testParam)
313 {
314 }
315
addVS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const316 void ShaderTileImageTestCase::addVS(SourceCollections& programCollection,
317 const std::map<std::string, std::string>& params) const
318 {
319 std::stringstream vertShader;
320 vertShader << "#version 450 core\n"
321 << "precision highp float;\n"
322 << "precision highp int;\n"
323 << "layout(location = 0) in highp vec2 v_position;\n"
324 << "layout(location = 0) flat out uint patchIndex;"
325 << "layout( push_constant ) uniform ConstBlock\n"
326 << "{\n"
327 << " highp uint drawIndex;\n"
328 << "};\n"
329 << "void main ()\n"
330 << "{\n"
331 << " uint localPatchIndex = uint(gl_VertexIndex) / ${VERTEX_COUNT_PER_PATCH} + 1;\n" // index from 1
332 << " uint patchCountPerDraw = ${PATCH_COUNT_PER_DRAW};\n"
333 << " uint globalPatchIndex = drawIndex * patchCountPerDraw + localPatchIndex;\n"
334 << " patchIndex = globalPatchIndex;\n"
335 << " gl_Position = vec4(v_position, ${INV_TOTAL_PATCH_COUNT} * globalPatchIndex, 1);\n"
336 << "}\n";
337
338 tcu::StringTemplate vertShaderTpl(vertShader.str());
339 programCollection.glslSources.add("vert") << glu::VertexSource(vertShaderTpl.specialize(params));
340 }
341
getColorTestTypeFS(std::stringstream & fragShader) const342 void ShaderTileImageTestCase::getColorTestTypeFS(std::stringstream& fragShader) const
343 {
344 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType);
345 const bool mrtDynamicIndexTestType = (m_testParam.testType == TestType::MultiRenderTargetDynamicIndex);
346 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
347
348 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat));
349 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
350 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
351 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat);
352
353 fragShader << "#version 450 core\n"
354 << "#extension GL_EXT_shader_tile_image : require\n"
355 << "precision highp float;\n"
356 << "precision highp int;\n"
357 << "layout( push_constant ) uniform ConstBlock\n"
358 << "{\n"
359 << " highp uint drawIndex;\n"
360 << "};\n"
361 << "layout( location = 0 ) flat in uint patchIndex;\n";
362
363 if (!m_testParam.coherent)
364 {
365 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
366 }
367
368 if (mrtDynamicIndexTestType)
369 {
370 // layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn[0]
371 fragShader << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn[${ATTACHMENT_COUNT}];\n";
372 }
373 else
374 {
375 for (deUint32 i = 0; i < attachmentCount; i++)
376 {
377 // layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn0
378 fragShader << "layout( location = " << i << ") tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn" << i << ";\n";
379 }
380 }
381
382 for (deUint32 i = 0; i < attachmentCount; i++)
383 {
384 // layout( location = 0 ) out highp vec4 out0
385 fragShader << "layout( location = " << i << " ) out highp ${OUTPUT_VECTOR_NAME} out" << i << ";\n";
386 }
387
388 fragShader << "void main()\n"
389 << "{\n"
390 << " uint zero = 0;\n"
391 << " uvec2 previous[${ATTACHMENT_COUNT}];\n";
392
393 float amplifier = 1.0f;
394 if (normalizedColorFormat)
395 {
396 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
397 static_cast<float>(1 << (channelBitDepth.y() - 1)) : // signed
398 static_cast<float>((1 << channelBitDepth.y()) - 1); // unsigned
399
400 // color output precision is less than test case;
401 DE_ASSERT(amplifier > static_cast<float>(kMultiPatchElementCount * kMultiDrawElementCount * attachmentCount +
402 getSampleCount(m_testParam.m_sampleCount)));
403 }
404
405 for (deUint32 i = 0; i < attachmentCount; i++)
406 {
407 // in0 or colorIn[0]
408 const std::string inputImage =
409 mrtDynamicIndexTestType ? "colorIn[" + std::to_string(i) + "]" : "colorIn" + std::to_string(i);
410
411 // (in0) or (colorIn0, gl_SampleID)
412 const std::string funcParams = multiSampleTest ? "(" + inputImage + ", gl_SampleID)" : "(" + inputImage + ")";
413
414 if (normalizedColorFormat)
415 {
416 // previous[0] = round(colorAttachmentRead(in0) * amplifier).xy;\n";
417 fragShader << " previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << " * "
418 << amplifier << ").xy));\n";
419 }
420 else
421 {
422 // previous[0] *= uvec2(round(colorAttachmentRead(in0).xy));\n";
423 fragShader << " previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << ").xy));\n";
424 }
425 }
426
427 // add overhead after fetching data
428 addOverhead(fragShader);
429
430 // used only for normalized color format
431 const float invAmplifier = 1.0f / static_cast<float>(amplifier);
432
433 // write output
434 for (deUint32 i = 0; i < attachmentCount; i++)
435 {
436 // if (previous[0].x == 0 && patchIndex == 1)", initial write
437 // out0.y = float(patchIndex + zero + gl_SampleID + 0);"
438 // else if (previous[0].x == 0 && (previous[0].y + 1) == (patchIndex + gl_SampleID + 0))"
439 // out0.y = float(previous[0].y + 1);"
440 // else
441 // out0.y = float(previous[0].y);"
442 // out0.x = 1;" // error
443 fragShader << " if (previous[" << i << "].x == 0 && patchIndex == 1)\n"
444 << " {\n"
445 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(patchIndex + zero + gl_SampleID + " << i << ");\n"
446 << " }\n"
447 << " else if (previous[" << i << "].x == 0 && (previous[" << i
448 << "].y + 1) == (patchIndex + gl_SampleID + " << i << "))\n"
449 << " {\n"
450 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y + 1 + zero);\n"
451 << " }\n"
452 << " else\n"
453 << " {\n"
454 << " out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y);\n" // for debug purpose
455 << " out" << i << ".x = 1;\n" // error
456 << " }\n";
457
458 if (normalizedColorFormat)
459 {
460 // out0.y *= invAmplifier;
461 fragShader << " out" << i << ".y *= " << invAmplifier << ";\n";
462 }
463 }
464 fragShader << "}\n";
465 }
466
getHelperClassTestTypeFS(std::stringstream & fragShader) const467 void ShaderTileImageTestCase::getHelperClassTestTypeFS(std::stringstream& fragShader) const
468 {
469 const bool depthHelperClassTest = (m_testParam.testType == TestType::HelperClassDepth);
470 const bool stencilHelperClassTest = (m_testParam.testType == TestType::HelperClassStencil);
471
472 DE_ASSERT(getPatchesPerDrawCount(!m_testParam.multiplePatchesPerDraw));
473 DE_ASSERT(getDrawCallCount(&m_testParam) == 2);
474 DE_ASSERT(getColorAttachmentCount(m_testParam.testType) == 2);
475 DE_ASSERT((m_testParam.m_sampleCount == VK_SAMPLE_COUNT_1_BIT));
476 DE_ASSERT(!isNormalizedColorFormat(m_testParam.colorFormat));
477
478 fragShader << "#version 450 core\n"
479 << "#extension GL_EXT_shader_tile_image : require\n"
480 << "precision highp float;\n"
481 << "precision highp int;\n"
482 << "layout( push_constant ) uniform ConstBlock\n"
483 << "{\n"
484 << " highp uint drawIndex;\n"
485 << "};\n"
486 << "layout( location = 0 ) flat in uint patchIndex;\n";
487
488 if (!m_testParam.coherent)
489 {
490 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
491 if (depthHelperClassTest)
492 {
493 fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n";
494 }
495
496 if (stencilHelperClassTest)
497 {
498 fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n";
499 }
500 }
501
502 fragShader << "layout(location = 0) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n";
503 fragShader << "layout(location = 1) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn1;\n";
504
505 fragShader << "layout(location = 0) out highp ${OUTPUT_VECTOR_NAME} out0;\n";
506 fragShader << "layout(location = 1) out highp ${OUTPUT_VECTOR_NAME} out1;\n";
507
508 fragShader << "void main()\n"
509 << "{\n"
510 << " uint zero = 0;\n"
511 << " uvec2 previous;\n";
512
513 if (depthHelperClassTest)
514 {
515 fragShader << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n";
516 fragShader << " previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n"; // read error status
517 fragShader << " previous.y = uint(round(depthAttachmentReadEXT() * scalingFactor));\n"; // read depth value
518 }
519 else if (stencilHelperClassTest)
520 {
521 fragShader << " previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n"; // read error status
522 fragShader << " previous.y = uint(stencilAttachmentReadEXT());\n"; // read stencil value
523 }
524 else
525 {
526 fragShader << " previous = uvec2(round((colorAttachmentReadEXT(colorIn0)).xy));\n";
527 }
528
529 {
530 // draw only one triangle for helperClassTestType, dx or dy should be 0 inside of triangle.
531 // And they should be patchIndex in the diagonal edge of triangle.
532 fragShader << " uint err = 0;\n"
533 << " uint dx = 0;\n"
534 << " uint dy = 0;\n"
535 << " if (patchIndex != 1)"
536 << " {\n"
537 << " dx = uint(round(abs(dFdxFine(previous.y))));\n"
538 << " dy = uint(round(abs(dFdyFine(previous.y))));\n"
539 << " uint err = 0;\n"
540 << " if ((dx != 0 && dx != patchIndex - 1) || (dy != 0 && dy != patchIndex - 1))\n"
541 << " {\n"
542 << " err = 1;\n" // first draw doesn't have error check.
543 << " }\n"
544 << " }\n";
545 }
546
547 // add overhead after fetching data
548 addOverhead(fragShader);
549
550 // first draw writes to attachment0
551 // second draw reads from attachment0(depth) writes to attachment1
552 {
553 fragShader << " if (patchIndex == 1 && err != 1)\n"
554 << " {\n"
555 << " out0.y = ${OUTPUT_BASIC_TYPE}(patchIndex);\n"
556 << " out0.x = 0;\n" // error
557 << " }\n"
558 << " else if (previous.x == 0 && err != 1 && ((previous.y + 1) == patchIndex || previous.y == 0))\n"
559 << " {\n"
560 << " out1.y = ${OUTPUT_BASIC_TYPE}(max(dx, dy) + 1);\n" // last 1 is to differentiate clear value
561 << " }\n"
562 << " else\n"
563 << " {\n"
564 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous.y);\n" // for debug purpose
565 << " out0.x = 1;\n" // error
566 << " out1.y = ${OUTPUT_BASIC_TYPE}(previous.x);\n"
567 << " out1.x = 1;\n" // error
568 << " }\n";
569 }
570 fragShader << "}\n";
571 }
572
getSampleMaskTypeFS(std::stringstream & fragShader) const573 void ShaderTileImageTestCase::getSampleMaskTypeFS(std::stringstream& fragShader) const
574 {
575 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount);
576
577 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat));
578 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
579 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
580 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat);
581
582 deUint32 amplifier = 1;
583 if (normalizedColorFormat)
584 {
585 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
586 (1 << (channelBitDepth.y() - 1)) : // signed
587 ((1 << channelBitDepth.y()) - 1); // unsigned
588 }
589
590 // Samples which is not covered should be 0
591 fragShader << "#version 450 core\n"
592 << "#extension GL_EXT_shader_tile_image : require\n"
593 << "precision highp float;\n"
594 << "precision highp int;\n"
595 << "layout( push_constant ) uniform ConstBlock\n"
596 << "{\n"
597 << " highp uint drawIndex;\n"
598 << "};\n";
599 if (!m_testParam.coherent)
600 {
601 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
602 }
603 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
604 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
605 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
606 << "\n"
607 << "void main()\n"
608 << "{\n"
609 << " uint zero = 0;\n"
610 << " uint previous = 0;\n"
611 << " bool error = false;\n"
612 << " for (int i = 0; i < " << sampleCount << "; ++i)\n"
613 << " {\n"
614 << " if (((gl_SampleMaskIn[0] >> i) & 0x1) == 0x1)\n"
615 << " {\n"
616 << " uvec2 previousSample = uvec2(round(colorAttachmentReadEXT"
617 << "(colorIn0, i) * " << amplifier << ")).xy;\n"
618 << " if (previousSample.x != 0)\n"
619 << " {\n"
620 << " error = true;\n"
621 << " break;"
622 << " }\n"
623 << " if (previous == 0)\n"
624 << " {\n"
625 << " previous = previousSample.y;\n" // write non zero value to the covered sample
626 << " }\n"
627 << "\n"
628 << " if ((patchIndex != 1 && previousSample.y == 0) || previous != previousSample.y)\n"
629 << " {\n"
630 << " error = true;\n"
631 << " break;\n"
632 << " }\n"
633 << " }\n"
634 << " }\n"
635 << "\n";
636
637 // add overhead after fetching data
638 addOverhead(fragShader);
639
640 // write output
641 fragShader << "if (!error && (previous + 1 == patchIndex))\n"
642 << " {\n"
643 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous + 1 + zero);\n"
644 << " }\n"
645 << " else\n"
646 << " {\n"
647 << " out0.y = ${OUTPUT_BASIC_TYPE}(previous);\n"
648 << " out0.x = 1;\n" // error
649 << " }\n";
650
651 const float invAmplifier = 1.0f / static_cast<float>(amplifier);
652 if (normalizedColorFormat)
653 {
654 fragShader << " out0.y *= " << invAmplifier << ";\n";
655 }
656
657 fragShader << "}\n";
658 }
659
getDepthTestTypeFS(std::stringstream & fragShader) const660 void ShaderTileImageTestCase::getDepthTestTypeFS(std::stringstream& fragShader) const
661 {
662 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
663 const std::string depthFuncParams = multiSampleTest ? "(gl_SampleID)" : "()";
664 const std::string colorFuncParams = multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)";
665 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount);
666
667 fragShader << "#version 450 core\n"
668 << "#extension GL_EXT_shader_tile_image : require\n"
669 << "precision highp float;\n"
670 << "precision highp int;\n"
671 << "layout( push_constant ) uniform ConstBlock\n"
672 << "{\n"
673 << " highp uint drawIndex;\n"
674 << "};\n";
675 if (!m_testParam.coherent)
676 {
677 fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n";
678 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
679 }
680 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
681 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
682 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
683 << "\n"
684 << "void main()\n"
685 << "{\n"
686 << " uint zero = 0;\n"
687 << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n";
688 if (multiSampleTest)
689 {
690 // scaling with (patch count + sample count) for multisample case
691 fragShader << " scalingFactor += " << sampleCount << ";\n";
692 }
693 fragShader << " uint previousDepth = uint(round(depthAttachmentReadEXT" << depthFuncParams
694 << " * scalingFactor));\n"
695 << " ${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT"
696 << colorFuncParams << "));\n";
697
698 // add overhead after fetching data
699 addOverhead(fragShader);
700
701 // write output
702 fragShader << " if (previous.x == 0 && patchIndex == 1)\n"
703 << " {\n"
704 << " out0.y = (1u + zero + gl_SampleID);\n"
705 << " }\n"
706 << " else if (previous.x == 0 && (previous.y + 1) == (patchIndex + gl_SampleID) && (previousDepth + 1) "
707 "== (patchIndex + gl_SampleID))\n"
708 << " {\n"
709 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth + 1 + zero);\n"
710 << " }\n"
711 << " else\n"
712 << " {\n"
713 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth);\n" // debug purpose
714 << " out0.x = 1;\n" // error
715 << " }\n";
716
717 if (multiSampleTest)
718 {
719 // Depth value is written without adding SampleID.
720 // Forcely write all fragment depth
721 fragShader << " gl_FragDepth = float(out0.y) / scalingFactor;\n";
722 }
723
724 fragShader << "}\n";
725 }
726
getStencilTestTypeFS(std::stringstream & fragShader) const727 void ShaderTileImageTestCase::getStencilTestTypeFS(std::stringstream& fragShader) const
728 {
729 const bool multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
730 const std::string stencilFuncParams = multiSampleTest ? "(gl_SampleID)" : "()";
731 const std::string colorFuncParams = multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)";
732
733 fragShader << "#version 450 core\n"
734 << "#extension GL_EXT_shader_tile_image : require\n"
735 << "precision highp float;\n"
736 << "precision highp int;\n"
737 << "layout( push_constant ) uniform ConstBlock\n"
738 << "{\n"
739 << " highp uint drawIndex;\n"
740 << "};\n";
741 if (!m_testParam.coherent)
742 {
743 fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n";
744 fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
745 }
746 fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
747 << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
748 << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
749 << "\n"
750 << "void main()\n"
751 << "{\n"
752 << " uint zero = 0;\n"
753 << " uint previousStencil = uint(round(stencilAttachmentReadEXT" << stencilFuncParams << " ));\n"
754 << " ${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT"
755 << colorFuncParams << "));\n";
756
757 // add overhead after fetching data
758 addOverhead(fragShader);
759
760 // write output
761 fragShader << " if (previous.x == 0 && (previous.y + 1) == patchIndex && (previousStencil + 1) == patchIndex)\n"
762 << " {\n"
763 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil + 1 + zero);\n"
764 << " }\n"
765 << " else\n"
766 << " {\n"
767 << " out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil);\n" // debug purpose
768 << " out0.x = 1;\n" // error
769 << " }\n"
770 << "}\n";
771 }
772
addFS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const773 void rasterization::ShaderTileImageTestCase::addFS(SourceCollections& programCollection,
774 const std::map<std::string, std::string>& params) const
775 {
776 std::stringstream fragShader;
777
778 switch (m_testParam.testType)
779 {
780 case TestType::Color:
781 case TestType::MultiRenderTarget:
782 case TestType::MultiRenderTargetDynamicIndex:
783 getColorTestTypeFS(fragShader);
784 break;
785 case TestType::HelperClassColor:
786 case TestType::HelperClassDepth:
787 case TestType::HelperClassStencil:
788 getHelperClassTestTypeFS(fragShader);
789 break;
790 case TestType::MsaaSampleMask:
791 getSampleMaskTypeFS(fragShader);
792 break;
793 case TestType::Depth:
794 getDepthTestTypeFS(fragShader);
795 break;
796 case TestType::Stencil:
797 getStencilTestTypeFS(fragShader);
798 break;
799 default:
800 DE_ASSERT(true);
801 }
802
803 tcu::StringTemplate fragShaderTpl(fragShader.str());
804 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
805 }
806
807 // Copy Image to Buffer using Compute Shader for handling multi sample cases
addCS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const808 void ShaderTileImageTestCase::addCS(SourceCollections& programCollection,
809 const std::map<std::string, std::string>& params) const
810 {
811 std::stringstream compShader;
812
813 const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount);
814 const std::string fsampler = sampleCount > 1 ? "texture2DMS" : "texture2D";
815 const std::string usampler = sampleCount > 1 ? "utexture2DMS" : "utexture2D";
816 const std::string isampler = sampleCount > 1 ? "itexture2DMS" : "itexture2D";
817
818 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat));
819 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
820 const tcu::IVec4 channelBitDepth = tcu::getTextureFormatBitDepth(colorFormat);
821 const bool normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
822
823 std::string sampler;
824 switch (channelClass)
825 {
826 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
827 sampler = usampler;
828 break;
829 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
830 sampler = isampler;
831 break;
832 default:
833 sampler = fsampler;
834 }
835
836 deUint32 amplifier = 1;
837
838 if (normalizedColorFormat)
839 {
840 amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
841 (1 << (channelBitDepth.y() - 1)) : // signed
842 ((1 << channelBitDepth.y()) - 1); // unsigned
843 }
844
845 // Compute shader copies color to linear layout in buffer memory
846 compShader << "#version 450 core\n"
847 << "#extension GL_EXT_samplerless_texture_functions : enable\n"
848 << "precision highp float;\n"
849 << "precision highp int;\n"
850 << "layout(set = 0, binding = 0) uniform " << sampler << " colorTex;\n"
851 << "layout(set = 0, binding = 1, std430) buffer Block0 { uvec2 values[]; } colorbuf;\n"
852 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
853 << "void main()\n"
854 << "{\n"
855 << " for (uint i = 0u; i < " << sampleCount << "u; ++i) {\n"
856 << " uint idx = ((gl_GlobalInvocationID.y * " << m_testParam.frameBufferSize
857 << "u) + gl_GlobalInvocationID.x) * " << sampleCount << "u + i;\n";
858
859 if (normalizedColorFormat)
860 {
861 compShader << " colorbuf.values[idx].y = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), "
862 "int(i)).y * "
863 << amplifier << "));\n";
864 compShader << " colorbuf.values[idx].x = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), "
865 "int(i)).x));\n";
866 }
867 else
868 {
869 compShader << " colorbuf.values[idx] = uvec2(round(vec2(texelFetch(colorTex, "
870 "ivec2(gl_GlobalInvocationID.xy), int(i)).xy)));\n";
871 }
872
873 compShader << " }\n"
874 << "}\n";
875
876 tcu::StringTemplate computeShaderTpl(compShader.str());
877 programCollection.glslSources.add("comp") << glu::ComputeSource(computeShaderTpl.specialize(params));
878 }
879
initPrograms(SourceCollections & programCollection) const880 void ShaderTileImageTestCase::initPrograms(SourceCollections& programCollection) const
881 {
882 std::map<std::string, std::string> params;
883
884 const deUint32 drawCount = getDrawCallCount(&m_testParam);
885 const deUint32 patchCountPerDraw = getPatchesPerDrawCount(m_testParam.multiplePatchesPerDraw);
886 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType);
887 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat));
888 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
889
890 params["VERTEX_COUNT_PER_PATCH"] = std::to_string(getVertexCountPerPatch(&m_testParam));
891 params["PATCH_COUNT_PER_DRAW"] = std::to_string(patchCountPerDraw);
892 params["INV_TOTAL_PATCH_COUNT"] = std::to_string(1.0f / static_cast<float>(drawCount * patchCountPerDraw));
893 params["TOTAL_PATCH_COUNT"] = std::to_string(drawCount * patchCountPerDraw);
894 params["ATTACHMENT_COUNT"] = std::to_string(attachmentCount);
895
896 std::string strVecName;
897 std::string strBasicType;
898 std::string strTileImageType;
899
900 switch (channelClass)
901 {
902 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
903 strVecName = "uvec";
904 strTileImageType = "uattachmentEXT";
905 strBasicType = "uint";
906 break;
907 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
908 strVecName = "ivec";
909 strTileImageType = "iattachmentEXT";
910 strBasicType = "int";
911 break;
912 default:
913 strVecName = "vec";
914 strTileImageType = "attachmentEXT";
915 strBasicType = "float";
916 }
917 params["OUTPUT_VECTOR_NAME"] = strVecName + std::to_string(tcu::getNumUsedChannels(colorFormat.order));
918 params["OUTPUT_BASIC_TYPE"] = strBasicType;
919 params["TILE_IMAGE_TYPE"] = strTileImageType;
920
921 addVS(programCollection, params);
922 addFS(programCollection, params);
923 addCS(programCollection, params);
924 }
925
createInstance(Context & context) const926 TestInstance* ShaderTileImageTestCase::createInstance(Context& context) const
927 {
928 return new ShaderTileImageTestInstance(context, &m_testParam);
929 }
930
checkSupport(Context & context) const931 void ShaderTileImageTestCase::checkSupport(Context& context) const
932 {
933 if (!context.requireDeviceFunctionality("VK_KHR_dynamic_rendering"))
934 {
935 TCU_THROW(NotSupportedError, "VK_KHR_dynamic_rendering not supported");
936 }
937
938 if (!context.requireDeviceFunctionality("VK_EXT_shader_tile_image"))
939 {
940 TCU_THROW(NotSupportedError, "VK_EXT_shader_tile_image not supported");
941 }
942 /* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */
943 VkPhysicalDeviceShaderTileImageFeaturesEXT shaderTileImageFeature = {};
944 shaderTileImageFeature.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT;
945
946 VkPhysicalDeviceFeatures features = {};
947 VkPhysicalDeviceFeatures2 features2 = {};
948 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
949 features2.pNext = &shaderTileImageFeature;
950
951 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
952 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
953
954 if (!shaderTileImageFeature.shaderTileImageColorReadAccess)
955 {
956 TCU_THROW(NotSupportedError, "color read access of VK_EXT_shader_tile_image is not supported");
957 }
958 switch (m_testParam.testType)
959 {
960 case TestType::Depth:
961 case TestType::HelperClassDepth:
962 if (!shaderTileImageFeature.shaderTileImageDepthReadAccess)
963 {
964 TCU_THROW(NotSupportedError, "depth read access of VK_EXT_shader_tile_image is not supported");
965 }
966 break;
967 case TestType::Stencil:
968 case TestType::HelperClassStencil:
969 if (!shaderTileImageFeature.shaderTileImageStencilReadAccess)
970 {
971 TCU_THROW(NotSupportedError, "stencil read access of VK_EXT_shader_tile_image is not supported");
972 }
973 break;
974 case TestType::Color:
975 case TestType::MultiRenderTarget:
976 case TestType::MultiRenderTargetDynamicIndex:
977 case TestType::MsaaSampleMask:
978 case TestType::HelperClassColor:
979 break;
980 default:
981 DE_ASSERT(0);
982 }
983
984 VkPhysicalDeviceVulkan12Properties vulkan12Properties = {};
985 vulkan12Properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
986
987 VkPhysicalDeviceShaderTileImagePropertiesEXT shaderTileImageProperties = {};
988 shaderTileImageProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT;
989 shaderTileImageProperties.pNext = &vulkan12Properties;
990
991 VkPhysicalDeviceProperties2 properties = {};
992 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
993 properties.pNext = &shaderTileImageProperties;
994
995 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
996
997 // shaderTileImageReadSampleFromPixelRateInvocation is a boolean that will be VK_TRUE if reading from samples from a
998 // pixel rate fragment invocation is supported when VkPipelineMultisampleStateCreateInfo::rasterizationSamples > 1.
999 // shaderTileImageReadFromHelperInvocation is a boolean that will be VK_TRUE if reads of tile image data from helper
1000 // fragment invocations result in valid values.
1001 if (!shaderTileImageProperties.shaderTileImageReadSampleFromPixelRateInvocation)
1002 {
1003 if (m_testParam.testType == TestType::MsaaSampleMask)
1004 {
1005 TCU_THROW(NotSupportedError, "multi-samples pixel access of VK_EXT_shader_tile_image is not supported");
1006 }
1007 }
1008
1009 if (!shaderTileImageProperties.shaderTileImageReadFromHelperInvocation)
1010 {
1011 if (isHelperClassTest(m_testParam.testType))
1012 {
1013 TCU_THROW(NotSupportedError, "helper class fragments access of VK_EXT_shader_tile_image is not supported");
1014 }
1015 }
1016
1017 const tcu::TextureFormat colorFormat(mapVkFormat(m_testParam.colorFormat));
1018 const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
1019 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
1020 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1021 {
1022 if ((vulkan12Properties.framebufferIntegerColorSampleCounts & m_testParam.m_sampleCount) == 0 ||
1023 (properties.properties.limits.sampledImageIntegerSampleCounts & m_testParam.m_sampleCount) == 0)
1024 {
1025 TCU_THROW(NotSupportedError, "Sample count not supported");
1026 }
1027 }
1028 else
1029 {
1030 if ((properties.properties.limits.framebufferColorSampleCounts & m_testParam.m_sampleCount) == 0 ||
1031 (properties.properties.limits.sampledImageColorSampleCounts & m_testParam.m_sampleCount) == 0)
1032 {
1033 TCU_THROW(NotSupportedError, "Sample count not supported");
1034 }
1035 }
1036
1037 if (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT && m_testParam.testType != TestType::MsaaSampleMask &&
1038 !features.sampleRateShading)
1039 {
1040 TCU_THROW(NotSupportedError, "sampleRateShading feature not supported");
1041 }
1042
1043 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType);
1044
1045 if (properties.properties.limits.maxFragmentOutputAttachments < attachmentCount ||
1046 properties.properties.limits.maxPerStageDescriptorInputAttachments < attachmentCount)
1047 {
1048 TCU_THROW(NotSupportedError, "attachment number not supported");
1049 }
1050
1051 const InstanceInterface& vki = context.getInstanceInterface();
1052 VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1053 const VkFormatProperties colorFormatProperties(
1054 getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.colorFormat));
1055 const VkFormatProperties dsFormatProperties(
1056 getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.depthStencilFormat));
1057
1058 if ((colorFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
1059 {
1060 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
1061 }
1062
1063 if ((dsFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
1064 {
1065 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
1066 }
1067 }
1068
ShaderTileImageTestInstance(Context & context,const TestParam * testParam)1069 ShaderTileImageTestInstance::ShaderTileImageTestInstance(Context& context, const TestParam* testParam)
1070 : TestInstance(context), m_testParam(testParam), m_vk(m_context.getDeviceInterface())
1071 {
1072 initialize();
1073 }
1074
initialize()1075 void ShaderTileImageTestInstance::initialize()
1076 {
1077 generateCmdBuffer();
1078 generateAttachments();
1079 generateVertexBuffer();
1080 m_graphicsPipeline = generateGraphicsPipeline(false, false, false);
1081 m_graphicsPipelineForHelperClass = generateGraphicsPipeline(true, true, true);
1082 generateComputePipeline();
1083 }
1084
generateComputePipeline()1085 void ShaderTileImageTestInstance::generateComputePipeline()
1086 {
1087 const deUint32 attachmentSize = getColorAttachmentCount(m_testParam->testType);
1088 const VkDevice device = m_context.getDevice();
1089
1090 const Unique<VkShaderModule> cs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("comp"), 0));
1091
1092 VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1093
1094 const VkDescriptorSetLayoutBinding bindings[] = {
1095 {
1096 0, // binding
1097 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1098 1, // descriptorCount
1099 VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
1100 DE_NULL, // pImmutableSamplers
1101 },
1102 {
1103 1, // binding
1104 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1105 1, // descriptorCount
1106 VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
1107 DE_NULL, // pImmutableSamplers
1108 },
1109 };
1110
1111 // Create a layout and allocate a descriptor set for it.
1112 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo = {
1113 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1114 DE_NULL, // pNext
1115 layoutCreateFlags, // flags
1116 sizeof(bindings) / sizeof(bindings[0]), // bindingCount
1117 &bindings[0] // pBindings
1118 };
1119
1120 m_computeDescriptorSetLayout = vk::createDescriptorSetLayout(m_vk, device, &setLayoutCreateInfo);
1121
1122 const VkPipelineShaderStageCreateInfo csShaderCreateInfo = {
1123 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1124 DE_NULL,
1125 (VkPipelineShaderStageCreateFlags)0,
1126 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1127 *cs, // shader
1128 "main",
1129 DE_NULL, // pSpecializationInfo
1130 };
1131
1132 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1133 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1134 DE_NULL, // pNext
1135 (VkPipelineLayoutCreateFlags)0,
1136 1, // setLayoutCount
1137 &m_computeDescriptorSetLayout.get(), // pSetLayouts
1138 0, // pushConstantRangeCount
1139 DE_NULL, // pPushConstantRanges
1140 };
1141
1142 m_computePipelineLayout = createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo, NULL);
1143
1144 const VkComputePipelineCreateInfo pipelineCreateInfo = {
1145 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1146 DE_NULL,
1147 0u, // flags
1148 csShaderCreateInfo, // cs
1149 *m_computePipelineLayout, // layout
1150 (vk::VkPipeline)0, // basePipelineHandle
1151 0u, // basePipelineIndex
1152 };
1153
1154 m_computePipeline = createComputePipeline(m_vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1155
1156 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1157
1158 vk::DescriptorPoolBuilder poolBuilder;
1159 for (deUint32 i = 0; i < (deInt32)(sizeof(bindings) / sizeof(bindings[0])); ++i)
1160 {
1161 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount * attachmentSize);
1162 }
1163 m_descriptorPool = poolBuilder.build(m_vk, device, poolCreateFlags, attachmentSize);
1164
1165 for (deUint32 i = 0; i < attachmentSize; ++i)
1166 {
1167 m_descriptorSets[i] = makeDescriptorSet(m_vk, device, *m_descriptorPool, *m_computeDescriptorSetLayout);
1168 VkDescriptorImageInfo imageInfo;
1169 VkDescriptorBufferInfo bufferInfo;
1170
1171 VkWriteDescriptorSet w = {
1172 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1173 DE_NULL, // pNext
1174 *m_descriptorSets[i], // dstSet
1175 (deUint32)0, // dstBinding
1176 0, // dstArrayElement
1177 1u, // descriptorCount
1178 bindings[0].descriptorType, // descriptorType
1179 &imageInfo, // pImageInfo
1180 &bufferInfo, // pBufferInfo
1181 DE_NULL, // pTexelBufferView
1182 };
1183
1184 imageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageColorView[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1185 w.dstBinding = 0;
1186 w.descriptorType = bindings[0].descriptorType;
1187 m_vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1188
1189 bufferInfo = makeDescriptorBufferInfo(m_imageBuffer[i]->object(), 0, VK_WHOLE_SIZE);
1190 w.dstBinding = 1;
1191 w.descriptorType = bindings[1].descriptorType;
1192 m_vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1193 }
1194 }
1195
generateGraphicsPipeline(bool disableColor0Write,bool disableDepthWrite,bool disableStencilWrite)1196 Move<VkPipeline> ShaderTileImageTestInstance::generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite,
1197 bool disableStencilWrite)
1198 {
1199 const VkDevice device = m_context.getDevice();
1200
1201 VkPushConstantRange pushConstant;
1202 pushConstant.offset = 0;
1203 pushConstant.size = sizeof(deUint32);
1204 pushConstant.stageFlags = (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
1205
1206 m_graphicsPipelineLayout = makePipelineLayout(m_vk, device, 0, nullptr, 1, &pushConstant);
1207 m_vertexModule = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("vert"), 0u);
1208 m_fragmentModule = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("frag"), 0u);
1209
1210 const VkVertexInputBindingDescription vertexInputBindingDescription = {
1211 0, // deUint32 binding;
1212 sizeof(tcu::Vec2), // deUint32 strideInBytes;
1213 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputStepRate stepRate;
1214 };
1215
1216 const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
1217 0u, // deUint32 location;
1218 0u, // deUint32 binding;
1219 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1220 0u, // deUint32 offsetInBytes;
1221 };
1222
1223 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1224 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1225 DE_NULL, // const void* pNext;
1226 0, // VkPipelineVertexInputStateCreateFlags flags;
1227 1u, // deUint32 bindingCount;
1228 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1229 1u, // deUint32 attributeCount;
1230 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1231 };
1232
1233 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
1234 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1235 DE_NULL, // const void* pNext;
1236 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1237 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1238 VK_FALSE, // VkBool32 primitiveRestartEnable;
1239 };
1240
1241 const VkViewport viewport{
1242 0, 0, static_cast<float>(m_testParam->frameBufferSize), static_cast<float>(m_testParam->frameBufferSize), 0, 1
1243 };
1244 const VkRect2D scissor{ { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } };
1245
1246 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = {
1247 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1248 DE_NULL, // const void* pNext;
1249 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
1250 1u, // uint32_t viewportCount;
1251 &viewport, // const VkViewport* pViewports;
1252 1u, // uint32_t scissorCount;
1253 &scissor, // const VkRect2D* pScissors;
1254 };
1255
1256 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = {
1257 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1258 DE_NULL, // const void* pNext;
1259 0u, // VkPipelineRasterizationStateCreateFlags flags;
1260 VK_FALSE, // VkBool32 depthClampEnable;
1261 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1262 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1263 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1264 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1265 VK_FALSE, // VkBool32 depthBiasEnable;
1266 0.0f, // float depthBiasConstantFactor;
1267 0.0f, // float depthBiasClamp;
1268 0.0f, // float depthBiasSlopeFactor;
1269 1.0f, // float lineWidth;
1270 };
1271
1272 const VkSampleMask sampleMask = getSampleMask(m_testParam->testType);
1273 const VkSampleMask* pSampleMask = (m_testParam->testType == TestType::MsaaSampleMask) ? &sampleMask : DE_NULL;
1274 const bool sampleShadingEnable = (m_testParam->testType != TestType::MsaaSampleMask);
1275
1276 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = {
1277 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1278 DE_NULL, // const void* pNext;
1279 0u, // VkPipelineMultisampleStateCreateFlags flags;
1280 m_testParam->m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1281 sampleShadingEnable, // VkBool32 sampleShadingEnable;
1282 1.0f, // float minSampleShading;
1283 pSampleMask, // const VkSampleMask* pSampleMask;
1284 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1285 VK_FALSE // VkBool32 alphaToOneEnable;
1286 };
1287
1288 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1289 getColorAttachmentCount(m_testParam->testType),
1290 {
1291 false, // VkBool32 blendEnable;
1292 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1293 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1294 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1295 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1296 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1297 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1298 (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT) // VkChannelFlags channelWriteMask;
1299 });
1300
1301 if (disableColor0Write)
1302 {
1303 colorBlendAttachmentState[0].colorWriteMask = 0;
1304 }
1305
1306 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = {
1307 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1308 DE_NULL, // const void* pNext;
1309 /* always needed */
1310 0, // VkPipelineColorBlendStateCreateFlags flags;
1311 false, // VkBool32 logicOpEnable;
1312 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1313 (deUint32)colorBlendAttachmentState.size(), // deUint32 attachmentCount;
1314 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
1315 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1316 };
1317
1318 VkStencilOpState stencilOpState = {
1319 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
1320 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp passOp;
1321 VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp depthFailOp;
1322 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1323 0xff, // uint32_t compareMask;
1324 0xff, // uint32_t writeMask;
1325 0, // uint32_t reference;
1326 };
1327
1328 if (disableStencilWrite)
1329 {
1330 stencilOpState.failOp = VK_STENCIL_OP_KEEP;
1331 stencilOpState.passOp = VK_STENCIL_OP_KEEP;
1332 stencilOpState.depthFailOp = VK_STENCIL_OP_KEEP;
1333 }
1334
1335 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = {
1336 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1337 // VkStructureType sType;
1338 DE_NULL, // const void* pNext;
1339 0,
1340 // VkPipelineDepthStencilStateCreateFlags flags;
1341 VK_TRUE, // VkBool32 depthTestEnable;
1342 VK_TRUE, // VkBool32 depthWriteEnable;
1343 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1344 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1345 VK_TRUE, // VkBool32 stencilTestEnable;
1346 stencilOpState, // VkStencilOpState front;
1347 stencilOpState, // VkStencilOpState back;
1348 0.0f, // float minDepthBounds;
1349 1.0f, // float maxDepthBounds;
1350 };
1351
1352 if (disableDepthWrite)
1353 {
1354 pipelineDepthStencilStateInfo.depthWriteEnable = VK_FALSE;
1355 }
1356
1357 std::vector<VkFormat> colorsAttachmentFormats(getColorAttachmentCount(m_testParam->testType),
1358 m_testParam->colorFormat);
1359 const tcu::TextureFormat depthStencilTexFormat = mapVkFormat(m_testParam->depthStencilFormat);
1360 VkFormat depthFormat = tcu::hasDepthComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED;
1361 VkFormat stencilFormat = tcu::hasStencilComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED;
1362 const VkPipelineRenderingCreateInfoKHR renderingCreateInfo{
1363 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, // VkStructureType sType;
1364 DE_NULL, // const void* pNext;
1365 0u, // deUint32 viewMask;
1366 static_cast<deUint32>(colorsAttachmentFormats.size()), // deUint32 colorAttachmentCount;
1367 colorsAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats;
1368 depthFormat, // VkFormat depthAttachmentFormat;
1369 stencilFormat, // VkFormat stencilAttachmentFormat;
1370 };
1371
1372 const VkPipelineShaderStageCreateInfo pShaderStages[] = {
1373 {
1374 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1375 DE_NULL, // const void* pNext;
1376 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1377 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1378 *m_vertexModule, // VkShaderModule module;
1379 "main", // const char* pName;
1380 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1381 },
1382 {
1383 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1384 DE_NULL, // const void* pNext;
1385 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1386 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1387 *m_fragmentModule, // VkShaderModule module;
1388 "main", // const char* pName;
1389 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1390 },
1391 };
1392
1393 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = {
1394 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1395 &renderingCreateInfo, // const void* pNext;
1396 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1397 2u, // deUint32 stageCount;
1398 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
1399 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1400 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1401 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1402 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
1403 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1404 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1405 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1406 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1407 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1408 *m_graphicsPipelineLayout, // VkPipelineLayout layout;
1409 DE_NULL, // VkRenderPass renderPass;
1410 0u, // deUint32 subpass;
1411 DE_NULL, // VkPipeline basePipelineHandle;
1412 0, // deInt32 basePipelineIndex;
1413 };
1414
1415 return createGraphicsPipeline(m_vk, device, DE_NULL, &graphicsPipelineInfo);
1416 }
1417
generateAttachments()1418 void ShaderTileImageTestInstance::generateAttachments()
1419 {
1420 const VkDevice device = m_context.getDevice();
1421 Allocator& allocator = m_context.getDefaultAllocator();
1422
1423 auto makeImageCreateInfo = [](const VkFormat format, deUint32 imageSize, VkSampleCountFlagBits sampleCount,
1424 VkImageUsageFlags usage) -> VkImageCreateInfo
1425 {
1426 const VkImageCreateInfo imageParams = {
1427 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1428 DE_NULL, // const void* pNext;
1429 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
1430 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1431 format, // VkFormat format;
1432 makeExtent3D(imageSize, imageSize, 1), // VkExtent3D extent;
1433 1u, // deUint32 mipLevels;
1434 1u, // deUint32 arrayLayers;
1435 sampleCount, // VkSampleCountFlagBits samples;
1436 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1437 usage, // VkImageUsageFlags usage;
1438 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1439 0u, // deUint32 queueFamilyIndexCount;
1440 DE_NULL, // const deUint32* pQueueFamilyIndices;
1441 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1442 };
1443 return imageParams;
1444 };
1445
1446 // Color Attachment
1447 {
1448 constexpr deUint32 imageBufferPixelSize = sizeof(deUint32) * 2; // always uvec2 type
1449 const VkImageUsageFlags imageUsage =
1450 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1451 const VkDeviceSize imageBufferSize = m_testParam->frameBufferSize * m_testParam->frameBufferSize *
1452 imageBufferPixelSize * getSampleCount(m_testParam->m_sampleCount);
1453 const VkImageSubresourceRange imageSubresource =
1454 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1455 const VkImageCreateInfo imageInfo = makeImageCreateInfo(m_testParam->colorFormat, m_testParam->frameBufferSize,
1456 m_testParam->m_sampleCount, imageUsage);
1457 const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(
1458 imageBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1459
1460 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam->testType);
1461 for (deUint32 i = 0; i < attachmentCount; ++i)
1462 {
1463 m_imageColor[i] = makeImage(m_vk, device, imageInfo);
1464 m_imageColorAlloc[i] = bindImage(m_vk, device, allocator, *m_imageColor[i], MemoryRequirement::Any);
1465 m_imageBuffer[i] =
1466 Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible);
1467 m_imageColorView[i] = makeImageView(m_vk, device, *m_imageColor[i], VK_IMAGE_VIEW_TYPE_2D,
1468 m_testParam->colorFormat, imageSubresource);
1469 }
1470
1471 m_imageColorBufferHostPtr = static_cast<deUint32*>(m_imageBuffer[0]->getHostPtr());
1472 }
1473
1474 // depth/stencil attachment.
1475 {
1476 const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat);
1477 const VkImageUsageFlags imageUsage =
1478 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1479
1480 VkImageAspectFlags aspect = 0;
1481 if (tcu::hasDepthComponent(depthStencilFormat.order))
1482 {
1483 aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
1484 }
1485 if (tcu::hasStencilComponent(depthStencilFormat.order))
1486 {
1487 aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
1488 }
1489
1490 const VkImageCreateInfo imageInfo = makeImageCreateInfo(
1491 m_testParam->depthStencilFormat, m_testParam->frameBufferSize, m_testParam->m_sampleCount, imageUsage);
1492
1493 const VkImageSubresourceRange imageSubresource = makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u);
1494
1495 m_imageDepthStencil = makeImage(m_vk, device, imageInfo);
1496 m_imageDepthStencilAlloc = bindImage(m_vk, device, allocator, *m_imageDepthStencil, MemoryRequirement::Any);
1497 m_imageDepthStencilView = makeImageView(m_vk, device, *m_imageDepthStencil, VK_IMAGE_VIEW_TYPE_2D,
1498 m_testParam->depthStencilFormat, imageSubresource);
1499 }
1500 }
1501
generateVertexBuffer()1502 void ShaderTileImageTestInstance::generateVertexBuffer()
1503 {
1504 const deUint32 drawCount = getDrawCallCount(m_testParam);
1505 const deUint32 patchCountPerDraw = getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1506 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1507 const VkDevice device = m_context.getDevice();
1508 Allocator& allocator = m_context.getDefaultAllocator();
1509 std::vector<tcu::Vec2> vbo;
1510 for (deUint32 patchIndex = 0; patchIndex < (patchCountPerDraw * drawCount); patchIndex++)
1511 {
1512 // _____
1513 // | /
1514 // | /
1515 // |/
1516 vbo.emplace_back(tcu::Vec2(-1, -1));
1517 vbo.emplace_back(tcu::Vec2(1, 1));
1518 vbo.emplace_back(tcu::Vec2(-1, 1));
1519
1520 if (getVertexCountPerPatch(m_testParam) == 6)
1521 {
1522 if (isHelperClassTest(m_testParam->testType) && patchIndex == 0)
1523 {
1524 // helper class cases render the first patch like follow.
1525 // _____
1526 // | /
1527 // | /
1528 // |/
1529 // So, 3 of second triangle is dummy.
1530 vbo.emplace_back(tcu::Vec2(-1, -1));
1531 vbo.emplace_back(tcu::Vec2(-1, -1));
1532 vbo.emplace_back(tcu::Vec2(-1, -1));
1533 }
1534 else
1535 {
1536 // Other 6 vertices cases render like follow
1537 // _____
1538 // | /|
1539 // | / |
1540 // |/__|
1541 vbo.emplace_back(tcu::Vec2(-1, -1));
1542 vbo.emplace_back(tcu::Vec2(1, -1));
1543 vbo.emplace_back(tcu::Vec2(1, 1));
1544 }
1545 }
1546 }
1547
1548 const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1549 {
1550 const VkBufferCreateInfo bufferInfo = {
1551 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1552 DE_NULL, // const void* pNext;
1553 0u, // VkBufferCreateFlags flags;
1554 dataSize, // VkDeviceSize size;
1555 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1556 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1557 1u, // deUint32 queueFamilyCount;
1558 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1559 };
1560 m_vertexBuffer =
1561 Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible);
1562 }
1563
1564 /* Load vertices into vertex buffer */
1565 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), vbo.data(), dataSize);
1566 flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
1567 }
generateCmdBuffer()1568 void ShaderTileImageTestInstance::generateCmdBuffer()
1569 {
1570 const VkDevice device = m_context.getDevice();
1571
1572 m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
1573 m_context.getUniversalQueueFamilyIndex());
1574 m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1575 }
1576
iterate()1577 tcu::TestStatus ShaderTileImageTestInstance::iterate()
1578 {
1579 rendering();
1580 return checkResult();
1581 }
1582
getResultValue(deUint32 fx,deUint32 fy,deUint32 fs,deUint32 renderTargetID) const1583 deUint32 ShaderTileImageTestInstance::getResultValue(deUint32 fx, deUint32 fy, deUint32 fs,
1584 deUint32 renderTargetID) const
1585 {
1586 const deUint32* resultData =
1587 static_cast<const deUint32*>(m_imageBuffer[renderTargetID]->getBoundMemory().getHostPtr());
1588 const deUint32 sampleCount = getSampleCount(m_testParam->m_sampleCount);
1589 const deUint32 index = (((fy * m_testParam->frameBufferSize) + fx) * sampleCount + fs) * 2; // 2 is for xy
1590 if (resultData[index] != 0) // error
1591 {
1592 return 0xFFFFFFFF;
1593 }
1594
1595 return resultData[index + 1]; // y value
1596 }
1597
simulate(deUint32 fx,deUint32 fy,deUint32 fs,deUint32 renderTargetID) const1598 deUint32 ShaderTileImageTestInstance::simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const
1599 {
1600 const deUint32 totalLayerCount =
1601 getDrawCallCount(m_testParam) * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1602
1603 if (m_testParam->testType == TestType::MsaaSampleMask)
1604 {
1605 deUint32 expectedValue = 0;
1606
1607 if (((getSampleMask(m_testParam->testType) >> fs) & 0x1) == 0x1)
1608 {
1609 expectedValue = totalLayerCount + renderTargetID;
1610 }
1611 return expectedValue;
1612 }
1613 if (m_testParam->testType == TestType::Stencil)
1614 {
1615 // stencil test doesn't add fragment sample ID to the output;
1616 const deUint32 expectedValue = totalLayerCount + renderTargetID;
1617 return expectedValue;
1618 }
1619 if (isHelperClassTest(m_testParam->testType))
1620 {
1621 // ________ ________ ________
1622 // 1|1|1|0| 0|0|*|1| 1|1|#|2|
1623 // 1|1|0|0| 0|0|1|*| 1|1|2|#|
1624 // 1|0|0|0| => *|1|0|0| => #|2|1|1|
1625 // 0|0|0|0| 1|*|0|0| 2|#|1|1|
1626 // ________ ________ ________
1627 // raster max(dx,dy) result(+1)
1628 // *(#): max(dx, dy) could be 0(1) or 1(2).
1629 if ((fx) == (fy))
1630 {
1631 return kDerivative1; // derivative is 1 because of coverage. (+1) for differentiate clear value
1632 }
1633 else
1634 {
1635 return kDerivative0; // 0, fill all or fill none for quad. (+1) for differentiate clear value
1636 }
1637 }
1638 else
1639 {
1640 const deUint32 expectedValue = totalLayerCount + renderTargetID + fs;
1641 return expectedValue;
1642 }
1643 }
1644
checkResult() const1645 tcu::TestStatus ShaderTileImageTestInstance::checkResult() const
1646 {
1647 const VkDevice device = m_context.getDevice();
1648
1649 qpTestResult res = QP_TEST_RESULT_PASS;
1650 const deUint32 sampleCount = getSampleCount(m_testParam->m_sampleCount);
1651 const deUint32 attachmentCount = getColorAttachmentCount(m_testParam->testType);
1652 const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam);
1653 // Loop over all samples in the same fragment
1654
1655 for (deUint32 rt = 0; (res == QP_TEST_RESULT_PASS) && rt < attachmentCount; rt++)
1656 {
1657 // Result of Helper Class test valid only for the rt 1
1658 invalidateAlloc(m_vk, device, m_imageBuffer[rt]->getBoundMemory());
1659
1660 if (rt != 1 && isHelperClassTest(m_testParam->testType))
1661 {
1662 continue;
1663 }
1664
1665 for (deUint32 fy = 0; (res == QP_TEST_RESULT_PASS) && fy < m_testParam->frameBufferSize; ++fy)
1666 {
1667 for (deUint32 fx = 0; (res == QP_TEST_RESULT_PASS) && fx < m_testParam->frameBufferSize; ++fx)
1668 {
1669 for (deUint32 fs = 0; (res == QP_TEST_RESULT_PASS) && fs < sampleCount; ++fs)
1670 {
1671 const deUint32 expectedValue = simulate(fx, fy, fs, rt);
1672 const deUint32 resultValue = getResultValue(fx, fy, fs, rt);
1673
1674 if (isHelperClassTest(m_testParam->testType))
1675 {
1676 // ________ ________ ________
1677 // 1|1|1|0| 0|0|*|1| 1|1|#|2|
1678 // 1|1|0|0| 0|0|1|*| 1|1|2|#|
1679 // 1|0|0|0| => *|1|0|0| => #|2|1|1|
1680 // 0|0|0|0| 1|*|0|0| 2|#|1|1|
1681 // ________ ________ ________
1682 // raster max(dx,dy) result(+1)
1683 // *(#): max(dx, dy) could be 0(1) or 1(2).
1684 if (expectedValue != resultValue)
1685 {
1686 if (std::abs(static_cast<deInt32>(fx - fy)) != 1 || resultValue != kDerivative1)
1687 {
1688 res = QP_TEST_RESULT_FAIL;
1689 break;
1690 }
1691 }
1692 }
1693 else if (vertexCountPerPatch == 6) // Fill full quad to the framebuffer
1694 {
1695 if (expectedValue != resultValue)
1696 {
1697 res = QP_TEST_RESULT_FAIL;
1698 break;
1699 }
1700 }
1701 else // Fill a triangle to the framebuffer, check half of framebuffer
1702 {
1703 if (fy > fx) // inside of triangle
1704 {
1705 if (expectedValue != resultValue) // not expected value
1706 {
1707 res = QP_TEST_RESULT_FAIL;
1708 break;
1709 }
1710 }
1711 else // outside of filling triangle or triangle edge
1712 {
1713 if (resultValue != 0 && resultValue != expectedValue) // can be not filling
1714 {
1715 res = QP_TEST_RESULT_FAIL;
1716 break;
1717 }
1718 }
1719 }
1720 }
1721 }
1722 }
1723 }
1724
1725 return tcu::TestStatus(res, qpGetTestResultName(res));
1726 }
1727
rendering()1728 void ShaderTileImageTestInstance::rendering()
1729 {
1730 const VkDevice device = m_context.getDevice();
1731 const VkQueue queue = m_context.getUniversalQueue();
1732
1733 beginCommandBuffer(m_vk, *m_cmdBuffer);
1734
1735 // begin render pass
1736 const VkClearValue clearValue = {}; // { 0, 0, 0, 0 }
1737 const VkClearValue dsClearValue = {}; // .depth = 0.0f, .stencil = 0
1738 const VkRect2D renderArea = { { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } };
1739
1740 const deUint32 colorAttachmentCount = getColorAttachmentCount(m_testParam->testType);
1741
1742 std::vector<VkRenderingAttachmentInfoKHR> colorAttachments;
1743 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1744 {
1745 const VkRenderingAttachmentInfoKHR renderingAtachInfo = {
1746 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1747 DE_NULL, // const void* pNext;
1748 *m_imageColorView[colorIndex], // VkImageView imageView;
1749 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
1750 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
1751 DE_NULL, // VkImageView resolveImageView;
1752 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
1753 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1754 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1755 clearValue, // VkClearValue clearValue;
1756 };
1757
1758 colorAttachments.push_back(renderingAtachInfo);
1759 }
1760
1761 const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat);
1762 const bool hasDepth = tcu::hasDepthComponent(depthStencilFormat.order);
1763 const bool hasStencil = tcu::hasStencilComponent(depthStencilFormat.order);
1764 VkImageLayout depthStencilLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1765 VkImageAspectFlags depthStencilAspect = 0;
1766 if (hasDepth && hasStencil)
1767 {
1768 depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1769 depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1770 }
1771 else if (hasDepth)
1772 {
1773 depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1774 depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
1775 }
1776 else if (hasStencil)
1777 {
1778 depthStencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1779 depthStencilAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
1780 }
1781
1782 const VkRenderingAttachmentInfoKHR depthStencilAttachment = {
1783 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1784 DE_NULL, // const void* pNext;
1785 *m_imageDepthStencilView, // VkImageView imageView;
1786 depthStencilLayout, // VkImageLayout imageLayout;
1787 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
1788 DE_NULL, // VkImageView resolveImageView;
1789 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
1790 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1791 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1792 dsClearValue, // VkClearValue clearValue;
1793 };
1794
1795 const VkRenderingInfoKHR renderingInfo = {
1796 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, // VkStructureType sType;
1797 DE_NULL, // const void* pNext;
1798 0, // VkRenderingFlagsKHR flags;
1799 renderArea, // VkRect2D renderArea;
1800 1u, // deUint32 layerCount;
1801 0u, // deUint32 viewMask;
1802 static_cast<deUint32>(colorAttachments.size()), // deUint32 colorAttachmentCount;
1803 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
1804 hasDepth ? &depthStencilAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
1805 hasStencil ? &depthStencilAttachment : DE_NULL // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
1806 };
1807
1808 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1809 {
1810 transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT,
1811 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0,
1812 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1813 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1814 }
1815
1816 transition2DImage(m_vk, *m_cmdBuffer, *m_imageDepthStencil, depthStencilAspect, VK_IMAGE_LAYOUT_UNDEFINED,
1817 depthStencilLayout, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1818 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1819 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1820
1821 m_vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1822
1823 // vertex input setup
1824 const VkBuffer vertexBuffer = m_vertexBuffer->object();
1825
1826 for (deUint32 drawIndex = 0; drawIndex < getDrawCallCount(m_testParam); drawIndex++)
1827 {
1828 // pipeline setup
1829 if (drawIndex == 1 && isHelperClassTest(m_testParam->testType))
1830 {
1831 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineForHelperClass);
1832 }
1833 else
1834 {
1835 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1836 }
1837
1838 const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam);
1839 const deUint32 vertexCount = vertexCountPerPatch * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1840 m_vk.cmdPushConstants(*m_cmdBuffer, *m_graphicsPipelineLayout,
1841 (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), 0, sizeof(deUint32),
1842 &drawIndex);
1843
1844 const VkDeviceSize vertexBufferOffset = (vertexCount * drawIndex) * sizeof(tcu::Vec2);
1845 m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1846
1847 if (!m_testParam->coherent)
1848 {
1849 VkMemoryBarrier2KHR memoryBarrierForColor = {
1850 VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, // sType
1851 DE_NULL, // pNext
1852 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// srcStageMask
1853 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR, // srcAccessMask
1854 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// dstStageMask
1855 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR // dstAccessMask
1856 };
1857
1858 VkMemoryBarrier2KHR memoryBarrierForDepthStencil = {
1859 VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR, // sType
1860 DE_NULL, // pNext
1861 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
1862 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, // srcStageMask
1863 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR, // srcAccessMask
1864 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
1865 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT , // dstStageMask
1866 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR // dstAccessMask
1867 };
1868
1869 VkMemoryBarrier2KHR* memoryBarrier =
1870 (m_testParam->testType == TestType::Depth) || (m_testParam->testType == TestType::Stencil) ?
1871 &memoryBarrierForDepthStencil :
1872 &memoryBarrierForColor;
1873
1874 VkDependencyInfoKHR dependencyInfo{
1875 VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // sType
1876 DE_NULL, // pNext
1877 VK_DEPENDENCY_BY_REGION_BIT, //dependency flags
1878 1, //memory barrier count
1879 memoryBarrier, //memory barrier
1880 0, // bufferMemoryBarrierCount
1881 DE_NULL, // pBufferMemoryBarriers
1882 0, // imageMemoryBarrierCount
1883 DE_NULL, // pImageMemoryBarriers
1884 };
1885 m_vk.cmdPipelineBarrier2(*m_cmdBuffer, &dependencyInfo);
1886 }
1887
1888 m_vk.cmdDraw(*m_cmdBuffer, vertexCount, 1, 0, 0u);
1889 }
1890 m_vk.cmdEndRendering(*m_cmdBuffer);
1891
1892 for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1893 {
1894
1895 transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT,
1896 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1897 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1898 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1899 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
1900 }
1901
1902 VkMemoryBarrier memBarrier = {
1903 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
1904 DE_NULL, // pNext
1905 0u, // srcAccessMask
1906 0u, // dstAccessMask
1907 };
1908 memBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1909 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
1910 m_vk.cmdPipelineBarrier(*m_cmdBuffer,
1911 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1912 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1913
1914 m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
1915
1916 // Copy color images to buffer memory
1917 for (deUint32 attachmentIndex = 0; attachmentIndex < colorAttachmentCount; attachmentIndex++)
1918 {
1919 m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelineLayout, 0u, 1,
1920 &*m_descriptorSets[attachmentIndex], 0u, DE_NULL);
1921
1922 m_vk.cmdDispatch(*m_cmdBuffer, m_testParam->frameBufferSize, m_testParam->frameBufferSize, 1);
1923 }
1924 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1925 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
1926 m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1,
1927 &memBarrier, 0, DE_NULL, 0, DE_NULL);
1928
1929 VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer));
1930
1931 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1932 }
1933
formatToName(VkFormat format)1934 std::string formatToName(VkFormat format)
1935 {
1936 const std::string formatStr = de::toString(format);
1937 const std::string prefix = "VK_FORMAT_";
1938
1939 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1940
1941 return de::toLower(formatStr.substr(prefix.length()));
1942 }
1943
createShaderTileImageTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr)1944 void createShaderTileImageTestVariations(tcu::TestContext& testCtx, tcu::TestCaseGroup* gr)
1945 {
1946 struct TestTypeParam
1947 {
1948 TestType value;
1949 const char* name;
1950 };
1951
1952 struct BoolParam
1953 {
1954 bool value;
1955 const char* name;
1956 };
1957
1958 struct VkSampleCountFlagParam
1959 {
1960 VkSampleCountFlagBits value;
1961 const char* name;
1962 };
1963
1964 const std::vector<BoolParam> coherentParams = { { true, "coherent" }, { false, "non_coherent" } };
1965
1966 const std::vector<TestTypeParam> testTypeParams = {
1967 { TestType::Color, "color" },
1968 { TestType::MultiRenderTarget, "mrt" },
1969 { TestType::MultiRenderTargetDynamicIndex, "mrt_dynamic_index" },
1970 { TestType::MsaaSampleMask, "msaa_sample_mask" },
1971 { TestType::HelperClassColor, "helper_class_color" },
1972 { TestType::HelperClassDepth, "helper_class_depth" },
1973 { TestType::HelperClassStencil, "helper_class_stencil" },
1974 { TestType::Depth, "depth" },
1975 { TestType::Stencil, "stencil" },
1976 };
1977
1978 const std::vector<VkSampleCountFlagParam> sampleCountParams = {
1979 { VK_SAMPLE_COUNT_1_BIT, "samples_1" }, { VK_SAMPLE_COUNT_2_BIT, "samples_2" },
1980 { VK_SAMPLE_COUNT_4_BIT, "samples_4" }, { VK_SAMPLE_COUNT_8_BIT, "samples_8" },
1981 { VK_SAMPLE_COUNT_16_BIT, "samples_16" }, { VK_SAMPLE_COUNT_32_BIT, "samples_32" },
1982 };
1983
1984 const std::vector<BoolParam> multiDrawsParams = { { false, "single_draw" }, { true, "multi_draws" } };
1985
1986 const std::vector<BoolParam> multiPatchParams = { { false, "single_patch" }, { true, "multi_patches" } };
1987
1988 const std::vector<VkFormat> formats = { VK_FORMAT_R5G6B5_UNORM_PACK16,
1989 VK_FORMAT_R8G8_UNORM,
1990 VK_FORMAT_R8G8_SNORM,
1991 VK_FORMAT_R8G8_UINT,
1992 VK_FORMAT_R8G8_SINT,
1993 VK_FORMAT_R8G8B8A8_UNORM,
1994 VK_FORMAT_R8G8B8A8_SNORM,
1995 VK_FORMAT_R8G8B8A8_UINT,
1996 VK_FORMAT_R8G8B8A8_SINT,
1997 VK_FORMAT_R8G8B8A8_SRGB,
1998 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1999 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2000 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2001 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2002 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2003 VK_FORMAT_B8G8R8A8_UNORM,
2004 VK_FORMAT_B8G8R8A8_SRGB,
2005 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2006 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2007 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2008 VK_FORMAT_R16G16_UNORM,
2009 VK_FORMAT_R16G16_SNORM,
2010 VK_FORMAT_R16G16_UINT,
2011 VK_FORMAT_R16G16_SINT,
2012 VK_FORMAT_R16G16_SFLOAT,
2013 VK_FORMAT_R16G16B16A16_UNORM,
2014 VK_FORMAT_R16G16B16A16_SNORM,
2015 VK_FORMAT_R16G16B16A16_UINT,
2016 VK_FORMAT_R16G16B16A16_SINT,
2017 VK_FORMAT_R16G16B16A16_SFLOAT,
2018 VK_FORMAT_R32G32_UINT,
2019 VK_FORMAT_R32G32_SINT,
2020 VK_FORMAT_R32G32_SFLOAT,
2021 VK_FORMAT_R32G32B32A32_UINT,
2022 VK_FORMAT_R32G32B32A32_SINT,
2023 VK_FORMAT_R32G32B32A32_SFLOAT,
2024 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2025
2026 VK_FORMAT_D16_UNORM,
2027 VK_FORMAT_X8_D24_UNORM_PACK32,
2028 VK_FORMAT_D32_SFLOAT,
2029 VK_FORMAT_S8_UINT,
2030 VK_FORMAT_D16_UNORM_S8_UINT,
2031 VK_FORMAT_D24_UNORM_S8_UINT,
2032 VK_FORMAT_D32_SFLOAT_S8_UINT };
2033
2034 tcu::TestCaseGroup* subGroup = nullptr;
2035 std::vector<tcu::TestCaseGroup*> testGroupStack;
2036 testGroupStack.push_back(gr);
2037
2038 for (const BoolParam& coherentParam : coherentParams)
2039 {
2040 subGroup = (new tcu::TestCaseGroup(testCtx, coherentParam.name));
2041 testGroupStack.back()->addChild(subGroup);
2042 testGroupStack.push_back(subGroup);
2043 for (const TestTypeParam& testTypeParam : testTypeParams)
2044 {
2045 subGroup = new tcu::TestCaseGroup(testCtx, testTypeParam.name);
2046 testGroupStack.back()->addChild(subGroup);
2047 testGroupStack.push_back(subGroup);
2048
2049 for (const VkSampleCountFlagParam& sampleCountParam : sampleCountParams)
2050 {
2051 if (testTypeParam.value == TestType::MsaaSampleMask && sampleCountParam.value == VK_SAMPLE_COUNT_1_BIT)
2052 {
2053 // SampleMask test requires MSAA
2054 continue;
2055 }
2056 if (isHelperClassTest(testTypeParam.value) && sampleCountParam.value != VK_SAMPLE_COUNT_1_BIT)
2057 {
2058 // HelperClass test designed for non msaa case
2059 continue;
2060 }
2061 subGroup = new tcu::TestCaseGroup(testCtx, sampleCountParam.name);
2062 testGroupStack.back()->addChild(subGroup);
2063 testGroupStack.push_back(subGroup);
2064
2065 for (const BoolParam& multiDrawsParam : multiDrawsParams)
2066 {
2067 if (isHelperClassTest(testTypeParam.value) && multiDrawsParam.value)
2068 {
2069 // helper class 2 draws but works like single draw call
2070 continue;
2071 }
2072
2073 subGroup = new tcu::TestCaseGroup(testCtx, multiDrawsParam.name);
2074 testGroupStack.back()->addChild(subGroup);
2075 testGroupStack.push_back(subGroup);
2076
2077 for (const BoolParam& multiPatchParam : multiPatchParams)
2078 {
2079 if (!coherentParam.value && multiPatchParam.value) // cannot guarantee
2080 {
2081 continue;
2082 }
2083 if (isHelperClassTest(testTypeParam.value) && multiPatchParam.value)
2084 {
2085 // helper class works on single patch cases
2086 continue;
2087 }
2088
2089 subGroup = new tcu::TestCaseGroup(testCtx, multiPatchParam.name);
2090 testGroupStack.back()->addChild(subGroup);
2091 testGroupStack.push_back(subGroup);
2092
2093 for (VkFormat format : formats)
2094 {
2095 tcu::TestCaseGroup* curGroup = testGroupStack.back();
2096 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(format).order);
2097 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(format).order);
2098 std::string name = formatToName(format);
2099
2100 TestParam testParam = {};
2101 testParam.coherent = coherentParam.value;
2102 testParam.testType = testTypeParam.value;
2103 testParam.colorFormat = VK_FORMAT_R32G32B32A32_UINT;
2104 testParam.depthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
2105 testParam.m_sampleCount = sampleCountParam.value;
2106 testParam.multipleDrawCalls = multiDrawsParam.value;
2107 testParam.multiplePatchesPerDraw = multiPatchParam.value;
2108 testParam.frameBufferSize = kImageSize;
2109 if (testTypeParam.value == TestType::Depth ||
2110 testTypeParam.value == TestType::HelperClassDepth)
2111 {
2112 if (hasDepth)
2113 {
2114 testParam.depthStencilFormat = format;
2115 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2116 }
2117 }
2118 else if (testTypeParam.value == TestType::Stencil ||
2119 testTypeParam.value == TestType::HelperClassStencil)
2120 {
2121 if (hasStencil)
2122 {
2123 testParam.depthStencilFormat = format;
2124 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2125 }
2126 }
2127 else
2128 {
2129 if (!hasStencil && !hasDepth)
2130 {
2131 if (isHelperClassTest(testTypeParam.value) && isNormalizedColorFormat(format))
2132 {
2133 // reduce helper class test cases and complexities
2134 continue;
2135 }
2136
2137 const deUint32 maxResultValue =
2138 (getDrawCallCount(&testParam) *
2139 getPatchesPerDrawCount(testParam.multiplePatchesPerDraw) *
2140 getColorAttachmentCount(testParam.testType) +
2141 getSampleCount(testParam.m_sampleCount));
2142 const tcu::IVec4 channelBitDepth =
2143 tcu::getTextureFormatBitDepth(mapVkFormat(format));
2144
2145 // color output precision is less than test case.
2146 // ban the overflow problem.
2147 if (static_cast<deUint32>(1 << (channelBitDepth.y() - 1)) > maxResultValue)
2148 {
2149 testParam.colorFormat = format;
2150 curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2151 }
2152 }
2153 }
2154 } // formats
2155 testGroupStack.pop_back();
2156 } // multiPatchParams
2157 testGroupStack.pop_back();
2158 } // multiDrawsParams
2159 testGroupStack.pop_back();
2160 } // sampleCountParams
2161 testGroupStack.pop_back();
2162 } // testTypeParams
2163 testGroupStack.pop_back();
2164 } // coherentParams
2165 }
2166 } // namespace
2167 // anonymous namespace
2168
createShaderTileImageTests(tcu::TestContext & testCtx)2169 tcu::TestCaseGroup* createShaderTileImageTests(tcu::TestContext& testCtx)
2170 {
2171 /* Add the color tests */
2172 tcu::TestCaseGroup* gr = new tcu::TestCaseGroup(testCtx, "shader_tile_image");
2173 createShaderTileImageTestVariations(testCtx, gr);
2174
2175 return gr;
2176 }
2177
2178 } // namespace rasterization
2179 } // namespace vkt
2180