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