1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017-2019 The Khronos Group Inc.
6 * Copyright (c) 2018-2020 NVIDIA Corporation
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Tests for VK_KHR_fragment_shading_rate
23 * The test renders 9*9 triangles, where each triangle has one of the valid
24 * fragment sizes ({1,2,4},{1,2,4}) (clamped to implementation limits) for
25 * each of the pipeline shading rate and the primitive shading rate. The
26 * fragment shader does an atomic add to a memory location to get a unique
27 * identifier for the fragment, and outputs the primitive ID, atomic counter,
28 * fragment size, and some other info the the color output. Then a compute
29 * shader copies this to buffer memory, and the host verifies several
30 * properties of the output. For example, if a sample has a particular
31 * primitive ID and atomic value, then all other samples in the tile with
32 * the same primitive ID should have the same atomic value.
33 *//*--------------------------------------------------------------------*/
34
35 #include "vktFragmentShadingRateBasic.hpp"
36
37 #include "vkBufferWithMemory.hpp"
38 #include "vkImageWithMemory.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkBuilderUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkTypeUtil.hpp"
43 #include "vkObjUtil.hpp"
44 #include "vkImageUtil.hpp"
45 #include "vkStrUtil.hpp"
46
47 #include "vktTestGroupUtil.hpp"
48 #include "vktTestCase.hpp"
49
50 #include "deDefs.h"
51 #include "deMath.h"
52 #include "deRandom.h"
53 #include "deSharedPtr.hpp"
54 #include "deString.h"
55
56 #include "tcuTestCase.hpp"
57 #include "tcuTestLog.hpp"
58
59 #include <set>
60 #include <string>
61 #include <sstream>
62 #include <vector>
63 #include <algorithm>
64 #include <iterator>
65
66 namespace vkt
67 {
68 namespace FragmentShadingRate
69 {
70 namespace
71 {
72 using namespace vk;
73 using namespace std;
74
75 #define NUM_TRIANGLES (9*9)
76
77 enum class AttachmentUsage
78 {
79 NO_ATTACHMENT = 0,
80 NO_ATTACHMENT_PTR,
81 WITH_ATTACHMENT,
82 WITH_ATTACHMENT_WITHOUT_IMAGEVIEW, // No imageview at VkRenderingFragmentShadingRateAttachmentInfoKHR.
83 };
84
85 struct CaseDef
86 {
87 SharedGroupParams groupParams;
88 deInt32 seed;
89 VkExtent2D framebufferDim;
90 VkSampleCountFlagBits samples;
91 VkFragmentShadingRateCombinerOpKHR combinerOp[2];
92 AttachmentUsage attachmentUsage;
93 bool shaderWritesRate;
94 bool geometryShader;
95 bool meshShader;
96 bool useDynamicState;
97 bool useApiSampleMask;
98 bool useSampleMaskIn;
99 bool conservativeEnable;
100 VkConservativeRasterizationModeEXT conservativeMode;
101 bool useDepthStencil; // == fragDepth || fragStencil
102 bool fragDepth;
103 bool fragStencil;
104 bool multiViewport;
105 bool colorLayered;
106 bool srLayered; // colorLayered must also be true
107 deUint32 numColorLayers;
108 bool multiView;
109 bool correlationMask;
110 bool interlock;
111 bool sampleLocations;
112 bool sampleShadingEnable;
113 bool sampleShadingInput;
114 bool sampleMaskTest;
115 bool earlyAndLateTest;
116 bool garbageAttachment;
117
useAttachmentvkt::FragmentShadingRate::__anon9bcbc2440111::CaseDef118 bool useAttachment () const
119 {
120 return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT);
121 }
122
useAttachmentWithoutImageViewvkt::FragmentShadingRate::__anon9bcbc2440111::CaseDef123 bool useAttachmentWithoutImageView () const
124 {
125 return (attachmentUsage == AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW);
126 }
127 };
128
129 class FSRTestInstance : public TestInstance
130 {
131 public:
132 FSRTestInstance (Context& context, const CaseDef& data);
133 ~FSRTestInstance (void);
134 tcu::TestStatus iterate (void);
135
136 private:
137 // Test parameters
138 CaseDef m_data;
139
140 // Cache simulated combiner operations, to avoid recomputing per-sample
141 deInt32 m_simulateValueCount;
142 vector<deInt32> m_simulateCache;
143 // Cache mapping of primitive ID to pipeline/primitive shading rate
144 vector<deInt32> m_primIDToPrimitiveShadingRate;
145 vector<deInt32> m_primIDToPipelineShadingRate;
146 deUint32 m_supportedFragmentShadingRateCount;
147 vector<VkPhysicalDeviceFragmentShadingRateKHR> m_supportedFragmentShadingRates;
148 VkPhysicalDeviceFragmentShadingRatePropertiesKHR m_shadingRateProperties;
149
150 protected:
151
152 void preRenderCommands (VkCommandBuffer cmdBuffer,
153 ImageWithMemory* cbImage,
154 ImageWithMemory* dsImage,
155 ImageWithMemory* derivImage,
156 deUint32 derivNumLevels,
157 ImageWithMemory* srImage,
158 VkImageLayout srLayout,
159 BufferWithMemory* srFillBuffer,
160 deUint32 numSRLayers,
161 deUint32 srWidth,
162 deUint32 srHeight,
163 deUint32 srFillBpp,
164 const VkClearValue& clearColor,
165 const VkClearValue& clearDepthStencil);
166 void beginLegacyRender (VkCommandBuffer cmdBuffer,
167 VkRenderPass renderPass,
168 VkFramebuffer framebuffer,
169 VkImageView srImageView,
170 VkImageView cbImageView,
171 VkImageView dsImageView,
172 bool imagelessFB) const;
173 void drawCommands (VkCommandBuffer cmdBuffer,
174 std::vector<GraphicsPipelineWrapper>& pipelines,
175 const std::vector<VkViewport>& viewports,
176 const std::vector<VkRect2D>& scissors,
177 const VkPipelineLayout pipelineLayout,
178 const VkRenderPass renderPass,
179 const VkPipelineVertexInputStateCreateInfo* vertexInputState,
180 const VkPipelineDynamicStateCreateInfo* dynamicState,
181 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
182 const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
183 const VkPipelineMultisampleStateCreateInfo* multisampleState,
184 VkPipelineFragmentShadingRateStateCreateInfoKHR* shadingRateState,
185 PipelineRenderingCreateInfoWrapper dynamicRenderingState,
186 const VkShaderModule vertShader,
187 const VkShaderModule geomShader,
188 const VkShaderModule meshShader,
189 const VkShaderModule fragShader,
190 const std::vector<VkDescriptorSet>& descriptorSet,
191 VkBuffer vertexBuffer,
192 const uint32_t pushConstantSize);
193 #ifndef CTS_USES_VULKANSC
194 void beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer,
195 VkFormat cbFormat,
196 VkFormat dsFormat,
197 VkRenderingFlagsKHR renderingFlags = 0u) const;
198 void beginDynamicRender (VkCommandBuffer cmdBuffer,
199 VkImageView srImageView,
200 VkImageLayout srImageLayout,
201 const VkExtent2D& srTexelSize,
202 VkImageView cbImageView,
203 VkImageView dsImageView,
204 const VkClearValue& clearColor,
205 const VkClearValue& clearDepthStencil,
206 VkRenderingFlagsKHR renderingFlags = 0u) const;
207 #endif // CTS_USES_VULKANSC
208
209 deInt32 PrimIDToPrimitiveShadingRate (deInt32 primID);
210 deInt32 PrimIDToPipelineShadingRate (deInt32 primID);
211 VkExtent2D SanitizeExtent (VkExtent2D ext) const;
212 deInt32 SanitizeRate (deInt32 rate) const;
213 deInt32 ShadingRateExtentToClampedMask (VkExtent2D ext) const;
214 deInt32 ShadingRateExtentToEnum (VkExtent2D ext) const;
215 VkExtent2D ShadingRateEnumToExtent (deInt32 rate) const;
216 deInt32 Simulate (deInt32 rate0, deInt32 rate1, deInt32 rate2);
217 VkExtent2D Combine (VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const;
218 deInt32 CombineMasks (deInt32 rateMask0, deInt32 rateMask1, VkFragmentShadingRateCombinerOpKHR comb, bool allowUnclampedResult) const;
219 bool Force1x1 () const;
220 };
221
FSRTestInstance(Context & context,const CaseDef & data)222 FSRTestInstance::FSRTestInstance (Context& context, const CaseDef& data)
223 : vkt::TestInstance (context)
224 , m_data (data)
225 , m_simulateValueCount (((4 * 4) | 4) + 1)
226 , m_simulateCache (m_simulateValueCount*m_simulateValueCount*m_simulateValueCount, ~0)
227 , m_primIDToPrimitiveShadingRate(NUM_TRIANGLES, ~0)
228 , m_primIDToPipelineShadingRate(NUM_TRIANGLES, ~0)
229 {
230 m_supportedFragmentShadingRateCount = 0;
231 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, DE_NULL);
232
233 if (m_supportedFragmentShadingRateCount < 3)
234 TCU_THROW(TestError, "*pFragmentShadingRateCount too small");
235
236 m_supportedFragmentShadingRates.resize(m_supportedFragmentShadingRateCount);
237 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
238 {
239 m_supportedFragmentShadingRates[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
240 m_supportedFragmentShadingRates[i].pNext = nullptr;
241 }
242 m_context.getInstanceInterface().getPhysicalDeviceFragmentShadingRatesKHR(m_context.getPhysicalDevice(), &m_supportedFragmentShadingRateCount, &m_supportedFragmentShadingRates[0]);
243
244 m_shadingRateProperties = m_context.getFragmentShadingRateProperties();
245 }
246
~FSRTestInstance(void)247 FSRTestInstance::~FSRTestInstance (void)
248 {
249 }
250
251 class FSRTestCase : public TestCase
252 {
253 public:
254 FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
255 ~FSRTestCase (void);
256 virtual void initPrograms (SourceCollections& programCollection) const;
257 virtual TestInstance* createInstance (Context& context) const;
258 virtual void checkSupport (Context& context) const;
259
260 private:
261 CaseDef m_data;
262 };
263
FSRTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef data)264 FSRTestCase::FSRTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
265 : vkt::TestCase (context, name, desc)
266 , m_data (data)
267 {
268 }
269
~FSRTestCase(void)270 FSRTestCase::~FSRTestCase (void)
271 {
272 }
273
Force1x1() const274 bool FSRTestInstance::Force1x1() const
275 {
276 if (m_data.useApiSampleMask && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
277 return true;
278
279 if (m_data.useSampleMaskIn && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
280 return true;
281
282 if (m_data.conservativeEnable && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithConservativeRasterization)
283 return true;
284
285 if (m_data.useDepthStencil && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderDepthStencilWrites)
286 return true;
287
288 if (m_data.interlock && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithFragmentShaderInterlock)
289 return true;
290
291 if (m_data.sampleLocations && !m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations)
292 return true;
293
294 if (m_data.sampleShadingEnable || m_data.sampleShadingInput)
295 return true;
296
297 return false;
298 }
299
300 static VkImageUsageFlags cbUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
301 VK_IMAGE_USAGE_SAMPLED_BIT |
302 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
303 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
304
305 static VkImageUsageFlags dsUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
306 VK_IMAGE_USAGE_SAMPLED_BIT |
307 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
308 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
309
310
checkSupport(Context & context) const311 void FSRTestCase::checkSupport(Context& context) const
312 {
313 context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
314
315 if (m_data.groupParams->useDynamicRendering)
316 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
317
318 if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
319 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
320
321 if (m_data.shaderWritesRate &&
322 !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
323 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
324
325 if (!context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate &&
326 m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
327 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRate not supported");
328
329 if (!context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
330 m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)
331 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
332
333 const auto& vki = context.getInstanceInterface();
334 const auto physDev = context.getPhysicalDevice();
335
336 VkImageFormatProperties imageProperties;
337 VkResult result = vki.getPhysicalDeviceImageFormatProperties(physDev, VK_FORMAT_R32G32B32A32_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, cbUsage, 0, &imageProperties);
338
339 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
340 TCU_THROW(NotSupportedError, "VK_FORMAT_R32G32B32A32_UINT not supported");
341
342 if (m_data.geometryShader)
343 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
344
345 if (!(imageProperties.sampleCounts & m_data.samples))
346 TCU_THROW(NotSupportedError, "color buffer sample count not supported");
347
348 if (m_data.numColorLayers > imageProperties.maxArrayLayers)
349 TCU_THROW(NotSupportedError, "color buffer layers not supported");
350
351 if (m_data.useAttachment() && !context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
352 TCU_THROW(NotSupportedError, "attachmentFragmentShadingRate not supported");
353
354 if (!context.getFragmentShadingRateProperties().fragmentShadingRateNonTrivialCombinerOps &&
355 ((m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
356 (m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR && m_data.combinerOp[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
357 TCU_THROW(NotSupportedError, "fragmentShadingRateNonTrivialCombinerOps not supported");
358
359 if (m_data.conservativeEnable)
360 {
361 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
362 if (m_data.conservativeMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT &&
363 !context.getConservativeRasterizationPropertiesEXT().primitiveUnderestimation)
364 TCU_THROW(NotSupportedError, "primitiveUnderestimation not supported");
365 }
366
367 if (m_data.fragStencil)
368 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
369
370 if (m_data.multiViewport &&
371 !context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports)
372 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateWithMultipleViewports not supported");
373
374 if (m_data.srLayered &&
375 !context.getFragmentShadingRateProperties().layeredShadingRateAttachments)
376 TCU_THROW(NotSupportedError, "layeredShadingRateAttachments not supported");
377
378 if ((m_data.multiViewport || m_data.colorLayered) &&
379 !m_data.geometryShader)
380 context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
381
382 if (m_data.multiView && m_data.geometryShader &&
383 !context.getMultiviewFeatures().multiviewGeometryShader)
384 TCU_THROW(NotSupportedError, "multiviewGeometryShader not supported");
385
386 if (m_data.interlock &&
387 !context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderPixelInterlock)
388 TCU_THROW(NotSupportedError, "fragmentShaderPixelInterlock not supported");
389
390 if (m_data.sampleLocations)
391 {
392 context.requireDeviceFunctionality("VK_EXT_sample_locations");
393 if (!(m_data.samples & context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts))
394 TCU_THROW(NotSupportedError, "samples not supported in sampleLocationSampleCounts");
395 }
396
397 if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
398 TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
399
400 #ifndef CTS_USES_VULKANSC
401 if (m_data.meshShader)
402 {
403 context.requireDeviceFunctionality("VK_EXT_mesh_shader");
404 const auto& meshFeatures = context.getMeshShaderFeaturesEXT();
405
406 if (m_data.shaderWritesRate && !meshFeatures.primitiveFragmentShadingRateMeshShader)
407 TCU_THROW(NotSupportedError, "primitiveFragmentShadingRateMeshShader not supported");
408
409 if (m_data.multiView && !meshFeatures.multiviewMeshShader)
410 TCU_THROW(NotSupportedError, "multiviewMeshShader not supported");
411 }
412
413 checkPipelineLibraryRequirements(vki, physDev, m_data.groupParams->pipelineConstructionType);
414
415 if (m_data.earlyAndLateTest)
416 {
417 context.requireDeviceFunctionality("VK_AMD_shader_early_and_late_fragment_tests");
418 if (context.getShaderEarlyAndLateFragmentTestsFeaturesAMD().shaderEarlyAndLateFragmentTests == VK_FALSE)
419 TCU_THROW(NotSupportedError, "shaderEarlyAndLateFragmentTests is not supported");
420 }
421 #endif
422 }
423
424 // Error codes writted by the fragment shader
425 enum
426 {
427 ERROR_NONE = 0,
428 ERROR_FRAGCOORD_CENTER = 1,
429 ERROR_VTG_READBACK = 2,
430 ERROR_FRAGCOORD_DERIV = 3,
431 ERROR_FRAGCOORD_IMPLICIT_DERIV = 4,
432 };
433
initPrograms(SourceCollections & programCollection) const434 void FSRTestCase::initPrograms (SourceCollections& programCollection) const
435 {
436 if (!m_data.meshShader)
437 {
438 std::stringstream vss;
439
440 vss <<
441 "#version 450 core\n"
442 "#extension GL_EXT_fragment_shading_rate : enable\n"
443 "#extension GL_ARB_shader_viewport_layer_array : enable\n"
444 "layout(push_constant) uniform PC {\n"
445 " int shadingRate;\n"
446 "} pc;\n"
447 "layout(location = 0) in vec2 pos;\n"
448 "layout(location = 0) out int instanceIndex;\n"
449 "layout(location = 1) out int readbackok;\n"
450 "layout(location = 2) out float zero;\n"
451 "out gl_PerVertex\n"
452 "{\n"
453 " vec4 gl_Position;\n"
454 "};\n"
455 "void main()\n"
456 "{\n"
457 " gl_Position = vec4(pos, 0, 1);\n"
458 " instanceIndex = gl_InstanceIndex;\n"
459 " readbackok = 1;\n"
460 " zero = 0;\n";
461
462 if (m_data.shaderWritesRate)
463 {
464 vss << " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
465
466 // Verify that we can read from the output variable
467 vss << " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
468
469 if (!m_data.geometryShader)
470 {
471 if (m_data.multiViewport)
472 vss << " gl_ViewportIndex = instanceIndex & 1;\n";
473 if (m_data.colorLayered)
474 vss << " gl_Layer = ((instanceIndex & 2) >> 1);\n";
475 }
476 }
477
478 vss << "}\n";
479
480 programCollection.glslSources.add("vert") << glu::VertexSource(vss.str());
481 programCollection.glslSources.add("vert_1_2") << glu::VertexSource(vss.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_5, 0u, true);
482
483 if (m_data.geometryShader)
484 {
485 std::string writeShadingRate = "";
486 if (m_data.shaderWritesRate)
487 {
488 writeShadingRate =
489 " gl_PrimitiveShadingRateEXT = pc.shadingRate;\n"
490 " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
491
492 if (m_data.multiViewport)
493 writeShadingRate += " gl_ViewportIndex = inInstanceIndex[0] & 1;\n";
494
495 if (m_data.colorLayered)
496 writeShadingRate += " gl_Layer = (inInstanceIndex[0] & 2) >> 1;\n";
497 }
498
499 std::stringstream gss;
500 gss <<
501 "#version 450 core\n"
502 "#extension GL_EXT_fragment_shading_rate : enable\n"
503 "\n"
504 "layout(push_constant) uniform PC {\n"
505 " int shadingRate;\n"
506 "} pc;\n"
507 "\n"
508 "in gl_PerVertex\n"
509 "{\n"
510 " vec4 gl_Position;\n"
511 "} gl_in[3];\n"
512 "\n"
513 "layout(location = 0) in int inInstanceIndex[];\n"
514 "layout(location = 0) out int outInstanceIndex;\n"
515 "layout(location = 1) out int readbackok;\n"
516 "layout(location = 2) out float zero;\n"
517 "layout(triangles) in;\n"
518 "layout(triangle_strip, max_vertices=3) out;\n"
519 "\n"
520 "out gl_PerVertex {\n"
521 " vec4 gl_Position;\n"
522 "};\n"
523 "\n"
524 "void main(void)\n"
525 "{\n"
526 " gl_Position = gl_in[0].gl_Position;\n"
527 " outInstanceIndex = inInstanceIndex[0];\n"
528 " readbackok = 1;\n"
529 " zero = 0;\n"
530 << writeShadingRate <<
531 " EmitVertex();"
532 "\n"
533 " gl_Position = gl_in[1].gl_Position;\n"
534 " outInstanceIndex = inInstanceIndex[1];\n"
535 " readbackok = 1;\n"
536 " zero = 0;\n"
537 << writeShadingRate <<
538 " EmitVertex();"
539 "\n"
540 " gl_Position = gl_in[2].gl_Position;\n"
541 " outInstanceIndex = inInstanceIndex[2];\n"
542 " readbackok = 1;\n"
543 " zero = 0;\n"
544 << writeShadingRate <<
545 " EmitVertex();"
546 "}\n";
547
548 programCollection.glslSources.add("geom") << glu::GeometrySource(gss.str());
549 }
550 }
551 else
552 {
553 std::stringstream mss;
554
555 mss <<
556 "#version 450 core\n"
557 "#extension GL_EXT_mesh_shader : enable\n"
558 "layout(local_size_x=3) in;\n"
559 "layout(triangles) out;\n"
560 "layout(max_vertices=3, max_primitives=1) out;\n"
561 "layout(push_constant, std430) uniform PC {\n"
562 " int shadingRate;\n"
563 " uint instanceIndex;\n"
564 "} pc;\n"
565 "layout(set=1, binding=0, std430) readonly buffer PosBuffer {\n"
566 " vec2 vertexPositions[];\n"
567 "} pb;\n"
568 "layout(location = 0) flat out int instanceIndex[];\n"
569 "layout(location = 1) flat out int readbackok[];\n"
570 "layout(location = 2) out float zero[];\n";
571
572 if (m_data.shaderWritesRate)
573 {
574 mss <<
575 "perprimitiveEXT out gl_MeshPerPrimitiveEXT {\n"
576 << (m_data.colorLayered ? " int gl_Layer;\n" : "")
577 << (m_data.multiViewport ? " int gl_ViewportIndex;\n" : "") <<
578 " int gl_PrimitiveShadingRateEXT;\n"
579 "} gl_MeshPrimitivesEXT[];\n";
580 }
581
582 mss <<
583 "void main()\n"
584 "{\n"
585 " SetMeshOutputsEXT(3u, 1u);\n"
586 " const uint vertexIdx = (pc.instanceIndex * 3u + gl_LocalInvocationIndex);\n"
587 " gl_MeshVerticesEXT[gl_LocalInvocationIndex].gl_Position = vec4(pb.vertexPositions[vertexIdx], 0, 1);\n"
588 " if (gl_LocalInvocationIndex == 0) {\n"
589 " gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0, 1, 2);\n"
590 " }\n"
591 " instanceIndex[gl_LocalInvocationIndex] = int(pc.instanceIndex);\n"
592 " readbackok[gl_LocalInvocationIndex] = 1;\n"
593 " zero[gl_LocalInvocationIndex] = 0;\n";
594
595 if (m_data.shaderWritesRate)
596 {
597 mss << " gl_MeshPrimitivesEXT[0].gl_PrimitiveShadingRateEXT = pc.shadingRate;\n";
598
599 // gl_MeshPerPrimitiveEXT is write-only in mesh shaders, so we cannot verify the readback operation.
600 //mss << " if (gl_PrimitiveShadingRateEXT != pc.shadingRate) readbackok = 0;\n";
601
602 if (m_data.multiViewport)
603 mss << " gl_MeshPrimitivesEXT[0].gl_ViewportIndex = int(pc.instanceIndex & 1);\n";
604 if (m_data.colorLayered)
605 mss << " gl_MeshPrimitivesEXT[0].gl_Layer = int((pc.instanceIndex & 2) >> 1);\n";
606 }
607
608 mss << "}\n";
609
610 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
611 programCollection.glslSources.add("mesh") << glu::MeshSource(mss.str()) << buildOptions;
612 }
613
614 std::stringstream fss;
615
616 fss <<
617 "#version 450 core\n"
618 "#extension GL_EXT_fragment_shading_rate : enable\n"
619 "#extension GL_ARB_shader_stencil_export : enable\n"
620 "#extension GL_ARB_fragment_shader_interlock : enable\n";
621
622 if (m_data.earlyAndLateTest)
623 fss << "#extension GL_AMD_shader_early_and_late_fragment_tests : enable\n";
624
625 fss << "layout(location = 0) out uvec4 col0;\n"
626 "layout(set = 0, binding = 0) buffer Block { uint counter; } buf;\n"
627 "layout(set = 0, binding = 3) uniform usampler2D tex;\n"
628 "layout(location = 0) flat in int instanceIndex;\n"
629 "layout(location = 1) flat in int readbackok;\n"
630 "layout(location = 2) " << (m_data.sampleShadingInput ? "sample " : "") << "in float zero;\n";
631
632 if (m_data.earlyAndLateTest)
633 fss << "layout(early_and_late_fragment_tests_amd) in;\n";
634
635 if (m_data.fragDepth && m_data.earlyAndLateTest)
636 fss << "layout(depth_less) out float gl_FragDepth;\n";
637
638 if (m_data.fragStencil && m_data.earlyAndLateTest)
639 fss << "layout(stencil_ref_less_front_amd) out int gl_FragStencilRefARB;\n";
640
641 if (m_data.interlock)
642 fss << "layout(pixel_interlock_ordered) in;\n";
643
644 fss <<
645 "void main()\n"
646 "{\n";
647
648 if (m_data.interlock)
649 fss << " beginInvocationInterlockARB();\n";
650
651 fss <<
652 // X component gets shading rate enum
653 " col0.x = gl_ShadingRateEXT;\n"
654 " col0.y = 0;\n"
655 // Z component gets packed primitiveID | atomic value
656 " col0.z = (instanceIndex << 24) | ((atomicAdd(buf.counter, 1) + 1) & 0x00FFFFFFu);\n"
657 " ivec2 fragCoordXY = ivec2(gl_FragCoord.xy);\n"
658 " ivec2 fragSize = ivec2(1<<((gl_ShadingRateEXT/4)&3), 1<<(gl_ShadingRateEXT&3));\n"
659 // W component gets error code
660 " col0.w = uint(zero)" << (m_data.sampleShadingInput ? " * gl_SampleID" : "") << ";\n"
661 " if (((fragCoordXY - fragSize / 2) % fragSize) != ivec2(0,0))\n"
662 " col0.w = " << ERROR_FRAGCOORD_CENTER << ";\n";
663
664 if (m_data.shaderWritesRate)
665 {
666 fss <<
667 " if (readbackok != 1)\n"
668 " col0.w = " << ERROR_VTG_READBACK << ";\n";
669 }
670
671 // When sample shading, gl_FragCoord is more likely to give bad derivatives,
672 // e.g. due to a partially covered quad having some pixels center sample and
673 // some sample at a sample location.
674 if (!m_data.sampleShadingEnable && !m_data.sampleShadingInput)
675 {
676 fss << " if (dFdx(gl_FragCoord.xy) != ivec2(fragSize.x, 0) || dFdy(gl_FragCoord.xy) != ivec2(0, fragSize.y))\n"
677 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (int(dFdx(gl_FragCoord.xy)) << 14) | (int(dFdx(gl_FragCoord.xy)) << 8) | " << ERROR_FRAGCOORD_DERIV << ";\n";
678
679 fss << " uint implicitDerivX = texture(tex, vec2(gl_FragCoord.x / textureSize(tex, 0).x, 0)).x;\n"
680 " uint implicitDerivY = texture(tex, vec2(0, gl_FragCoord.y / textureSize(tex, 0).y)).x;\n"
681 " if (implicitDerivX != fragSize.x || implicitDerivY != fragSize.y)\n"
682 " col0.w = (fragSize.y << 26) | (fragSize.x << 20) | (implicitDerivY << 14) | (implicitDerivX << 8) | " << ERROR_FRAGCOORD_IMPLICIT_DERIV << ";\n";
683 }
684 // Y component gets sample mask value
685 if (m_data.useSampleMaskIn)
686 fss << " col0.y = gl_SampleMaskIn[0];\n";
687
688 if (m_data.fragDepth)
689 fss << " gl_FragDepth = float(instanceIndex) / float(" << NUM_TRIANGLES << ");\n";
690
691 if (m_data.fragStencil)
692 fss << " gl_FragStencilRefARB = instanceIndex;\n";
693
694 if (m_data.interlock)
695 fss << " endInvocationInterlockARB();\n";
696
697 fss <<
698 "}\n";
699
700 programCollection.glslSources.add("frag") << glu::FragmentSource(fss.str());
701
702 std::stringstream css;
703
704 std::string fsampType = m_data.samples > 1 ? "texture2DMSArray" : "texture2DArray";
705 std::string usampType = m_data.samples > 1 ? "utexture2DMSArray" : "utexture2DArray";
706
707 // Compute shader copies color/depth/stencil to linear layout in buffer memory
708 css <<
709 "#version 450 core\n"
710 "#extension GL_EXT_samplerless_texture_functions : enable\n"
711 "layout(set = 0, binding = 1) uniform " << usampType << " colorTex;\n"
712 "layout(set = 0, binding = 2, std430) buffer Block0 { uvec4 b[]; } colorbuf;\n"
713 "layout(set = 0, binding = 4, std430) buffer Block1 { float b[]; } depthbuf;\n"
714 "layout(set = 0, binding = 5, std430) buffer Block2 { uint b[]; } stencilbuf;\n"
715 "layout(set = 0, binding = 6) uniform " << fsampType << " depthTex;\n"
716 "layout(set = 0, binding = 7) uniform " << usampType << " stencilTex;\n"
717 "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
718 "void main()\n"
719 "{\n"
720 " for (int i = 0; i < " << m_data.samples << "; ++i) {\n"
721 " uint idx = ((gl_GlobalInvocationID.z * " << m_data.framebufferDim.height << " + gl_GlobalInvocationID.y) * " << m_data.framebufferDim.width << " + gl_GlobalInvocationID.x) * " << m_data.samples << " + i;\n"
722 " colorbuf.b[idx] = texelFetch(colorTex, ivec3(gl_GlobalInvocationID.xyz), i);\n";
723
724 if (m_data.fragDepth)
725 css << " depthbuf.b[idx] = texelFetch(depthTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
726
727 if (m_data.fragStencil)
728 css << " stencilbuf.b[idx] = texelFetch(stencilTex, ivec3(gl_GlobalInvocationID.xyz), i).x;\n";
729
730 css <<
731 " }\n"
732 "}\n";
733
734 programCollection.glslSources.add("comp") << glu::ComputeSource(css.str());
735 }
736
createInstance(Context & context) const737 TestInstance* FSRTestCase::createInstance (Context& context) const
738 {
739 return new FSRTestInstance(context, m_data);
740 }
741
ShadingRateExtentToEnum(VkExtent2D ext) const742 deInt32 FSRTestInstance::ShadingRateExtentToEnum(VkExtent2D ext) const
743 {
744 ext.width = deCtz32(ext.width);
745 ext.height = deCtz32(ext.height);
746
747 return (ext.width << 2) | ext.height;
748 }
749
ShadingRateEnumToExtent(deInt32 rate) const750 VkExtent2D FSRTestInstance::ShadingRateEnumToExtent(deInt32 rate) const
751 {
752 VkExtent2D ret;
753 ret.width = 1 << ((rate/4) & 3);
754 ret.height = 1 << (rate & 3);
755
756 return ret;
757 }
758
Combine(VkExtent2D ext0,VkExtent2D ext1,VkFragmentShadingRateCombinerOpKHR comb) const759 VkExtent2D FSRTestInstance::Combine(VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const
760 {
761 VkExtent2D ret;
762 switch (comb)
763 {
764 default:
765 DE_ASSERT(0);
766 // fallthrough
767 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR:
768 return ext0;
769 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR:
770 return ext1;
771 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR:
772 ret = { de::min(ext0.width, ext1.width), de::min(ext0.height, ext1.height) };
773 return ret;
774 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR:
775 ret = { de::max(ext0.width, ext1.width), de::max(ext0.height, ext1.height) };
776 return ret;
777 case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR:
778 ret = { ext0.width * ext1.width, ext0.height * ext1.height };
779 if (!m_shadingRateProperties.fragmentShadingRateStrictMultiplyCombiner)
780 {
781 if (ext0.width == 1 && ext1.width == 1)
782 ret.width = 2;
783 if (ext0.height == 1 && ext1.height == 1)
784 ret.height = 2;
785 }
786 return ret;
787 }
788 }
789
CombineMasks(deInt32 rateMask0,deInt32 rateMask1,VkFragmentShadingRateCombinerOpKHR comb,bool allowUnclampedResult) const790 deInt32 FSRTestInstance::CombineMasks(deInt32 rateMask0, deInt32 rateMask1, VkFragmentShadingRateCombinerOpKHR comb, bool allowUnclampedResult) const
791 {
792 deInt32 combinedMask = 0;
793
794 for (int i = 0; i < 16; i++)
795 {
796 if (rateMask0 & (1 << i))
797 {
798 VkExtent2D rate0 = ShadingRateEnumToExtent(i);
799
800 for (int j = 0; j < 16; j++)
801 {
802 if (rateMask1 & (1 << j))
803 {
804 VkExtent2D combinerResult = Combine(rate0, ShadingRateEnumToExtent(j), comb);
805 deInt32 clampedResult = ShadingRateExtentToClampedMask(combinerResult);
806
807 if (allowUnclampedResult)
808 {
809 combinedMask |= 1 << ShadingRateExtentToEnum(combinerResult);
810 }
811
812 combinedMask |= clampedResult;
813 }
814 }
815 }
816 }
817
818 return combinedMask;
819 }
820
Simulate(deInt32 rate0,deInt32 rate1,deInt32 rate2)821 deInt32 FSRTestInstance::Simulate(deInt32 rate0, deInt32 rate1, deInt32 rate2)
822 {
823 deInt32 &cachedRate = m_simulateCache[(rate2*m_simulateValueCount + rate1)*m_simulateValueCount + rate0];
824 if (cachedRate != ~0)
825 return cachedRate;
826
827 const VkExtent2D extent0 = ShadingRateEnumToExtent(rate0);
828 const VkExtent2D extent1 = ShadingRateEnumToExtent(rate1);
829 const VkExtent2D extent2 = ShadingRateEnumToExtent(rate2);
830
831 deInt32 finalMask = 0;
832
833 // Clamped and unclamped inputs.
834 const deInt32 extentMask0 = ShadingRateExtentToClampedMask(extent0) | (1 << rate0);
835 const deInt32 extentMask1 = ShadingRateExtentToClampedMask(extent1) | (1 << rate1);
836 const deInt32 extentMask2 = ShadingRateExtentToClampedMask(extent2) | (1 << rate2);
837
838 // Combine rate 0 and 1, get a mask of possible clamped rates
839 deInt32 intermedMask = CombineMasks(extentMask0, extentMask1, m_data.combinerOp[0], true /* allowUnclampedResult */);
840
841 // For each clamped rate, combine that with rate 2 and accumulate the possible clamped rates
842 for (int i = 0; i < 16; ++i)
843 {
844 if (intermedMask & (1<<i))
845 {
846 finalMask |= CombineMasks(intermedMask , extentMask2, m_data.combinerOp[1], false /* allowUnclampedResult */);
847 }
848 }
849
850 if (Force1x1())
851 finalMask = 0x1;
852
853 cachedRate = finalMask;
854 return finalMask;
855 }
856
857 // If a rate is not valid (<=4x4), clamp it to something valid.
858 // This is only used for "inputs" to the system, not to mimic
859 // how the implementation internally clamps intermediate values.
SanitizeExtent(VkExtent2D ext) const860 VkExtent2D FSRTestInstance::SanitizeExtent(VkExtent2D ext) const
861 {
862 DE_ASSERT(ext.width > 0 && ext.height > 0);
863
864 ext.width = de::min(ext.width, 4u);
865 ext.height = de::min(ext.height, 4u);
866
867 return ext;
868 }
869
870 // Map an extent to a mask of all modes smaller than or equal to it in either dimension
ShadingRateExtentToClampedMask(VkExtent2D ext) const871 deInt32 FSRTestInstance::ShadingRateExtentToClampedMask(VkExtent2D ext) const
872 {
873 const deUint32 shadingRateBit = (1 << ShadingRateExtentToEnum(ext));
874 deUint32 desiredSize = ext.width * ext.height;
875 deInt32 mask = 0;
876 deInt32 swappedSizesMask = 0;
877
878 while (desiredSize > 0)
879 {
880 // First, find modes that maximize the area
881 for (deUint32 i = 0; i < m_supportedFragmentShadingRateCount; ++i)
882 {
883 const VkPhysicalDeviceFragmentShadingRateKHR &supportedRate = m_supportedFragmentShadingRates[i];
884 if ((supportedRate.sampleCounts & m_data.samples) &&
885 supportedRate.fragmentSize.width * supportedRate.fragmentSize.height == desiredSize)
886 {
887 if (supportedRate.fragmentSize.width <= ext.width && supportedRate.fragmentSize.height <= ext.height)
888 {
889 mask |= 1 << ShadingRateExtentToEnum(supportedRate.fragmentSize);
890 }
891 else if (supportedRate.fragmentSize.height <= ext.width && supportedRate.fragmentSize.width <= ext.height)
892 {
893 swappedSizesMask |= 1 << ShadingRateExtentToEnum(supportedRate.fragmentSize);
894 }
895 }
896 }
897 if (mask)
898 {
899 // Amongst the modes that maximize the area, pick the ones that
900 // minimize the aspect ratio. Prefer ratio of 1, then 2, then 4.
901 // 1x1 = 0, 2x2 = 5, 4x4 = 10
902 static const deUint32 aspectMaskRatio1 = 0x421;
903 // 2x1 = 4, 1x2 = 1, 4x2 = 9, 2x4 = 6
904 static const deUint32 aspectMaskRatio2 = 0x252;
905 // 4x1 = 8, 1x4 = 2,
906 static const deUint32 aspectMaskRatio4 = 0x104;
907
908 if (mask & aspectMaskRatio1)
909 {
910 mask &= aspectMaskRatio1;
911 break;
912 }
913 if (mask & aspectMaskRatio2)
914 {
915 mask &= aspectMaskRatio2;
916 break;
917 }
918 if (mask & aspectMaskRatio4)
919 {
920 mask &= aspectMaskRatio4;
921 break;
922 }
923 DE_ASSERT(0);
924 }
925 desiredSize /= 2;
926 }
927
928 // Optionally include the sizes with swapped width and height.
929 mask |= swappedSizesMask;
930
931 if (mask & shadingRateBit)
932 {
933 // The given shading rate is valid. Don't clamp it.
934 return shadingRateBit;
935 }
936
937 // Return alternative shading rates.
938 return mask;
939 }
940
941
SanitizeRate(deInt32 rate) const942 deInt32 FSRTestInstance::SanitizeRate(deInt32 rate) const
943 {
944 VkExtent2D extent = ShadingRateEnumToExtent(rate);
945
946 extent = SanitizeExtent(extent);
947
948 return ShadingRateExtentToEnum(extent);
949 }
950
951 // Map primID % 9 to primitive shading rate
PrimIDToPrimitiveShadingRate(deInt32 primID)952 deInt32 FSRTestInstance::PrimIDToPrimitiveShadingRate(deInt32 primID)
953 {
954 deInt32 &cachedRate = m_primIDToPrimitiveShadingRate[primID];
955 if (cachedRate != ~0)
956 return cachedRate;
957
958 VkExtent2D extent;
959 extent.width = 1 << (primID % 3);
960 extent.height = 1 << ((primID/3) % 3);
961
962 cachedRate = ShadingRateExtentToEnum(extent);
963 return cachedRate;
964 }
965
966 // Map primID / 9 to pipeline shading rate
PrimIDToPipelineShadingRate(deInt32 primID)967 deInt32 FSRTestInstance::PrimIDToPipelineShadingRate(deInt32 primID)
968 {
969 deInt32 &cachedRate = m_primIDToPipelineShadingRate[primID];
970 if (cachedRate != ~0)
971 return cachedRate;
972
973 primID /= 9;
974 VkExtent2D extent;
975 extent.width = 1 << (primID % 3);
976 extent.height = 1 << ((primID/3) % 3);
977
978 cachedRate = ShadingRateExtentToEnum(extent);
979 return cachedRate;
980 }
981
CreateCachedBuffer(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkBufferCreateInfo & bufferCreateInfo)982 static de::MovePtr<BufferWithMemory> CreateCachedBuffer(const vk::DeviceInterface& vk,
983 const vk::VkDevice device,
984 vk::Allocator& allocator,
985 const vk::VkBufferCreateInfo& bufferCreateInfo)
986 {
987 try
988 {
989 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
990 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Cached));
991 }
992 catch (const tcu::NotSupportedError&)
993 {
994 return de::MovePtr<BufferWithMemory>(new BufferWithMemory(
995 vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
996 }
997 }
998
iterate(void)999 tcu::TestStatus FSRTestInstance::iterate (void)
1000 {
1001 const DeviceInterface& vk = m_context.getDeviceInterface();
1002 const VkDevice device = m_context.getDevice();
1003 tcu::TestLog& log = m_context.getTestContext().getLog();
1004 Allocator& allocator = m_context.getDefaultAllocator();
1005 VkFlags allShaderStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
1006 VkFlags allPipelineStages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
1007 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
1008 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
1009 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
1010 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
1011 VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
1012 const VkFormat cbFormat = VK_FORMAT_R32G32B32A32_UINT;
1013 VkFormat dsFormat = VK_FORMAT_UNDEFINED;
1014 const auto vertBufferUsage = (m_data.meshShader ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1015
1016 if (m_data.meshShader)
1017 {
1018 #ifndef CTS_USES_VULKANSC
1019 allShaderStages |= VK_SHADER_STAGE_MESH_BIT_EXT;
1020 allPipelineStages |= VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT;
1021 #else
1022 DE_ASSERT(false);
1023 #endif // CTS_USES_VULKANSC
1024 }
1025 else
1026 {
1027 allShaderStages |= VK_SHADER_STAGE_VERTEX_BIT;
1028 allPipelineStages |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
1029
1030 if (m_data.geometryShader)
1031 {
1032 allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
1033 allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
1034 }
1035 }
1036
1037 if (m_data.useDepthStencil)
1038 {
1039 VkFormatProperties formatProps;
1040 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), VK_FORMAT_D32_SFLOAT_S8_UINT, &formatProps);
1041 if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
1042 {
1043 dsFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
1044 }
1045 else
1046 {
1047 dsFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1048 }
1049 }
1050
1051 deRandom rnd;
1052 deRandom_init(&rnd, m_data.seed);
1053
1054 qpTestResult res = QP_TEST_RESULT_PASS;
1055 deUint32 numUnexpected1x1Samples = 0;
1056 deUint32 numTotalSamples = 0;
1057
1058 enum AttachmentModes
1059 {
1060 ATTACHMENT_MODE_DEFAULT = 0,
1061 ATTACHMENT_MODE_LAYOUT_OPTIMAL,
1062 ATTACHMENT_MODE_IMAGELESS,
1063 ATTACHMENT_MODE_2DARRAY,
1064 ATTACHMENT_MODE_TILING_LINEAR,
1065
1066 ATTACHMENT_MODE_COUNT,
1067 };
1068
1069 deUint32 numSRLayers = m_data.srLayered ? 2u : 1u;
1070
1071 VkExtent2D minFragmentShadingRateAttachmentTexelSize = {1, 1};
1072 VkExtent2D maxFragmentShadingRateAttachmentTexelSize = {1, 1};
1073 deUint32 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1;
1074 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate)
1075 {
1076 minFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().minFragmentShadingRateAttachmentTexelSize;
1077 maxFragmentShadingRateAttachmentTexelSize = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSize;
1078 maxFragmentShadingRateAttachmentTexelSizeAspectRatio = m_context.getFragmentShadingRateProperties().maxFragmentShadingRateAttachmentTexelSizeAspectRatio;
1079 }
1080
1081 VkDeviceSize atomicBufferSize = sizeof(deUint32);
1082
1083 de::MovePtr<BufferWithMemory> atomicBuffer;
1084 atomicBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1085 vk, device, allocator, makeBufferCreateInfo(atomicBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
1086
1087 deUint32 *abuf = (deUint32 *)atomicBuffer->getAllocation().getHostPtr();
1088
1089 // NUM_TRIANGLES triangles, 3 vertices, 2 components of float position
1090 VkDeviceSize vertexBufferSize = NUM_TRIANGLES * 3 * 2 * sizeof(float);
1091
1092 de::MovePtr<BufferWithMemory> vertexBuffer;
1093 vertexBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
1094 vk, device, allocator, makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vertBufferUsage), MemoryRequirement::HostVisible | MemoryRequirement::Coherent));
1095
1096 float *vbuf = (float *)vertexBuffer->getAllocation().getHostPtr();
1097 for (deInt32 i = 0; i < (deInt32)(vertexBufferSize / sizeof(float)); ++i)
1098 {
1099 vbuf[i] = deRandom_getFloat(&rnd)*2.0f - 1.0f;
1100 }
1101 flushAlloc(vk, device, vertexBuffer->getAllocation());
1102
1103 VkDeviceSize colorOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * 4 * sizeof(deUint32) * m_data.numColorLayers;
1104 de::MovePtr<BufferWithMemory> colorOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(colorOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
1105
1106 VkDeviceSize depthOutputBufferSize = 0, stencilOutputBufferSize = 0;
1107 de::MovePtr<BufferWithMemory> depthOutputBuffer, stencilOutputBuffer;
1108 if (m_data.useDepthStencil)
1109 {
1110 depthOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(float) * m_data.numColorLayers;
1111 depthOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(depthOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
1112
1113 stencilOutputBufferSize = m_data.framebufferDim.width * m_data.framebufferDim.height * m_data.samples * sizeof(deUint32) * m_data.numColorLayers;
1114 stencilOutputBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(stencilOutputBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
1115 }
1116
1117 deUint32 minSRTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
1118 deUint32 minSRTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
1119 deUint32 maxSRWidth = (m_data.framebufferDim.width + minSRTexelWidth - 1) / minSRTexelWidth;
1120 deUint32 maxSRHeight = (m_data.framebufferDim.height + minSRTexelHeight - 1) / minSRTexelHeight;
1121
1122 // max size over all formats
1123 VkDeviceSize srFillBufferSize = numSRLayers * maxSRWidth * maxSRHeight * 32/*4 component 64-bit*/;
1124 de::MovePtr<BufferWithMemory> srFillBuffer;
1125 deUint8 *fillPtr = DE_NULL;
1126 if (m_data.useAttachment())
1127 {
1128 srFillBuffer = CreateCachedBuffer(vk, device, allocator, makeBufferCreateInfo(srFillBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
1129 fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
1130 }
1131
1132 de::MovePtr<ImageWithMemory> cbImage;
1133 Move<VkImageView> cbImageView;
1134 {
1135 const VkImageCreateInfo imageCreateInfo =
1136 {
1137 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1138 DE_NULL, // const void* pNext;
1139 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1140 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1141 cbFormat, // VkFormat format;
1142 {
1143 m_data.framebufferDim.width, // deUint32 width;
1144 m_data.framebufferDim.height, // deUint32 height;
1145 1u // deUint32 depth;
1146 }, // VkExtent3D extent;
1147 1u, // deUint32 mipLevels;
1148 m_data.numColorLayers, // deUint32 arrayLayers;
1149 m_data.samples, // VkSampleCountFlagBits samples;
1150 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1151 cbUsage, // VkImageUsageFlags usage;
1152 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1153 0u, // deUint32 queueFamilyIndexCount;
1154 DE_NULL, // const deUint32* pQueueFamilyIndices;
1155 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1156 };
1157 cbImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1158 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1159
1160 VkImageViewCreateInfo imageViewCreateInfo =
1161 {
1162 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1163 DE_NULL, // const void* pNext;
1164 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1165 **cbImage, // VkImage image;
1166 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
1167 cbFormat, // VkFormat format;
1168 {
1169 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1170 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1171 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1172 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1173 }, // VkComponentMapping components;
1174 {
1175 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1176 0u, // deUint32 baseMipLevel;
1177 1u, // deUint32 levelCount;
1178 0u, // deUint32 baseArrayLayer;
1179 m_data.numColorLayers // deUint32 layerCount;
1180 } // VkImageSubresourceRange subresourceRange;
1181 };
1182 cbImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1183 }
1184
1185 de::MovePtr<ImageWithMemory> dsImage;
1186 Move<VkImageView> dsImageView, dImageView, sImageView;
1187
1188 if (m_data.useDepthStencil)
1189 {
1190 const VkImageCreateInfo imageCreateInfo =
1191 {
1192 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1193 DE_NULL, // const void* pNext;
1194 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1195 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1196 dsFormat, // VkFormat format;
1197 {
1198 m_data.framebufferDim.width, // deUint32 width;
1199 m_data.framebufferDim.height, // deUint32 height;
1200 1u // deUint32 depth;
1201 }, // VkExtent3D extent;
1202 1u, // deUint32 mipLevels;
1203 m_data.numColorLayers, // deUint32 arrayLayers;
1204 m_data.samples, // VkSampleCountFlagBits samples;
1205 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1206 dsUsage, // VkImageUsageFlags usage;
1207 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1208 0u, // deUint32 queueFamilyIndexCount;
1209 DE_NULL, // const deUint32* pQueueFamilyIndices;
1210 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1211 };
1212 dsImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1213 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1214
1215 VkImageViewCreateInfo imageViewCreateInfo =
1216 {
1217 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1218 DE_NULL, // const void* pNext;
1219 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1220 **dsImage, // VkImage image;
1221 VK_IMAGE_VIEW_TYPE_2D_ARRAY, // VkImageViewType viewType;
1222 dsFormat, // VkFormat format;
1223 {
1224 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1225 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1226 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1227 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1228 }, // VkComponentMapping components;
1229 {
1230 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
1231 0u, // deUint32 baseMipLevel;
1232 1u, // deUint32 levelCount;
1233 0u, // deUint32 baseArrayLayer;
1234 m_data.numColorLayers // deUint32 layerCount;
1235 } // VkImageSubresourceRange subresourceRange;
1236 };
1237 dsImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1238 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1239 dImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1240 imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1241 sImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1242 }
1243
1244 // Image used to test implicit derivative calculations.
1245 // Filled with a value of 1<<lod.
1246 de::MovePtr<ImageWithMemory> derivImage;
1247 Move<VkImageView> derivImageView;
1248 VkImageUsageFlags derivUsage = VK_IMAGE_USAGE_SAMPLED_BIT |
1249 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1250 deUint32 derivNumLevels;
1251 {
1252 deUint32 maxDim = de::max(m_context.getFragmentShadingRateProperties().maxFragmentSize.width, m_context.getFragmentShadingRateProperties().maxFragmentSize.height);
1253 derivNumLevels = 1 + deCtz32(maxDim);
1254 const VkImageCreateInfo imageCreateInfo =
1255 {
1256 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1257 DE_NULL, // const void* pNext;
1258 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1259 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1260 VK_FORMAT_R32_UINT, // VkFormat format;
1261 {
1262 m_context.getFragmentShadingRateProperties().maxFragmentSize.width, // deUint32 width;
1263 m_context.getFragmentShadingRateProperties().maxFragmentSize.height, // deUint32 height;
1264 1u // deUint32 depth;
1265 }, // VkExtent3D extent;
1266 derivNumLevels, // deUint32 mipLevels;
1267 1u, // deUint32 arrayLayers;
1268 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1269 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1270 derivUsage, // VkImageUsageFlags usage;
1271 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1272 0u, // deUint32 queueFamilyIndexCount;
1273 DE_NULL, // const deUint32* pQueueFamilyIndices;
1274 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1275 };
1276 derivImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1277 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1278
1279 VkImageViewCreateInfo imageViewCreateInfo =
1280 {
1281 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1282 DE_NULL, // const void* pNext;
1283 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1284 **derivImage, // VkImage image;
1285 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1286 VK_FORMAT_R32_UINT, // VkFormat format;
1287 {
1288 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1289 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1290 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1291 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1292 }, // VkComponentMapping components;
1293 {
1294 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1295 0u, // deUint32 baseMipLevel;
1296 derivNumLevels, // deUint32 levelCount;
1297 0u, // deUint32 baseArrayLayer;
1298 1u // deUint32 layerCount;
1299 } // VkImageSubresourceRange subresourceRange;
1300 };
1301 derivImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1302 }
1303
1304 // sampler used with derivImage
1305 const struct VkSamplerCreateInfo samplerInfo =
1306 {
1307 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // sType
1308 DE_NULL, // pNext
1309 0u, // flags
1310 VK_FILTER_NEAREST, // magFilter
1311 VK_FILTER_NEAREST, // minFilter
1312 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
1313 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
1314 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
1315 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
1316 0.0f, // mipLodBias
1317 VK_FALSE, // anisotropyEnable
1318 1.0f, // maxAnisotropy
1319 DE_FALSE, // compareEnable
1320 VK_COMPARE_OP_ALWAYS, // compareOp
1321 0.0f, // minLod
1322 (float)derivNumLevels, // maxLod
1323 VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, // borderColor
1324 VK_FALSE, // unnormalizedCoords
1325 };
1326
1327 Move<VkSampler> sampler = createSampler(vk, device, &samplerInfo);
1328
1329 std::vector<Move<vk::VkDescriptorSetLayout>> descriptorSetLayouts;
1330 const VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1331
1332 const VkDescriptorSetLayoutBinding bindings[] =
1333 {
1334 {
1335 0u, // binding
1336 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1337 1u, // descriptorCount
1338 allShaderStages, // stageFlags
1339 DE_NULL, // pImmutableSamplers
1340 },
1341 {
1342 1u, // binding
1343 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1344 1u, // descriptorCount
1345 allShaderStages, // stageFlags
1346 DE_NULL, // pImmutableSamplers
1347 },
1348 {
1349 2u, // binding
1350 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1351 1u, // descriptorCount
1352 allShaderStages, // stageFlags
1353 DE_NULL, // pImmutableSamplers
1354 },
1355 {
1356 3u, // binding
1357 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType
1358 1u, // descriptorCount
1359 allShaderStages, // stageFlags
1360 DE_NULL, // pImmutableSamplers
1361 },
1362 {
1363 4u, // binding
1364 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1365 1u, // descriptorCount
1366 allShaderStages, // stageFlags
1367 DE_NULL, // pImmutableSamplers
1368 },
1369 {
1370 5u, // binding
1371 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1372 1u, // descriptorCount
1373 allShaderStages, // stageFlags
1374 DE_NULL, // pImmutableSamplers
1375 },
1376 {
1377 6u, // binding
1378 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1379 1u, // descriptorCount
1380 allShaderStages, // stageFlags
1381 DE_NULL, // pImmutableSamplers
1382 },
1383 {
1384 7u, // binding
1385 VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1386 1u, // descriptorCount
1387 allShaderStages, // stageFlags
1388 DE_NULL, // pImmutableSamplers
1389 },
1390 };
1391
1392 // Create a layout and allocate a descriptor set for it.
1393 const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo =
1394 {
1395 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1396 DE_NULL, // pNext
1397 layoutCreateFlags, // flags
1398 static_cast<uint32_t>(de::arrayLength(bindings)), // bindingCount
1399 &bindings[0] // pBindings
1400 };
1401
1402 descriptorSetLayouts.push_back(vk::createDescriptorSetLayout(vk, device, &setLayoutCreateInfo));
1403
1404 // Mesh shaders use set 1 binding 0 as the vertex buffer.
1405 if (m_data.meshShader)
1406 {
1407 #ifndef CTS_USES_VULKANSC
1408 const VkDescriptorSetLayoutBinding extraBinding =
1409 {
1410 0u, // binding
1411 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1412 1u, // descriptorCount
1413 VK_SHADER_STAGE_MESH_BIT_EXT, // stageFlags
1414 DE_NULL, // pImmutableSamplers
1415 };
1416
1417 const VkDescriptorSetLayoutCreateInfo extraSetLayoutCreateInfo =
1418 {
1419 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1420 DE_NULL, // pNext
1421 layoutCreateFlags, // flags
1422 1u, // bindingCount
1423 &extraBinding, // pBindings
1424 };
1425
1426 descriptorSetLayouts.push_back(vk::createDescriptorSetLayout(vk, device, &extraSetLayoutCreateInfo));
1427 #else
1428 DE_ASSERT(false);
1429 #endif // CTS_USES_VULKANSC
1430 }
1431
1432 const uint32_t numConstants = (m_data.meshShader ? 2u : 1u);
1433 const uint32_t pushConstantSize = (static_cast<uint32_t>(sizeof(deInt32)) * numConstants);
1434 const VkPushConstantRange pushConstantRange =
1435 {
1436 allShaderStages, // VkShaderStageFlags stageFlags;
1437 0u, // deUint32 offset;
1438 pushConstantSize, // deUint32 size;
1439 };
1440
1441 std::vector<VkDescriptorSetLayout> descriptorSetLayoutsRaw;
1442 descriptorSetLayoutsRaw.reserve(descriptorSetLayouts.size());
1443
1444 std::transform(begin(descriptorSetLayouts), end(descriptorSetLayouts), std::back_inserter(descriptorSetLayoutsRaw),
1445 [](const Move<VkDescriptorSetLayout>& elem) { return elem.get(); });
1446
1447 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1448 {
1449 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1450 DE_NULL, // pNext
1451 (VkPipelineLayoutCreateFlags)0,
1452 static_cast<uint32_t>(descriptorSetLayoutsRaw.size()), // setLayoutCount
1453 de::dataOrNull(descriptorSetLayoutsRaw), // pSetLayouts
1454 1u, // pushConstantRangeCount
1455 &pushConstantRange, // pPushConstantRanges
1456 };
1457
1458 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo, NULL);
1459
1460 const Unique<VkShaderModule> cs (createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
1461
1462 const VkPipelineShaderStageCreateInfo csShaderCreateInfo =
1463 {
1464 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1465 DE_NULL,
1466 (VkPipelineShaderStageCreateFlags)0,
1467 VK_SHADER_STAGE_COMPUTE_BIT, // stage
1468 *cs, // shader
1469 "main",
1470 DE_NULL, // pSpecializationInfo
1471 };
1472
1473 const VkComputePipelineCreateInfo pipelineCreateInfo =
1474 {
1475 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1476 DE_NULL,
1477 0u, // flags
1478 csShaderCreateInfo, // cs
1479 *pipelineLayout, // layout
1480 (vk::VkPipeline)0, // basePipelineHandle
1481 0u, // basePipelineIndex
1482 };
1483 Move<VkPipeline> computePipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1484
1485 for (deUint32 modeIdx = 0; modeIdx < ATTACHMENT_MODE_COUNT; ++modeIdx)
1486 {
1487 // If we're not using an attachment, don't test all the different attachment modes
1488 if (modeIdx != ATTACHMENT_MODE_DEFAULT && !m_data.useAttachment())
1489 continue;
1490
1491 // Consider all uint formats possible
1492 static const VkFormat srFillFormats[] =
1493 {
1494 VK_FORMAT_R8_UINT,
1495 VK_FORMAT_R8G8_UINT,
1496 VK_FORMAT_R8G8B8_UINT,
1497 VK_FORMAT_R8G8B8A8_UINT,
1498 VK_FORMAT_R16_UINT,
1499 VK_FORMAT_R16G16_UINT,
1500 VK_FORMAT_R16G16B16_UINT,
1501 VK_FORMAT_R16G16B16A16_UINT,
1502 VK_FORMAT_R32_UINT,
1503 VK_FORMAT_R32G32_UINT,
1504 VK_FORMAT_R32G32B32_UINT,
1505 VK_FORMAT_R32G32B32A32_UINT,
1506 VK_FORMAT_R64_UINT,
1507 VK_FORMAT_R64G64_UINT,
1508 VK_FORMAT_R64G64B64_UINT,
1509 VK_FORMAT_R64G64B64A64_UINT,
1510 };
1511 // Only test all formats in the default mode
1512 deUint32 numFillFormats = modeIdx == ATTACHMENT_MODE_DEFAULT ? (deUint32)(sizeof(srFillFormats)/sizeof(srFillFormats[0])) : 1u;
1513
1514 // Iterate over all supported tile sizes and formats
1515 for (deUint32 srTexelWidth = minFragmentShadingRateAttachmentTexelSize.width;
1516 srTexelWidth <= maxFragmentShadingRateAttachmentTexelSize.width;
1517 srTexelWidth *= 2)
1518 for (deUint32 srTexelHeight = minFragmentShadingRateAttachmentTexelSize.height;
1519 srTexelHeight <= maxFragmentShadingRateAttachmentTexelSize.height;
1520 srTexelHeight *= 2)
1521 for (deUint32 formatIdx = 0; formatIdx < numFillFormats; ++formatIdx)
1522 {
1523 deUint32 aspectRatio = (srTexelHeight > srTexelWidth) ? (srTexelHeight / srTexelWidth) : (srTexelWidth / srTexelHeight);
1524 if (aspectRatio > maxFragmentShadingRateAttachmentTexelSizeAspectRatio)
1525 continue;
1526
1527 // Go through the loop only once when not using an attachment
1528 if (!m_data.useAttachment() &&
1529 (srTexelWidth != minFragmentShadingRateAttachmentTexelSize.width ||
1530 srTexelHeight != minFragmentShadingRateAttachmentTexelSize.height ||
1531 formatIdx != 0))
1532 continue;
1533
1534 bool imagelessFB = modeIdx == ATTACHMENT_MODE_IMAGELESS;
1535
1536 deUint32 srWidth = (m_data.framebufferDim.width + srTexelWidth - 1) / srTexelWidth;
1537 deUint32 srHeight = (m_data.framebufferDim.height + srTexelHeight - 1) / srTexelHeight;
1538
1539 VkFormat srFormat = srFillFormats[formatIdx];
1540 deUint32 srFillBpp = tcu::getPixelSize(mapVkFormat(srFormat));
1541
1542 VkImageLayout srLayout = modeIdx == ATTACHMENT_MODE_LAYOUT_OPTIMAL ? VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR : VK_IMAGE_LAYOUT_GENERAL;
1543 VkImageViewType srViewType = modeIdx == ATTACHMENT_MODE_2DARRAY ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1544 VkImageTiling srTiling = (modeIdx == ATTACHMENT_MODE_TILING_LINEAR) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1545
1546 VkFormatProperties srFormatProperties;
1547 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), srFormat, &srFormatProperties);
1548 VkFormatFeatureFlags srFormatFeatures = srTiling == VK_IMAGE_TILING_LINEAR ? srFormatProperties.linearTilingFeatures : srFormatProperties.optimalTilingFeatures;
1549
1550 if (m_context.getFragmentShadingRateFeatures().attachmentFragmentShadingRate &&
1551 !(srFormatFeatures & VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR))
1552 {
1553 if (srFormat == VK_FORMAT_R8_UINT && srTiling == VK_IMAGE_TILING_OPTIMAL)
1554 {
1555 log << tcu::TestLog::Message << "VK_FORMAT_R8_UINT/VK_IMAGE_TILING_OPTIMAL don't support VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR" << tcu::TestLog::EndMessage;
1556 res = QP_TEST_RESULT_FAIL;
1557 }
1558 continue;
1559 }
1560
1561 Move<vk::VkDescriptorPool> descriptorPool;
1562 std::vector<Move<vk::VkDescriptorSet>> descriptorSets;
1563 VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1564
1565 vk::DescriptorPoolBuilder poolBuilder;
1566 for (deInt32 i = 0; i < (deInt32)(sizeof(bindings)/sizeof(bindings[0])); ++i)
1567 poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount);
1568 if (m_data.meshShader)
1569 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1570
1571 descriptorPool = poolBuilder.build(vk, device, poolCreateFlags, static_cast<uint32_t>(descriptorSetLayouts.size()));
1572 for (const auto& setLayout : descriptorSetLayouts)
1573 descriptorSets.push_back(makeDescriptorSet(vk, device, *descriptorPool, *setLayout));
1574
1575 const auto mainDescriptorSet = descriptorSets.front().get();
1576
1577 de::MovePtr<ImageWithMemory> srImage;
1578 Move<VkImageView> srImageView;
1579 VkImageUsageFlags srUsage = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
1580 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1581 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1582
1583 if (m_data.useAttachment())
1584 {
1585 const VkImageCreateInfo imageCreateInfo =
1586 {
1587 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1588 DE_NULL, // const void* pNext;
1589 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1590 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1591 srFormat, // VkFormat format;
1592 {
1593 srWidth, // deUint32 width;
1594 srHeight, // deUint32 height;
1595 1u // deUint32 depth;
1596 }, // VkExtent3D extent;
1597 1u, // deUint32 mipLevels;
1598 numSRLayers, // deUint32 arrayLayers;
1599 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1600 srTiling, // VkImageTiling tiling;
1601 srUsage, // VkImageUsageFlags usage;
1602 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1603 0u, // deUint32 queueFamilyIndexCount;
1604 DE_NULL, // const deUint32* pQueueFamilyIndices;
1605 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1606 };
1607 srImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(
1608 vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1609
1610 VkImageViewCreateInfo imageViewCreateInfo =
1611 {
1612 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1613 DE_NULL, // const void* pNext;
1614 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
1615 **srImage, // VkImage image;
1616 srViewType, // VkImageViewType viewType;
1617 srFormat, // VkFormat format;
1618 {
1619 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r;
1620 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g;
1621 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b;
1622 VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a;
1623 }, // VkComponentMapping components;
1624 {
1625 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1626 0u, // deUint32 baseMipLevel;
1627 1u, // deUint32 levelCount;
1628 0u, // deUint32 baseArrayLayer;
1629 srViewType == VK_IMAGE_VIEW_TYPE_2D ?
1630 1 : numSRLayers, // deUint32 layerCount;
1631 } // VkImageSubresourceRange subresourceRange;
1632 };
1633 srImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
1634 }
1635
1636 VkDescriptorImageInfo imageInfo;
1637 VkDescriptorBufferInfo bufferInfo;
1638
1639 VkWriteDescriptorSet w =
1640 {
1641 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1642 DE_NULL, // pNext
1643 descriptorSets.front().get(), // dstSet
1644 (deUint32)0, // dstBinding
1645 0, // dstArrayElement
1646 1u, // descriptorCount
1647 bindings[0].descriptorType, // descriptorType
1648 &imageInfo, // pImageInfo
1649 &bufferInfo, // pBufferInfo
1650 DE_NULL, // pTexelBufferView
1651 };
1652
1653 abuf[0] = 0;
1654 flushAlloc(vk, device, atomicBuffer->getAllocation());
1655
1656 bufferInfo = makeDescriptorBufferInfo(**atomicBuffer, 0, atomicBufferSize);
1657 w.dstBinding = 0;
1658 w.descriptorType = bindings[0].descriptorType;
1659 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1660
1661 imageInfo = makeDescriptorImageInfo(DE_NULL, *cbImageView, VK_IMAGE_LAYOUT_GENERAL);
1662 w.dstBinding = 1;
1663 w.descriptorType = bindings[1].descriptorType;
1664 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1665
1666 bufferInfo = makeDescriptorBufferInfo(**colorOutputBuffer, 0, colorOutputBufferSize);
1667 w.dstBinding = 2;
1668 w.descriptorType = bindings[2].descriptorType;
1669 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1670
1671 imageInfo = makeDescriptorImageInfo(*sampler, *derivImageView, VK_IMAGE_LAYOUT_GENERAL);
1672 w.dstBinding = 3;
1673 w.descriptorType = bindings[3].descriptorType;
1674 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1675
1676 if (m_data.useDepthStencil)
1677 {
1678 bufferInfo = makeDescriptorBufferInfo(**depthOutputBuffer, 0, depthOutputBufferSize);
1679 w.dstBinding = 4;
1680 w.descriptorType = bindings[4].descriptorType;
1681 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1682
1683 bufferInfo = makeDescriptorBufferInfo(**stencilOutputBuffer, 0, stencilOutputBufferSize);
1684 w.dstBinding = 5;
1685 w.descriptorType = bindings[5].descriptorType;
1686 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1687
1688 imageInfo = makeDescriptorImageInfo(DE_NULL, *dImageView, VK_IMAGE_LAYOUT_GENERAL);
1689 w.dstBinding = 6;
1690 w.descriptorType = bindings[6].descriptorType;
1691 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1692
1693 imageInfo = makeDescriptorImageInfo(DE_NULL, *sImageView, VK_IMAGE_LAYOUT_GENERAL);
1694 w.dstBinding = 7;
1695 w.descriptorType = bindings[7].descriptorType;
1696 vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1697 }
1698
1699 // Update vertex buffer descriptor.
1700 if (m_data.meshShader)
1701 {
1702 const auto extraBufferInfo = makeDescriptorBufferInfo(vertexBuffer->get(), 0ull, vertexBufferSize);
1703 const VkWriteDescriptorSet extraWrite =
1704 {
1705 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1706 DE_NULL, // pNext
1707 descriptorSets.back().get(), // dstSet
1708 (deUint32)0, // dstBinding
1709 0, // dstArrayElement
1710 1u, // descriptorCount
1711 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1712 nullptr, // pImageInfo
1713 &extraBufferInfo, // pBufferInfo
1714 DE_NULL, // pTexelBufferView
1715 };
1716
1717 vk.updateDescriptorSets(device, 1u, &extraWrite, 0u, nullptr);
1718 }
1719
1720 Move<VkRenderPass> renderPass;
1721 Move<VkFramebuffer> framebuffer;
1722
1723 std::vector<VkImageView> attachments;
1724 attachments.push_back(*cbImageView);
1725 deUint32 dsAttachmentIdx = 0, srAttachmentIdx = 0;
1726 if (m_data.useAttachment())
1727 {
1728 srAttachmentIdx = (deUint32)attachments.size();
1729 attachments.push_back(*srImageView);
1730 }
1731 if (m_data.useDepthStencil)
1732 {
1733 dsAttachmentIdx = (deUint32)attachments.size();
1734 attachments.push_back(*dsImageView);
1735 }
1736
1737 if (!m_data.groupParams->useDynamicRendering)
1738 {
1739 const vk::VkAttachmentReference2 colorAttachmentReference
1740 {
1741 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1742 DE_NULL, // pNext
1743 0, // attachment
1744 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1745 0, // aspectMask
1746 };
1747
1748 const vk::VkAttachmentReference2 fragmentShadingRateAttachment =
1749 {
1750 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1751 DE_NULL, // pNext
1752 srAttachmentIdx, // attachment
1753 srLayout, // layout
1754 0, // aspectMask
1755 };
1756
1757 const vk::VkAttachmentReference2 depthAttachmentReference =
1758 {
1759 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // sType
1760 DE_NULL, // pNext
1761 dsAttachmentIdx, // attachment
1762 vk::VK_IMAGE_LAYOUT_GENERAL, // layout
1763 0, // aspectMask
1764 };
1765
1766 const bool noAttachmentPtr = (m_data.attachmentUsage == AttachmentUsage::NO_ATTACHMENT_PTR);
1767 const VkFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo =
1768 {
1769 VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1770 DE_NULL, // const void* pNext;
1771 (noAttachmentPtr ? nullptr : &fragmentShadingRateAttachment), // const VkAttachmentReference2* pFragmentShadingRateAttachment;
1772 { srTexelWidth, srTexelHeight }, // VkExtent2D shadingRateAttachmentTexelSize;
1773 };
1774
1775 const bool useAttachmentInfo = (m_data.attachmentUsage != AttachmentUsage::NO_ATTACHMENT);
1776 const VkSubpassDescription2 subpassDesc =
1777 {
1778 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // sType
1779 (useAttachmentInfo ? &shadingRateAttachmentInfo : nullptr), // pNext;
1780 (vk::VkSubpassDescriptionFlags)0, // flags
1781 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1782 m_data.multiView ? 0x3 : 0u, // viewMask
1783 0u, // inputCount
1784 DE_NULL, // pInputAttachments
1785 1, // colorCount
1786 &colorAttachmentReference, // pColorAttachments
1787 DE_NULL, // pResolveAttachments
1788 m_data.useDepthStencil ? &depthAttachmentReference : DE_NULL, // depthStencilAttachment
1789 0u, // preserveCount
1790 DE_NULL, // pPreserveAttachments
1791 };
1792
1793 std::vector<VkAttachmentDescription2> attachmentDescriptions
1794 {
1795 {
1796 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1797 DE_NULL, // const void* pNext;
1798 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1799 cbFormat, // VkFormat format;
1800 m_data.samples, // VkSampleCountFlagBits samples;
1801 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1802 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1803 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1804 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1805 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1806 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1807 }
1808 };
1809 if (m_data.useAttachment())
1810 attachmentDescriptions.push_back(
1811 {
1812 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1813 DE_NULL, // const void* pNext;
1814 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1815 srFormat, // VkFormat format;
1816 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1817 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1818 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1819 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
1820 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
1821 srLayout, // VkImageLayout initialLayout;
1822 srLayout // VkImageLayout finalLayout;
1823 }
1824 );
1825
1826 if (m_data.useDepthStencil)
1827 attachmentDescriptions.push_back(
1828 {
1829 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1830 DE_NULL, // const void* pNext;
1831 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
1832 dsFormat, // VkFormat format;
1833 m_data.samples, // VkSampleCountFlagBits samples;
1834 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1835 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1836 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp stencilLoadOp;
1837 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1838 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout;
1839 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout;
1840 }
1841 );
1842
1843 const deUint32 correlatedViewMask = 0x3;
1844 const VkRenderPassCreateInfo2 renderPassParams =
1845 {
1846 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // sType
1847 DE_NULL, // pNext
1848 (vk::VkRenderPassCreateFlags)0,
1849 (deUint32)attachmentDescriptions.size(), // attachmentCount
1850 &attachmentDescriptions[0], // pAttachments
1851 1u, // subpassCount
1852 &subpassDesc, // pSubpasses
1853 0u, // dependencyCount
1854 DE_NULL, // pDependencies
1855 m_data.correlationMask, // correlatedViewMaskCount
1856 m_data.correlationMask ? &correlatedViewMask : DE_NULL // pCorrelatedViewMasks
1857 };
1858
1859 renderPass = createRenderPass2(vk, device, &renderPassParams);
1860
1861 std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfo;
1862 framebufferAttachmentImageInfo.push_back(
1863 {
1864 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1865 DE_NULL, // const void* pNext;
1866 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1867 cbUsage, // VkImageUsageFlags usage;
1868 m_data.framebufferDim.width, // deUint32 width;
1869 m_data.framebufferDim.height, // deUint32 height;
1870 m_data.numColorLayers, // deUint32 layerCount;
1871 1u, // deUint32 viewFormatCount;
1872 &cbFormat // const VkFormat* pViewFormats;
1873 }
1874 );
1875 if (m_data.useAttachment())
1876 framebufferAttachmentImageInfo.push_back(
1877 {
1878 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1879 DE_NULL, // const void* pNext;
1880 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1881 srUsage, // VkImageUsageFlags usage;
1882 srWidth, // deUint32 width;
1883 srHeight, // deUint32 height;
1884 srViewType == VK_IMAGE_VIEW_TYPE_2D ? 1 : numSRLayers, // deUint32 layerCount;
1885 1u, // deUint32 viewFormatCount;
1886 &srFormat // const VkFormat* pViewFormats;
1887 }
1888 );
1889
1890 if (m_data.useDepthStencil)
1891 framebufferAttachmentImageInfo.push_back(
1892 {
1893 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, // VkStructureType sType;
1894 DE_NULL, // const void* pNext;
1895 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
1896 dsUsage, // VkImageUsageFlags usage;
1897 m_data.framebufferDim.width, // deUint32 width;
1898 m_data.framebufferDim.height, // deUint32 height;
1899 m_data.numColorLayers, // deUint32 layerCount;
1900 1u, // deUint32 viewFormatCount;
1901 &dsFormat // const VkFormat* pViewFormats;
1902 }
1903 );
1904
1905 const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo =
1906 {
1907 VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, // VkStructureType sType;
1908 DE_NULL, // const void* pNext;
1909 (deUint32)framebufferAttachmentImageInfo.size(), // deUint32 attachmentImageInfoCount;
1910 &framebufferAttachmentImageInfo[0] // const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
1911 };
1912
1913 const vk::VkFramebufferCreateInfo framebufferParams =
1914 {
1915 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
1916 imagelessFB ? &framebufferAttachmentsCreateInfo : DE_NULL, // pNext
1917 (vk::VkFramebufferCreateFlags)(imagelessFB ? VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT : 0),
1918 *renderPass, // renderPass
1919 (deUint32)attachments.size(), // attachmentCount
1920 imagelessFB ? DE_NULL : &attachments[0], // pAttachments
1921 m_data.framebufferDim.width, // width
1922 m_data.framebufferDim.height, // height
1923 m_data.multiView ? 1 : m_data.numColorLayers, // layers
1924 };
1925
1926 framebuffer = createFramebuffer(vk, device, &framebufferParams);
1927 }
1928
1929 const VkVertexInputBindingDescription vertexBinding =
1930 {
1931 0u, // deUint32 binding;
1932 sizeof(float) * 2, // deUint32 stride;
1933 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
1934 };
1935 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1936 {
1937 0u, // deUint32 location;
1938 0u, // deUint32 binding;
1939 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1940 0u // deUint32 offset;
1941 };
1942
1943 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
1944 {
1945 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1946 DE_NULL, // const void* pNext;
1947 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1948 1u, // deUint32 vertexBindingDescriptionCount;
1949 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1950 1u, // deUint32 vertexAttributeDescriptionCount;
1951 &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1952 };
1953
1954 const VkPipelineRasterizationConservativeStateCreateInfoEXT consRastState =
1955 {
1956 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1957 DE_NULL, // const void* pNext;
1958 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
1959 m_data.conservativeMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
1960 0.0f, // float extraPrimitiveOverestimationSize;
1961 };
1962
1963 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
1964 {
1965 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1966 m_data.conservativeEnable ? &consRastState : DE_NULL, // const void* pNext;
1967 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1968 VK_FALSE, // VkBool32 depthClampEnable;
1969 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1970 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1971 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1972 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1973 VK_FALSE, // VkBool32 depthBiasEnable;
1974 0.0f, // float depthBiasConstantFactor;
1975 0.0f, // float depthBiasClamp;
1976 0.0f, // float depthBiasSlopeFactor;
1977 1.0f // float lineWidth;
1978 };
1979
1980 // Kill some bits from each AA mode
1981 const VkSampleMask sampleMask = m_data.sampleMaskTest ? 0x9 : 0x7D56;
1982 const VkSampleMask* pSampleMask = m_data.useApiSampleMask ? &sampleMask : DE_NULL;
1983
1984 // All samples at pixel center. We'll validate that pixels are fully covered or uncovered.
1985 std::vector<VkSampleLocationEXT> sampleLocations(m_data.samples, { 0.5f, 0.5f });
1986 const VkSampleLocationsInfoEXT sampleLocationsInfo =
1987 {
1988 VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
1989 DE_NULL, // const void* pNext;
1990 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits sampleLocationsPerPixel;
1991 { 1, 1 }, // VkExtent2D sampleLocationGridSize;
1992 (deUint32)m_data.samples, // uint32_t sampleLocationsCount;
1993 &sampleLocations[0], // const VkSampleLocationEXT* pSampleLocations;
1994 };
1995
1996 const VkPipelineSampleLocationsStateCreateInfoEXT pipelineSampleLocationsCreateInfo =
1997 {
1998 VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1999 DE_NULL, // const void* pNext;
2000 VK_TRUE, // VkBool32 sampleLocationsEnable;
2001 sampleLocationsInfo, // VkSampleLocationsInfoEXT sampleLocationsInfo;
2002 };
2003
2004 const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
2005 {
2006 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
2007 m_data.sampleLocations ? &pipelineSampleLocationsCreateInfo : DE_NULL, // const void* pNext
2008 0u, // VkPipelineMultisampleStateCreateFlags flags
2009 (VkSampleCountFlagBits)m_data.samples, // VkSampleCountFlagBits rasterizationSamples
2010 (VkBool32)m_data.sampleShadingEnable, // VkBool32 sampleShadingEnable
2011 1.0f, // float minSampleShading
2012 pSampleMask, // const VkSampleMask* pSampleMask
2013 VK_FALSE, // VkBool32 alphaToCoverageEnable
2014 VK_FALSE // VkBool32 alphaToOneEnable
2015 };
2016
2017 std::vector<VkViewport> viewports;
2018 std::vector<VkRect2D> scissors;
2019 if (m_data.multiViewport)
2020 {
2021 // Split the viewport into left and right halves
2022 int x0 = 0, x1 = m_data.framebufferDim.width/2, x2 = m_data.framebufferDim.width;
2023
2024 viewports.push_back(makeViewport((float)x0, 0, std::max((float)(x1 - x0), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
2025 scissors.push_back(makeRect2D(x0, 0, x1 - x0, m_data.framebufferDim.height));
2026
2027 viewports.push_back(makeViewport((float)x1, 0, std::max((float)(x2 - x1), 1.0f), (float)m_data.framebufferDim.height, 0.0f, 1.0f));
2028 scissors.push_back(makeRect2D(x1, 0, x2 - x1, m_data.framebufferDim.height));
2029 }
2030 else
2031 {
2032 viewports.push_back(makeViewport(m_data.framebufferDim.width, m_data.framebufferDim.height));
2033 scissors.push_back(makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height));
2034 }
2035
2036 const auto& binaries = m_context.getBinaryCollection();
2037 Move<VkShaderModule> fragShader = createShaderModule(vk, device, binaries.get("frag"), 0);
2038 Move<VkShaderModule> vertShader;
2039 Move<VkShaderModule> geomShader;
2040 Move<VkShaderModule> meshShader;
2041
2042 if (m_data.meshShader)
2043 {
2044 meshShader = createShaderModule(vk, device, binaries.get("mesh"), 0);
2045 }
2046 else
2047 {
2048 if (m_context.contextSupports(VK_API_VERSION_1_2))
2049 vertShader = createShaderModule(vk, device, binaries.get("vert_1_2"), 0);
2050 else
2051 vertShader = createShaderModule(vk, device, binaries.get("vert"), 0);
2052
2053 if (m_data.geometryShader)
2054 geomShader = createShaderModule(vk, device, binaries.get("geom"), 0);
2055 }
2056
2057 const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 1;
2058
2059 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
2060 #ifndef CTS_USES_VULKANSC
2061 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
2062 {
2063 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2064 DE_NULL,
2065 m_data.multiView ? 0x3 : 0u,
2066 1u,
2067 &cbFormat,
2068 dsFormat,
2069 dsFormat
2070 };
2071 renderingCreateInfoWrapper.ptr = m_data.groupParams->useDynamicRendering ? &renderingCreateInfo : DE_NULL;
2072 #endif // CTS_USES_VULKANSC
2073
2074 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo
2075 {
2076 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
2077 renderingCreateInfoWrapper.ptr, // const void* pNext;
2078 { fragSizeWH, fragSizeWH }, // VkExtent2D fragmentSize;
2079 { m_data.combinerOp[0], m_data.combinerOp[1] }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
2080 };
2081
2082 VkDynamicState dynamicState = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR;
2083 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo
2084 {
2085 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
2086 DE_NULL, // const void* pNext;
2087 (VkPipelineDynamicStateCreateFlags)0, // VkPipelineDynamicStateCreateFlags flags;
2088 m_data.useDynamicState ? 1u : 0u, // uint32_t dynamicStateCount;
2089 &dynamicState, // const VkDynamicState* pDynamicStates;
2090 };
2091
2092 // Enable depth/stencil writes, always passing
2093 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams
2094 {
2095 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
2096 DE_NULL, // const void* pNext;
2097 0u, // VkPipelineDepthStencilStateCreateFlags flags;
2098 VK_TRUE, // VkBool32 depthTestEnable;
2099 VK_TRUE, // VkBool32 depthWriteEnable;
2100 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
2101 VK_FALSE, // VkBool32 depthBoundsTestEnable;
2102 VK_TRUE, // VkBool32 stencilTestEnable;
2103 // VkStencilOpState front;
2104 {
2105 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
2106 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
2107 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
2108 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
2109 0u, // deUint32 compareMask;
2110 0xFFu, // deUint32 writeMask;
2111 0xFFu, // deUint32 reference;
2112 },
2113 // VkStencilOpState back;
2114 {
2115 VK_STENCIL_OP_REPLACE, // VkStencilOp failOp;
2116 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
2117 VK_STENCIL_OP_REPLACE, // VkStencilOp depthFailOp;
2118 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
2119 0u, // deUint32 compareMask;
2120 0xFFu, // deUint32 writeMask;
2121 0xFFu, // deUint32 reference;
2122 },
2123 0.0f, // float minDepthBounds;
2124 0.0f, // float maxDepthBounds;
2125 };
2126
2127 const VkQueue queue = m_context.getUniversalQueue();
2128 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
2129 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2130 Move<VkCommandBuffer> secCmdBuffer;
2131 VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
2132 VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
2133
2134 std::vector<GraphicsPipelineWrapper> pipelines;
2135 pipelines.reserve(m_data.useDynamicState ? 1u : NUM_TRIANGLES);
2136
2137 std::vector<VkDescriptorSet> descriptorSetsRaw;
2138
2139 descriptorSetsRaw.reserve(descriptorSets.size());
2140
2141 std::transform(begin(descriptorSets), end(descriptorSets), std::back_inserter(descriptorSetsRaw),
2142 [](const Move<VkDescriptorSet>& elem) { return elem.get(); });
2143
2144 #ifndef CTS_USES_VULKANSC
2145 const VkExtent2D srTexelSize { srTexelWidth, srTexelHeight };
2146 if (m_data.groupParams->useSecondaryCmdBuffer)
2147 {
2148 secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2149
2150 // record secondary command buffer
2151 if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2152 {
2153 beginSecondaryCmdBuffer(*secCmdBuffer, cbFormat, dsFormat, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
2154 beginDynamicRender(*secCmdBuffer, *srImageView, srLayout, srTexelSize, *cbImageView, *dsImageView,
2155 clearColor, clearDepthStencil);
2156 }
2157 else
2158 beginSecondaryCmdBuffer(*secCmdBuffer, cbFormat, dsFormat);
2159
2160 drawCommands(*secCmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
2161 &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
2162 &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
2163 renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
2164
2165 if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2166 endRendering(vk, *secCmdBuffer);
2167
2168 endCommandBuffer(vk, *secCmdBuffer);
2169
2170 // record primary command buffer
2171 beginCommandBuffer(vk, *cmdBuffer, 0u);
2172
2173 preRenderCommands(*cmdBuffer, cbImage.get(), dsImage.get(), derivImage.get(), derivNumLevels, srImage.get(), srLayout,
2174 srFillBuffer.get(), numSRLayers, srWidth, srHeight, srFillBpp, clearColor, clearDepthStencil);
2175 if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2176 beginDynamicRender(*cmdBuffer, *srImageView, srLayout, srTexelSize, *cbImageView, *dsImageView,
2177 clearColor, clearDepthStencil, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR);
2178
2179 vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
2180
2181 if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2182 endRendering(vk, *cmdBuffer);
2183 }
2184 else if (m_data.groupParams->useDynamicRendering)
2185 {
2186 beginCommandBuffer(vk, *cmdBuffer);
2187 preRenderCommands(*cmdBuffer, cbImage.get(), dsImage.get(), derivImage.get(), derivNumLevels, srImage.get(), srLayout,
2188 srFillBuffer.get(), numSRLayers, srWidth, srHeight, srFillBpp, clearColor, clearDepthStencil);
2189 beginDynamicRender(*cmdBuffer, *srImageView, srLayout, srTexelSize, *cbImageView, *dsImageView, clearColor, clearDepthStencil);
2190 drawCommands(*cmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
2191 &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
2192 &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
2193 renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
2194 endRendering(vk, *cmdBuffer);
2195 }
2196 #endif // CTS_USES_VULKANSC
2197
2198 if (!m_data.groupParams->useDynamicRendering)
2199 {
2200 beginCommandBuffer(vk, *cmdBuffer);
2201 preRenderCommands(*cmdBuffer, cbImage.get(), dsImage.get(), derivImage.get(), derivNumLevels, srImage.get(), srLayout,
2202 srFillBuffer.get(), numSRLayers, srWidth, srHeight, srFillBpp, clearColor, clearDepthStencil);
2203 beginLegacyRender(*cmdBuffer, *renderPass, *framebuffer, *srImageView, *cbImageView, *dsImageView, imagelessFB);
2204 drawCommands(*cmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
2205 &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
2206 &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
2207 renderingCreateInfoWrapper, *vertShader, *geomShader, *meshShader, *fragShader, descriptorSetsRaw, **vertexBuffer, pushConstantSize);
2208 endRenderPass(vk, *cmdBuffer);
2209 }
2210
2211 VkMemoryBarrier memBarrier
2212 {
2213 VK_STRUCTURE_TYPE_MEMORY_BARRIER,
2214 DE_NULL,
2215 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2216 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT
2217 };
2218 vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2219
2220 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &mainDescriptorSet, 0u, DE_NULL);
2221 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
2222
2223 // Copy color/depth/stencil buffers to buffer memory
2224 vk.cmdDispatch(*cmdBuffer, m_data.framebufferDim.width, m_data.framebufferDim.height, m_data.numColorLayers);
2225
2226 memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2227 memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
2228 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2229 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2230
2231 endCommandBuffer(vk, *cmdBuffer);
2232
2233 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
2234
2235 deUint32 *colorptr = (deUint32 *)colorOutputBuffer->getAllocation().getHostPtr();
2236 invalidateAlloc(vk, device, colorOutputBuffer->getAllocation());
2237
2238 invalidateAlloc(vk, device, atomicBuffer->getAllocation());
2239
2240 float *depthptr = DE_NULL;
2241 deUint32 *stencilptr = DE_NULL;
2242
2243 if (m_data.useDepthStencil)
2244 {
2245 depthptr = (float *)depthOutputBuffer->getAllocation().getHostPtr();
2246 invalidateAlloc(vk, device, depthOutputBuffer->getAllocation());
2247
2248 stencilptr = (deUint32 *)stencilOutputBuffer->getAllocation().getHostPtr();
2249 invalidateAlloc(vk, device, stencilOutputBuffer->getAllocation());
2250 }
2251
2252 // Loop over all samples and validate the output
2253 for (deUint32 layer = 0; layer < m_data.numColorLayers && res == QP_TEST_RESULT_PASS; ++layer)
2254 {
2255 for (deUint32 y = 0; y < m_data.framebufferDim.height && res == QP_TEST_RESULT_PASS; ++y)
2256 {
2257 for (deUint32 x = 0; x < m_data.framebufferDim.width && res == QP_TEST_RESULT_PASS; ++x)
2258 {
2259 for (deInt32 s = 0; s < m_data.samples && res == QP_TEST_RESULT_PASS; ++s)
2260 {
2261 deUint32 *sample = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2262
2263 // If testing the rasterizer sample mask, if this sample is not set in the
2264 // mask then it shouldn't have written anything.
2265 if (m_data.useApiSampleMask && !(sampleMask & (1 << s)) && sample[2] != 0)
2266 {
2267 log << tcu::TestLog::Message << std::hex << "sample written despite pSampleMask (" << x << "," << y << ",sample " << s << ")" << tcu::TestLog::EndMessage;
2268 res = QP_TEST_RESULT_FAIL;
2269 continue;
2270 }
2271
2272 // The same isn't covered by any primitives, skip it
2273 if (sample[2] == 0)
2274 continue;
2275
2276 // skip samples that have the same value as sample zero - it would be redundant to check them.
2277 if (s > 0)
2278 {
2279 deUint32 *sample0 = &colorptr[4*(((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0)];
2280 bool same = deMemCmp(sample, sample0, 16) == 0;
2281
2282 if (m_data.fragDepth)
2283 {
2284 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2285 float *dsample0 = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2286 same = same && (*dsample == *dsample0);
2287 }
2288
2289 if (m_data.fragStencil)
2290 {
2291 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2292 deUint32 *ssample0 = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + 0];
2293 same = same && (*ssample == *ssample0);
2294 }
2295
2296 if (same)
2297 continue;
2298 }
2299
2300 // Fragment shader writes error codes to .w component.
2301 // All nonzero values are unconditionally failures
2302 if (sample[3] != 0)
2303 {
2304 if (sample[3] == ERROR_FRAGCOORD_CENTER)
2305 log << tcu::TestLog::Message << std::hex << "fragcoord test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2306 else if (sample[3] == ERROR_VTG_READBACK)
2307 log << tcu::TestLog::Message << std::hex << "vs/gs output readback test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2308 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_DERIV)
2309 log << tcu::TestLog::Message << std::hex << "fragcoord derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2310 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2311 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2312 else if ((sample[3] & 0xFF) == ERROR_FRAGCOORD_IMPLICIT_DERIV)
2313 log << tcu::TestLog::Message << std::hex << "implicit derivative test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")="
2314 "(0x" << ((sample[3] >> 8) & 0x3F) << ",0x" << ((sample[3] >> 14) & 0x3F) << "), expected="
2315 "(0x" << ((sample[3] >> 20) & 0x3F) << ",0x" << ((sample[3] >> 26) & 0x3F) << ")" << tcu::TestLog::EndMessage;
2316 else
2317 log << tcu::TestLog::Message << std::hex << "w coord unknown test failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")" << tcu::TestLog::EndMessage;
2318 res = QP_TEST_RESULT_FAIL;
2319 continue;
2320 }
2321
2322 // x component of sample
2323 deUint32 rate = sample[0];
2324 // fragment size
2325 deUint32 pixelsX = 1 << ((rate/4)&3);
2326 deUint32 pixelsY = 1 << (rate&3);
2327
2328 // Fragment region
2329 deUint32 fragMinX = x & ~(pixelsX-1);
2330 deUint32 fragMinY = y & ~(pixelsY-1);
2331 deUint32 fragMaxX = fragMinX + pixelsX;
2332 deUint32 fragMaxY = fragMinY + pixelsY;
2333
2334 // Clamp to FB dimension for odd sizes
2335 if (fragMaxX > m_data.framebufferDim.width)
2336 fragMaxX = m_data.framebufferDim.width;
2337 if (fragMaxY > m_data.framebufferDim.height)
2338 fragMaxY = m_data.framebufferDim.height;
2339
2340 // z component of sample
2341 deUint32 primID = sample[2] >> 24;
2342 deUint32 atomVal = sample[2] & 0xFFFFFF;
2343
2344 // Compute pipeline and primitive rate from primitive ID, and attachment
2345 // rate from the x/y coordinate
2346 deInt32 pipelineRate = PrimIDToPipelineShadingRate(primID);
2347 deInt32 primitiveRate = m_data.shaderWritesRate ? PrimIDToPrimitiveShadingRate(primID) : 0;
2348
2349 deInt32 attachmentLayer = (m_data.srLayered && modeIdx == ATTACHMENT_MODE_2DARRAY) ? layer : 0;
2350 deInt32 attachmentRate = m_data.useAttachment() ? fillPtr[srFillBpp*((attachmentLayer * srHeight + (y / srTexelHeight)) * srWidth + (x / srTexelWidth))] : 0;
2351
2352 // Get mask of allowed shading rates
2353 deInt32 expectedMasks = Simulate(pipelineRate, primitiveRate, attachmentRate);
2354
2355 if (!(expectedMasks & (1 << rate)))
2356 {
2357 log << tcu::TestLog::Message << std::hex << "unexpected shading rate. failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ") "
2358 "result rate 0x" << rate << " mask of expected rates 0x" << expectedMasks <<
2359 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate << tcu::TestLog::EndMessage;
2360 res = QP_TEST_RESULT_FAIL;
2361 continue;
2362 }
2363 // Check that not all fragments are downgraded to 1x1
2364 if (rate == 0 && expectedMasks != 1)
2365 numUnexpected1x1Samples++;
2366 numTotalSamples++;
2367
2368 // Check that gl_FragDepth = primID / NUM_TRIANGLES
2369 if (m_data.fragDepth)
2370 {
2371 float *dsample = &depthptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2372 float expected = (float)primID / NUM_TRIANGLES;
2373 if (fabs(*dsample - expected) > 0.01)
2374 {
2375 log << tcu::TestLog::Message << std::hex << "depth write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *dsample << " expected " << expected << tcu::TestLog::EndMessage;
2376 res = QP_TEST_RESULT_FAIL;
2377 continue;
2378 }
2379 }
2380
2381 // Check that stencil value = primID
2382 if (m_data.fragStencil)
2383 {
2384 deUint32 *ssample = &stencilptr[((layer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s];
2385 if (*ssample != primID)
2386 {
2387 log << tcu::TestLog::Message << std::hex << "stencil write failed pixel (0x" << x << ",0x" << y << ",sample 0x" << s << ")=" << *ssample << " expected " << primID << tcu::TestLog::EndMessage;
2388 res = QP_TEST_RESULT_FAIL;
2389 continue;
2390 }
2391 }
2392
2393 // Check that primitives are in the right viewport/scissor
2394 if (m_data.multiViewport)
2395 {
2396 VkRect2D *scissor = &scissors[primID & 1];
2397 if ((int)x < scissor->offset.x || (int)x >= (int)(scissor->offset.x + scissor->extent.width) ||
2398 (int)y < scissor->offset.y || (int)y >= (int)(scissor->offset.y + scissor->extent.height))
2399 {
2400 log << tcu::TestLog::Message << std::hex << "primitive found outside of expected viewport (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << tcu::TestLog::EndMessage;
2401 res = QP_TEST_RESULT_FAIL;
2402 continue;
2403 }
2404 }
2405
2406 // Check that primitives are in the right layer
2407 if (m_data.colorLayered)
2408 {
2409 if (layer != ((primID & 2)>>1))
2410 {
2411 log << tcu::TestLog::Message << std::hex << "primitive found in wrong layer (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " layer=" << layer << tcu::TestLog::EndMessage;
2412 res = QP_TEST_RESULT_FAIL;
2413 continue;
2414 }
2415 }
2416
2417 // Check that multiview broadcasts the same primitive to both layers
2418 if (m_data.multiView)
2419 {
2420 deUint32 otherLayer = layer^1;
2421 deUint32 *othersample = &colorptr[4*(((otherLayer * m_data.framebufferDim.height + y) * m_data.framebufferDim.width + x)*m_data.samples + s)];
2422 deUint32 otherPrimID = othersample[2] >> 24;
2423 if (primID != otherPrimID)
2424 {
2425 log << tcu::TestLog::Message << std::hex << "multiview primitive mismatch (0x" << x << ",0x" << y << ",sample 0x" << s << ") primID=" << primID << " otherPrimID=" << otherPrimID << tcu::TestLog::EndMessage;
2426 res = QP_TEST_RESULT_FAIL;
2427 continue;
2428 }
2429 }
2430
2431 // Loop over all samples in the same fragment
2432 for (deUint32 fx = fragMinX; fx < fragMaxX; ++fx)
2433 {
2434 for (deUint32 fy = fragMinY; fy < fragMaxY; ++fy)
2435 {
2436 for (deInt32 fs = 0; fs < m_data.samples; ++fs)
2437 {
2438 deUint32 *fsample = &colorptr[4*(((layer * m_data.framebufferDim.height + fy) * m_data.framebufferDim.width + fx)*m_data.samples + fs)];
2439 deUint32 frate = fsample[0];
2440 deUint32 fprimID = fsample[2] >> 24;
2441 deUint32 fatomVal = fsample[2] & 0xFFFFFF;
2442
2443 // If we write out the sample mask value, check that the samples in the
2444 // mask must not be uncovered, and that samples not in the mask must not
2445 // be covered by this primitive
2446 if (m_data.useSampleMaskIn)
2447 {
2448 int p = pixelsX * pixelsY - ((fx - fragMinX) + pixelsX * (fy - fragMinY)) - 1;
2449 int sampleIdx = fs + m_data.samples * p;
2450
2451 if ((sample[1] & (1 << sampleIdx)) && fsample[2] == 0)
2452 {
2453 log << tcu::TestLog::Message << std::hex << "sample set in sampleMask but not written (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2454 res = QP_TEST_RESULT_FAIL;
2455 continue;
2456 }
2457 if (!(sample[1] & (1 << sampleIdx)) && fsample[2] != 0 && fprimID == primID)
2458 {
2459 log << tcu::TestLog::Message << std::hex << "sample not set in sampleMask but written with same primID (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2460 res = QP_TEST_RESULT_FAIL;
2461 continue;
2462 }
2463 }
2464
2465 // If conservative raster is enabled, or custom sample locations all at the center, check that
2466 // samples in the same pixel must be covered.
2467 if (m_data.conservativeEnable ||
2468 (m_data.sampleLocations && m_context.getFragmentShadingRateProperties().fragmentShadingRateWithCustomSampleLocations))
2469 {
2470 // If it's in the same pixel, expect it to be fully covered.
2471 if (fx == x && fy == y && fsample[2] == 0)
2472 {
2473 log << tcu::TestLog::Message << std::hex << "pixel not fully covered (0x" << fx << ",0x" << fy << ",sample 0x" << fs << ")" << tcu::TestLog::EndMessage;
2474 res = QP_TEST_RESULT_FAIL;
2475 continue;
2476 }
2477 }
2478
2479 if (fsample[2] == 0)
2480 continue;
2481
2482 // If the primitive matches this sample, then it must have the same rate and
2483 // atomic value
2484 if (fprimID == primID)
2485 {
2486 if (rate != frate || (atomVal != fatomVal && !(m_data.sampleShadingEnable || m_data.sampleShadingInput)))
2487 {
2488 log << tcu::TestLog::Message << std::hex << "failed pixel (0x" << x << ",0x" << y << ",sample " << s << ")=0x" << ((primID<<24)|atomVal) <<
2489 " compared to (0x" << fx << ",0x" << fy << ",sample " << fs << ")=0x" << ((fprimID<<24)|fatomVal) <<
2490 " pipelineRate=0x" << pipelineRate << " primitiveRate=0x" << primitiveRate << " attachmentRate =0x" << attachmentRate <<
2491 tcu::TestLog::EndMessage;
2492 res = QP_TEST_RESULT_FAIL;
2493 }
2494 }
2495 }
2496 }
2497 }
2498 }
2499 }
2500 }
2501 }
2502 if (res == QP_TEST_RESULT_FAIL)
2503 break;
2504 }
2505 }
2506 // All samples were coerced to 1x1, unexpected
2507 if (res == QP_TEST_RESULT_PASS &&
2508 numTotalSamples != 0 &&
2509 numUnexpected1x1Samples == numTotalSamples &&
2510 numTotalSamples > 16)
2511 {
2512 log << tcu::TestLog::Message << std::hex << "Quality warning - all fragments used 1x1" << tcu::TestLog::EndMessage;
2513 res = QP_TEST_RESULT_QUALITY_WARNING;
2514 }
2515
2516 return tcu::TestStatus(res, qpGetTestResultName(res));
2517 }
2518
2519 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer,VkFormat cbFormat,VkFormat dsFormat,VkRenderingFlagsKHR renderingFlags) const2520 void FSRTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat cbFormat, VkFormat dsFormat, VkRenderingFlagsKHR renderingFlags) const
2521 {
2522 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
2523 {
2524 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
2525 DE_NULL, // const void* pNext;
2526 renderingFlags, // VkRenderingFlagsKHR flags;
2527 m_data.multiView ? 0x3 : 0u, // uint32_t viewMask;
2528 1u, // uint32_t colorAttachmentCount;
2529 &cbFormat, // const VkFormat* pColorAttachmentFormats;
2530 dsFormat, // VkFormat depthAttachmentFormat;
2531 dsFormat, // VkFormat stencilAttachmentFormat;
2532 m_data.samples, // VkSampleCountFlagBits rasterizationSamples;
2533 };
2534 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
2535
2536 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2537 if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2538 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2539
2540 const VkCommandBufferBeginInfo commandBufBeginParams
2541 {
2542 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2543 DE_NULL, // const void* pNext;
2544 usageFlags, // VkCommandBufferUsageFlags flags;
2545 &bufferInheritanceInfo
2546 };
2547
2548 const DeviceInterface& vk = m_context.getDeviceInterface();
2549 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
2550 }
2551
beginDynamicRender(VkCommandBuffer cmdBuffer,VkImageView srImageView,VkImageLayout srImageLayout,const VkExtent2D & srTexelSize,VkImageView cbImageView,VkImageView dsImageView,const VkClearValue & clearColor,const VkClearValue & clearDepthStencil,VkRenderingFlagsKHR renderingFlags) const2552 void FSRTestInstance::beginDynamicRender(VkCommandBuffer cmdBuffer, VkImageView srImageView, VkImageLayout srImageLayout,
2553 const VkExtent2D& srTexelSize, VkImageView cbImageView, VkImageView dsImageView,
2554 const VkClearValue& clearColor, const VkClearValue& clearDepthStencil,
2555 VkRenderingFlagsKHR renderingFlags) const
2556 {
2557 const DeviceInterface& vk = m_context.getDeviceInterface();
2558 VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
2559
2560 VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
2561 {
2562 VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2563 DE_NULL, // const void* pNext;
2564 m_data.useAttachment() ? srImageView : DE_NULL, // VkImageView imageView;
2565 srImageLayout, // VkImageLayout imageLayout;
2566 srTexelSize // VkExtent2D shadingRateAttachmentTexelSize;
2567 };
2568
2569 VkRenderingAttachmentInfoKHR colorAttachment
2570 {
2571 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2572 DE_NULL, // const void* pNext;
2573 cbImageView, // VkImageView imageView;
2574 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2575 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2576 DE_NULL, // VkImageView resolveImageView;
2577 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2578 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2579 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2580 clearColor // VkClearValue clearValue;
2581 };
2582
2583 std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
2584 {
2585 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
2586 DE_NULL, // const void* pNext;
2587 dsImageView, // VkImageView imageView;
2588 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
2589 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
2590 DE_NULL, // VkImageView resolveImageView;
2591 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
2592 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
2593 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2594 clearDepthStencil // VkClearValue clearValue;
2595 });
2596
2597 vk::VkRenderingInfoKHR renderingInfo
2598 {
2599 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2600 m_data.useAttachment() || m_data.useAttachmentWithoutImageView() ? &shadingRateAttachmentInfo : DE_NULL,
2601 renderingFlags, // VkRenderingFlagsKHR flags;
2602 renderArea, // VkRect2D renderArea;
2603 m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
2604 m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
2605 1u, // deUint32 colorAttachmentCount;
2606 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
2607 m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
2608 m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
2609 };
2610
2611 vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
2612 }
2613 #endif // CTS_USES_VULKANSC
2614
preRenderCommands(VkCommandBuffer cmdBuffer,ImageWithMemory * cbImage,ImageWithMemory * dsImage,ImageWithMemory * derivImage,deUint32 derivNumLevels,ImageWithMemory * srImage,VkImageLayout srLayout,BufferWithMemory * srFillBuffer,deUint32 numSRLayers,deUint32 srWidth,deUint32 srHeight,deUint32 srFillBpp,const VkClearValue & clearColor,const VkClearValue & clearDepthStencil)2615 void FSRTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer, ImageWithMemory* cbImage, ImageWithMemory* dsImage,
2616 ImageWithMemory* derivImage, deUint32 derivNumLevels,
2617 ImageWithMemory* srImage, VkImageLayout srLayout, BufferWithMemory* srFillBuffer,
2618 deUint32 numSRLayers, deUint32 srWidth, deUint32 srHeight, deUint32 srFillBpp,
2619 const VkClearValue& clearColor, const VkClearValue& clearDepthStencil)
2620 {
2621 const DeviceInterface& vk = m_context.getDeviceInterface();
2622 const VkDevice device = m_context.getDevice();
2623
2624 VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
2625 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
2626 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
2627 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
2628 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
2629 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
2630 VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
2631
2632 if (m_data.geometryShader)
2633 allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
2634
2635 VkImageMemoryBarrier imageBarrier
2636 {
2637 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
2638 DE_NULL, // const void* pNext
2639 0u, // VkAccessFlags srcAccessMask
2640 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
2641 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
2642 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
2643 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
2644 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
2645 cbImage->get(), // VkImage image
2646 {
2647 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
2648 0u, // uint32_t baseMipLevel
2649 VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
2650 0u, // uint32_t baseArray
2651 VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
2652 }
2653 };
2654
2655 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2656 (VkDependencyFlags)0,
2657 0, (const VkMemoryBarrier*)DE_NULL,
2658 0, (const VkBufferMemoryBarrier*)DE_NULL,
2659 1, &imageBarrier);
2660
2661 imageBarrier.image = derivImage->get();
2662 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2663
2664 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2665 (VkDependencyFlags)0,
2666 0, (const VkMemoryBarrier*)DE_NULL,
2667 0, (const VkBufferMemoryBarrier*)DE_NULL,
2668 1, &imageBarrier);
2669
2670 // Clear level to 1<<level
2671 for (deUint32 i = 0; i < derivNumLevels; ++i)
2672 {
2673 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
2674 VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
2675 vk.cmdClearColorImage(cmdBuffer, derivImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
2676 }
2677
2678 // Clear color buffer to transparent black
2679 {
2680 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
2681 vk.cmdClearColorImage(cmdBuffer, cbImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
2682 }
2683
2684 // Clear depth and stencil
2685 if (m_data.useDepthStencil)
2686 {
2687 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
2688 VkImageMemoryBarrier dsBarrier = imageBarrier;
2689 dsBarrier.image = dsImage->get();
2690 dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2691 dsBarrier.subresourceRange = range;
2692 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2693 0u, // dependencyFlags
2694 0u, nullptr,
2695 0u, nullptr,
2696 1u, &dsBarrier);
2697 vk.cmdClearDepthStencilImage(cmdBuffer, dsImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
2698 }
2699
2700 // Initialize shading rate image with varying values
2701 if (m_data.useAttachment())
2702 {
2703 imageBarrier.image = srImage->get();
2704 imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2705
2706 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2707 (VkDependencyFlags)0,
2708 0, (const VkMemoryBarrier*)DE_NULL,
2709 0, (const VkBufferMemoryBarrier*)DE_NULL,
2710 1, &imageBarrier);
2711
2712 deUint8 *fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
2713 for (deUint32 layer = 0; layer < numSRLayers; ++layer)
2714 {
2715 for (deUint32 x = 0; x < srWidth; ++x)
2716 {
2717 for (deUint32 y = 0; y < srHeight; ++y)
2718 {
2719 deUint32 idx = (layer*srHeight + y)*srWidth + x;
2720 deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
2721 // actual shading rate is always in the LSBs of the first byte of a texel
2722 fillPtr[srFillBpp*idx] = val;
2723 }
2724 }
2725 }
2726 flushAlloc(vk, device, srFillBuffer->getAllocation());
2727
2728 const VkBufferImageCopy copyRegion
2729 {
2730 0u, // VkDeviceSize bufferOffset;
2731 0u, // deUint32 bufferRowLength;
2732 0u, // deUint32 bufferImageHeight;
2733 {
2734 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
2735 0u, // deUint32 mipLevel;
2736 0u, // deUint32 baseArrayLayer;
2737 numSRLayers, // deUint32 layerCount;
2738 }, // VkImageSubresourceLayers imageSubresource;
2739 { 0, 0, 0 }, // VkOffset3D imageOffset;
2740 { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
2741 };
2742
2743 vk.cmdCopyBufferToImage(cmdBuffer, srFillBuffer->get(), srImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
2744
2745 imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2746 imageBarrier.newLayout = srLayout;
2747
2748 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2749 (VkDependencyFlags)0,
2750 0, (const VkMemoryBarrier*)DE_NULL,
2751 0, (const VkBufferMemoryBarrier*)DE_NULL,
2752 1, &imageBarrier);
2753 }
2754
2755 VkMemoryBarrier memBarrier
2756 {
2757 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
2758 DE_NULL, // pNext
2759 0u, // srcAccessMask
2760 0u, // dstAccessMask
2761 };
2762
2763 memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
2764 memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
2765 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
2766 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
2767 }
2768
beginLegacyRender(VkCommandBuffer cmdBuffer,VkRenderPass renderPass,VkFramebuffer framebuffer,VkImageView srImageView,VkImageView cbImageView,VkImageView dsImageView,bool imagelessFB) const2769 void FSRTestInstance::beginLegacyRender(VkCommandBuffer cmdBuffer, VkRenderPass renderPass, VkFramebuffer framebuffer,
2770 VkImageView srImageView, VkImageView cbImageView, VkImageView dsImageView, bool imagelessFB) const
2771 {
2772 const DeviceInterface& vk = m_context.getDeviceInterface();
2773 VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
2774
2775 std::vector<VkImageView> attachments = { cbImageView };
2776 if (m_data.useAttachment())
2777 attachments.push_back(srImageView);
2778 if (m_data.useDepthStencil)
2779 attachments.push_back(dsImageView);
2780
2781 const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2782 {
2783 VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
2784 DE_NULL, // const void* pNext;
2785 (deUint32)attachments.size(), // deUint32 attachmentCount;
2786 &attachments[0] // const VkImageView* pAttachments;
2787 };
2788
2789 beginRenderPass(vk, cmdBuffer, renderPass, framebuffer, renderArea,
2790 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
2791 }
2792
drawCommands(VkCommandBuffer cmdBuffer,std::vector<GraphicsPipelineWrapper> & pipelines,const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineDynamicStateCreateInfo * dynamicState,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const VkPipelineMultisampleStateCreateInfo * multisampleState,VkPipelineFragmentShadingRateStateCreateInfoKHR * shadingRateState,PipelineRenderingCreateInfoWrapper dynamicRenderingState,const VkShaderModule vertShader,const VkShaderModule geomShader,const VkShaderModule meshShader,const VkShaderModule fragShader,const std::vector<VkDescriptorSet> & descriptorSets,VkBuffer vertexBuffer,const uint32_t pushConstantSize)2793 void FSRTestInstance::drawCommands(VkCommandBuffer cmdBuffer,
2794 std::vector<GraphicsPipelineWrapper>& pipelines,
2795 const std::vector<VkViewport>& viewports,
2796 const std::vector<VkRect2D>& scissors,
2797 const VkPipelineLayout pipelineLayout,
2798 const VkRenderPass renderPass,
2799 const VkPipelineVertexInputStateCreateInfo* vertexInputState,
2800 const VkPipelineDynamicStateCreateInfo* dynamicState,
2801 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
2802 const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
2803 const VkPipelineMultisampleStateCreateInfo* multisampleState,
2804 VkPipelineFragmentShadingRateStateCreateInfoKHR* shadingRateState,
2805 PipelineRenderingCreateInfoWrapper dynamicRenderingState,
2806 const VkShaderModule vertShader,
2807 const VkShaderModule geomShader,
2808 const VkShaderModule meshShader,
2809 const VkShaderModule fragShader,
2810 const std::vector<VkDescriptorSet>& descriptorSets,
2811 VkBuffer vertexBuffer,
2812 const uint32_t pushConstantSize)
2813 {
2814 const DeviceInterface& vk = m_context.getDeviceInterface();
2815 const VkDevice device = m_context.getDevice();
2816 const bool useMesh = (meshShader != DE_NULL);
2817
2818 #ifdef CTS_USES_VULKANSC
2819 if (useMesh)
2820 DE_ASSERT(false);
2821 #endif // CTS_USES_VULKANSC
2822
2823 VkFlags allShaderStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
2824
2825 if (useMesh)
2826 {
2827 #ifndef CTS_USES_VULKANSC
2828 allShaderStages |= VK_SHADER_STAGE_MESH_BIT_EXT;
2829 #endif // CTS_USES_VULKANSC
2830 }
2831 else
2832 {
2833 allShaderStages |= VK_SHADER_STAGE_VERTEX_BIT;
2834 if (m_data.geometryShader)
2835 allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
2836 }
2837
2838 VkPipelineCreateFlags pipelineCreateFlags = (VkPipelineCreateFlags)0;
2839
2840 #ifndef CTS_USES_VULKANSC
2841 if (m_data.groupParams->useDynamicRendering)
2842 pipelineCreateFlags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
2843 #endif // CTS_USES_VULKANSC
2844
2845 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, static_cast<uint32_t>(descriptorSets.size()), de::dataOrNull(descriptorSets), 0, DE_NULL);
2846
2847 PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo = dynamicRenderingState;
2848 #ifndef CTS_USES_VULKANSC
2849 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfoWithGarbage;
2850 std::vector<VkFormat> garbageFormats;
2851
2852 if (m_data.garbageAttachment)
2853 {
2854 for (int i = 0; i < 10; i++)
2855 garbageFormats.push_back(VK_FORMAT_UNDEFINED);
2856
2857 pipelineRenderingCreateInfoWithGarbage = *dynamicRenderingState.ptr;
2858 // Just set a bunch of VK_FORMAT_UNDEFINED for garbage_color_attachment tests to make the validation happy.
2859 pipelineRenderingCreateInfoWithGarbage.colorAttachmentCount = static_cast<uint32_t>(garbageFormats.size());
2860 pipelineRenderingCreateInfoWithGarbage.pColorAttachmentFormats = garbageFormats.data();
2861 pipelineRenderingCreateInfo = &pipelineRenderingCreateInfoWithGarbage;
2862 }
2863 #endif
2864
2865 // If using dynamic state, create a single graphics pipeline and bind it
2866 if (m_data.useDynamicState)
2867 {
2868 pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
2869 auto& pipeline = pipelines.back();
2870
2871 pipeline
2872 .setDefaultColorBlendState()
2873 .setDynamicState(dynamicState);
2874
2875 if (useMesh)
2876 {
2877 #ifndef CTS_USES_VULKANSC
2878 pipeline
2879 .setupPreRasterizationMeshShaderState(viewports,
2880 scissors,
2881 pipelineLayout,
2882 renderPass,
2883 0u,
2884 DE_NULL,
2885 meshShader,
2886 rasterizationState,
2887 nullptr,
2888 nullptr,
2889 shadingRateState,
2890 pipelineRenderingCreateInfo);
2891 #endif // CTS_USES_VULKANSC
2892 }
2893 else
2894 {
2895 pipeline
2896 .setupVertexInputState(vertexInputState)
2897 .setupPreRasterizationShaderState(viewports,
2898 scissors,
2899 pipelineLayout,
2900 renderPass,
2901 0u,
2902 vertShader,
2903 rasterizationState,
2904 DE_NULL,
2905 DE_NULL,
2906 geomShader,
2907 DE_NULL,
2908 shadingRateState,
2909 pipelineRenderingCreateInfo);
2910 }
2911
2912 pipeline
2913 .setupFragmentShaderState(pipelineLayout,
2914 renderPass,
2915 0u,
2916 fragShader,
2917 depthStencilState,
2918 multisampleState)
2919 .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
2920 .setMonolithicPipelineLayout(pipelineLayout)
2921 .buildPipeline();
2922
2923 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
2924 }
2925
2926 // Push constant block (must match shaders).
2927 struct
2928 {
2929 int32_t shadingRate;
2930 uint32_t instanceIndex;
2931 } pushConstantBlock;
2932
2933 for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
2934 {
2935 if (!useMesh)
2936 {
2937 // Bind vertex attributes pointing to the next triangle
2938 VkDeviceSize vertexBufferOffset = i * 3 * 2 * sizeof(float);
2939 vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
2940 }
2941
2942 // Put primitive shading rate and instance index (used in mesh shading cases) in push constants.
2943 pushConstantBlock.shadingRate = PrimIDToPrimitiveShadingRate(i);
2944 pushConstantBlock.instanceIndex = static_cast<uint32_t>(i);
2945 vk.cmdPushConstants(cmdBuffer, pipelineLayout, allShaderStages, 0, pushConstantSize, &pushConstantBlock);
2946
2947 if (m_data.useDynamicState)
2948 {
2949 VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2950 vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, m_data.combinerOp);
2951 }
2952 else
2953 {
2954 // Create a new pipeline with the desired pipeline shading rate
2955 shadingRateState->fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
2956
2957 pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
2958 auto& pipeline = pipelines.back();
2959
2960 pipeline
2961 .setDefaultColorBlendState()
2962 .setDynamicState(dynamicState);
2963
2964 if (useMesh)
2965 {
2966 #ifndef CTS_USES_VULKANSC
2967 pipeline
2968 .setupPreRasterizationMeshShaderState(viewports,
2969 scissors,
2970 pipelineLayout,
2971 renderPass,
2972 0u,
2973 DE_NULL,
2974 meshShader,
2975 rasterizationState,
2976 nullptr,
2977 nullptr,
2978 shadingRateState,
2979 dynamicRenderingState);
2980 #endif // CTS_USES_VULKANSC
2981 }
2982 else
2983 {
2984 pipeline
2985 .setupVertexInputState(vertexInputState)
2986 .setupPreRasterizationShaderState(viewports,
2987 scissors,
2988 pipelineLayout,
2989 renderPass,
2990 0u,
2991 vertShader,
2992 rasterizationState,
2993 DE_NULL,
2994 DE_NULL,
2995 geomShader,
2996 DE_NULL,
2997 shadingRateState,
2998 dynamicRenderingState);
2999 }
3000
3001 pipeline
3002 .setupFragmentShaderState(pipelineLayout,
3003 renderPass,
3004 0u,
3005 fragShader,
3006 depthStencilState,
3007 multisampleState)
3008 #ifndef CTS_USES_VULKANSC
3009 .setRenderingColorAttachmentsInfo(dynamicRenderingState)
3010 #endif
3011 .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
3012 .setMonolithicPipelineLayout(pipelineLayout)
3013 .buildPipeline();
3014
3015 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
3016 }
3017
3018 if (useMesh)
3019 {
3020 #ifndef CTS_USES_VULKANSC
3021 // Create a single workgroup to draw one triangle. The "primitive id" will be in the push constants.
3022 vk.cmdDrawMeshTasksEXT(cmdBuffer, 1u, 1u, 1u);
3023 #endif // CTS_USES_VULKANSC
3024 }
3025 else
3026 {
3027 // Draw one triangle, with "primitive ID" in gl_InstanceIndex
3028 vk.cmdDraw(cmdBuffer, 3u, 1, 0u, i);
3029 }
3030 }
3031 }
3032
3033 } // anonymous
3034
createBasicTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * parentGroup,SharedGroupParams groupParams)3035 void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, SharedGroupParams groupParams)
3036 {
3037 typedef struct
3038 {
3039 deUint32 count;
3040 const char* name;
3041 const char* description;
3042 } TestGroupCase;
3043
3044 typedef struct
3045 {
3046 VkExtent2D count;
3047 const char* name;
3048 const char* description;
3049 } TestGroupCase2D;
3050
3051 typedef struct
3052 {
3053 AttachmentUsage usage;
3054 const char* name;
3055 const char* description;
3056 } TestGroupUsageCase;
3057
3058 TestGroupCase groupCases[] =
3059 {
3060 { 0, "basic", "basic tests" },
3061 { 1, "apisamplemask", "use pSampleMask" },
3062 { 2, "samplemaskin", "use gl_SampleMaskIn" },
3063 { 3, "conservativeunder", "conservative underestimation" },
3064 { 4, "conservativeover", "conservative overestimation" },
3065 { 5, "fragdepth", "depth shader output" },
3066 { 6, "fragstencil", "stencil shader output" },
3067 { 7, "multiviewport", "multiple viewports and gl_ViewportIndex" },
3068 { 8, "colorlayered", "multiple layer color, single layer shading rate" },
3069 { 9, "srlayered", "multiple layer color, multiple layers shading rate" },
3070 { 10, "multiview", "multiview" },
3071 { 11, "multiviewsrlayered", "multiview and multilayer shading rate" },
3072 { 12, "multiviewcorrelation", "multiview with correlation mask" },
3073 { 13, "interlock", "fragment shader interlock" },
3074 { 14, "samplelocations", "custom sample locations" },
3075 { 15, "sampleshadingenable", "enable sample shading in createinfo" },
3076 { 16, "sampleshadinginput", "enable sample shading by using gl_SampleID" },
3077 #ifndef CTS_USES_VULKANSC
3078 { 17, "fragdepth_early_late", "depth shader output" },
3079 { 18, "fragstencil_early_late", "stencil shader output" },
3080 #endif
3081 };
3082
3083 TestGroupCase dynCases[] =
3084 {
3085 { 1, "dynamic", "uses dynamic shading rate state" },
3086 { 0, "static", "uses static shading rate state" },
3087 };
3088
3089 TestGroupUsageCase attCases[] =
3090 {
3091 { AttachmentUsage::NO_ATTACHMENT, "noattachment", "no shading rate attachment" },
3092 { AttachmentUsage::WITH_ATTACHMENT, "attachment", "has shading rate attachment" },
3093 { AttachmentUsage::NO_ATTACHMENT_PTR, "noattachmentptr", "no shading rate attachment pointer" },
3094 { AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW, "attachment_noimageview", "has shading rate attachment without imageview" },
3095 };
3096
3097 TestGroupCase shdCases[] =
3098 {
3099 { 0, "noshaderrate", "shader doesn't write rate" },
3100 { 1, "shaderrate", "shader writes rate" },
3101 };
3102
3103 TestGroupCase combCases[] =
3104 {
3105 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, "keep", "keep" },
3106 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR, "replace", "replace" },
3107 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, "min", "min" },
3108 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, "max", "max" },
3109 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, "mul", "mul" },
3110 };
3111
3112 TestGroupCase2D extentCases[] =
3113 {
3114 { {1, 1}, "1x1", "1x1" },
3115 { {4, 4}, "4x4", "4x4" },
3116 { {33, 35}, "33x35", "33x35" },
3117 { {151, 431}, "151x431", "151x431" },
3118 { {256, 256}, "256x256", "256x256" },
3119 };
3120
3121 TestGroupCase sampCases[] =
3122 {
3123 { VK_SAMPLE_COUNT_1_BIT, "samples1", "1 raster sample" },
3124 { VK_SAMPLE_COUNT_2_BIT, "samples2", "2 raster samples" },
3125 { VK_SAMPLE_COUNT_4_BIT, "samples4", "4 raster samples" },
3126 { VK_SAMPLE_COUNT_8_BIT, "samples8", "8 raster samples" },
3127 { VK_SAMPLE_COUNT_16_BIT, "samples16", "16 raster samples" },
3128 };
3129
3130 TestGroupCase shaderCases[] =
3131 {
3132 { 0, "vs", "vertex shader only" },
3133 { 1, "gs", "vertex and geometry shader" },
3134 #ifndef CTS_USES_VULKANSC
3135 { 2, "ms", "mesh shader" },
3136 #endif // CTS_USES_VULKANSC
3137 };
3138
3139 deInt32 seed = 0;
3140
3141 for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupCases); groupNdx++)
3142 {
3143 if (groupParams->useDynamicRendering && groupNdx == 12)
3144 continue;
3145
3146 if (groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
3147 {
3148 // for graphics pipeline library we need to repeat only selected groups
3149 if (std::set<int> { 2, 3, 4, 10, 11, 12, 13, 14, 15 }.count(groupNdx) == 0)
3150 continue;
3151 }
3152
3153 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, groupCases[groupNdx].name, groupCases[groupNdx].description));
3154 for (int dynNdx = 0; dynNdx < DE_LENGTH_OF_ARRAY(dynCases); dynNdx++)
3155 {
3156 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
3157 if (groupParams->useSecondaryCmdBuffer && (dynNdx != 0))
3158 continue;
3159
3160 de::MovePtr<tcu::TestCaseGroup> dynGroup(new tcu::TestCaseGroup(testCtx, dynCases[dynNdx].name, dynCases[dynNdx].description));
3161 for (int attNdx = 0; attNdx < DE_LENGTH_OF_ARRAY(attCases); attNdx++)
3162 {
3163 if (groupParams->useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
3164 continue;
3165
3166 // WITH_ATTACHMENT_WITHOUT_IMAGEVIEW is only for VkRenderingFragmentShadingRateAttachmentInfoKHR.
3167 if (!groupParams->useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::WITH_ATTACHMENT_WITHOUT_IMAGEVIEW)
3168 continue;
3169
3170 de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
3171 for (int shdNdx = 0; shdNdx < DE_LENGTH_OF_ARRAY(shdCases); shdNdx++)
3172 {
3173 de::MovePtr<tcu::TestCaseGroup> shdGroup(new tcu::TestCaseGroup(testCtx, shdCases[shdNdx].name, shdCases[shdNdx].description));
3174 for (int cmb0Ndx = 0; cmb0Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb0Ndx++)
3175 {
3176 de::MovePtr<tcu::TestCaseGroup> cmb0Group(new tcu::TestCaseGroup(testCtx, combCases[cmb0Ndx].name, combCases[cmb0Ndx].description));
3177 for (int cmb1Ndx = 0; cmb1Ndx < DE_LENGTH_OF_ARRAY(combCases); cmb1Ndx++)
3178 {
3179 de::MovePtr<tcu::TestCaseGroup> cmb1Group(new tcu::TestCaseGroup(testCtx, combCases[cmb1Ndx].name, combCases[cmb1Ndx].description));
3180 for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
3181 {
3182 // reduce number of cases repeat every other extent case for graphics pipeline library
3183 if ((groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) && ((extNdx % 2) == 1))
3184 continue;
3185
3186 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
3187 if (groupParams->useSecondaryCmdBuffer && (extNdx != 1))
3188 continue;
3189
3190 de::MovePtr<tcu::TestCaseGroup> extGroup(new tcu::TestCaseGroup(testCtx, extentCases[extNdx].name, extentCases[extNdx].description));
3191 for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
3192 {
3193 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
3194 if (groupParams->useSecondaryCmdBuffer && (sampNdx != 1))
3195 continue;
3196
3197 de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
3198 for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(shaderCases); shaderNdx++)
3199 {
3200 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
3201 if (groupParams->useSecondaryCmdBuffer && (shaderNdx != 0))
3202 continue;
3203
3204 bool useApiSampleMask = groupNdx == 1;
3205 bool useSampleMaskIn = groupNdx == 2;
3206 bool consRast = groupNdx == 3 || groupNdx == 4;
3207 bool fragDepth = groupNdx == 5 || groupNdx == 17;
3208 bool fragStencil = groupNdx == 6 || groupNdx == 18;
3209 bool multiViewport = groupNdx == 7;
3210 bool colorLayered = groupNdx == 8 || groupNdx == 9;
3211 bool srLayered = groupNdx == 9 || groupNdx == 11;
3212 bool multiView = groupNdx == 10 || groupNdx == 11 || groupNdx == 12;
3213 bool correlationMask = groupNdx == 12;
3214 bool interlock = groupNdx == 13;
3215 bool sampleLocations = groupNdx == 14;
3216 bool sampleShadingEnable = groupNdx == 15;
3217 bool sampleShadingInput = groupNdx == 16;
3218 bool useGeometryShader = (shaderCases[shaderNdx].count == 1u);
3219 bool useMeshShader = (shaderCases[shaderNdx].count == 2u);
3220 bool earlyAndLateTest = groupNdx == 17 || groupNdx == 18;
3221
3222 VkConservativeRasterizationModeEXT conservativeMode = (groupNdx == 3) ? VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT : VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
3223 deUint32 numColorLayers = (colorLayered || multiView) ? 2u : 1u;
3224
3225 // Don't bother with geometry shader if we're not testing shader writes
3226 if (useGeometryShader && !shdCases[shdNdx].count)
3227 continue;
3228
3229 // reduce number of tests
3230 if ((groupNdx != 0) &&
3231 (!dynCases[dynNdx].count ||
3232 !(combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb0Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR) ||
3233 !(combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || combCases[cmb1Ndx].count == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR)))
3234 continue;
3235
3236 // Don't bother with geometry shader if we're testing conservative raster, sample mask, depth/stencil
3237 if (useGeometryShader && (useApiSampleMask || useSampleMaskIn || consRast || fragDepth || fragStencil))
3238 continue;
3239
3240 // Don't bother with geometry shader if we're testing non-dynamic state
3241 if (useGeometryShader && !dynCases[dynNdx].count)
3242 continue;
3243
3244 // Only test multiViewport/layered with shaderWritesRate
3245 if ((multiViewport || colorLayered) && !shdCases[shdNdx].count)
3246 continue;
3247
3248 // Can't test layered shading rate attachment without an attachment
3249 if (srLayered && attCases[attNdx].usage != AttachmentUsage::WITH_ATTACHMENT)
3250 continue;
3251
3252 CaseDef c
3253 {
3254 groupParams, // SharedGroupParams groupParams;
3255 seed++, // deInt32 seed;
3256 extentCases[extNdx].count, // VkExtent2D framebufferDim;
3257 (VkSampleCountFlagBits)sampCases[sampNdx].count, // VkSampleCountFlagBits samples;
3258 {
3259 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb0Ndx].count,
3260 (VkFragmentShadingRateCombinerOpKHR)combCases[cmb1Ndx].count
3261 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
3262 attCases[attNdx].usage, // AttachmentUsage attachmentUsage;
3263 (bool)shdCases[shdNdx].count, // bool shaderWritesRate;
3264 useGeometryShader, // bool geometryShader;
3265 useMeshShader, // bool meshShader;
3266 (bool)dynCases[dynNdx].count, // bool useDynamicState;
3267 useApiSampleMask, // bool useApiSampleMask;
3268 useSampleMaskIn, // bool useSampleMaskIn;
3269 consRast, // bool conservativeEnable;
3270 conservativeMode, // VkConservativeRasterizationModeEXT conservativeMode;
3271 fragDepth || fragStencil, // bool useDepthStencil;
3272 fragDepth, // bool fragDepth;
3273 fragStencil, // bool fragStencil;
3274 multiViewport, // bool multiViewport;
3275 colorLayered, // bool colorLayered;
3276 srLayered, // bool srLayered;
3277 numColorLayers, // deUint32 numColorLayers;
3278 multiView, // bool multiView;
3279 correlationMask, // bool correlationMask;
3280 interlock, // bool interlock;
3281 sampleLocations, // bool sampleLocations;
3282 sampleShadingEnable, // bool sampleShadingEnable;
3283 sampleShadingInput, // bool sampleShadingInput;
3284 false, // bool sampleMaskTest;
3285 earlyAndLateTest, // bool earlyAndLateTest;
3286 false, // bool garbageAttachment;
3287 };
3288
3289 sampGroup->addChild(new FSRTestCase(testCtx, shaderCases[shaderNdx].name, shaderCases[shaderNdx].description, c));
3290 }
3291 extGroup->addChild(sampGroup.release());
3292 }
3293 cmb1Group->addChild(extGroup.release());
3294 }
3295 cmb0Group->addChild(cmb1Group.release());
3296 }
3297 shdGroup->addChild(cmb0Group.release());
3298 }
3299 attGroup->addChild(shdGroup.release());
3300 }
3301 dynGroup->addChild(attGroup.release());
3302 }
3303 group->addChild(dynGroup.release());
3304 }
3305 parentGroup->addChild(group.release());
3306 }
3307
3308 {
3309 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
3310
3311 if (!groupParams->useSecondaryCmdBuffer)
3312 {
3313 group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
3314 groupParams, // SharedGroupParams groupParams;
3315 123, // deInt32 seed;
3316 {32, 33}, // VkExtent2D framebufferDim;
3317 VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
3318 {
3319 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
3320 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
3321 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
3322 AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
3323 true, // bool shaderWritesRate;
3324 false, // bool geometryShader;
3325 false, // bool meshShader;
3326 false, // bool useDynamicState;
3327 true, // bool useApiSampleMask;
3328 false, // bool useSampleMaskIn;
3329 false, // bool conservativeEnable;
3330 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
3331 false, // bool useDepthStencil;
3332 false, // bool fragDepth;
3333 false, // bool fragStencil;
3334 false, // bool multiViewport;
3335 false, // bool colorLayered;
3336 false, // bool srLayered;
3337 1u, // deUint32 numColorLayers;
3338 false, // bool multiView;
3339 false, // bool correlationMask;
3340 false, // bool interlock;
3341 false, // bool sampleLocations;
3342 false, // bool sampleShadingEnable;
3343 false, // bool sampleShadingInput;
3344 true, // bool sampleMaskTest;
3345 false, // bool earlyAndLateTest;
3346 false, // bool garbageAttachment;
3347 }));
3348 }
3349
3350 #ifndef CTS_USES_VULKANSC
3351 if (groupParams->useDynamicRendering && groupParams->pipelineConstructionType != vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
3352 {
3353 group->addChild(new FSRTestCase(testCtx, "garbage_color_attachment", "", {
3354 groupParams, // SharedGroupParams groupParams;
3355 123, // deInt32 seed;
3356 {32, 33}, // VkExtent2D framebufferDim;
3357 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3358 {
3359 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
3360 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
3361 }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
3362 AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
3363 false, // bool shaderWritesRate;
3364 false, // bool geometryShader;
3365 false, // bool meshShader;
3366 false, // bool useDynamicState;
3367 false, // bool useApiSampleMask;
3368 false, // bool useSampleMaskIn;
3369 false, // bool conservativeEnable;
3370 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
3371 false, // bool useDepthStencil;
3372 false, // bool fragDepth;
3373 false, // bool fragStencil;
3374 false, // bool multiViewport;
3375 false, // bool colorLayered;
3376 false, // bool srLayered;
3377 1u, // deUint32 numColorLayers;
3378 false, // bool multiView;
3379 false, // bool correlationMask;
3380 false, // bool interlock;
3381 false, // bool sampleLocations;
3382 false, // bool sampleShadingEnable;
3383 false, // bool sampleShadingInput;
3384 false, // bool sampleMaskTest;
3385 false, // bool earlyAndLateTest;
3386 true, // bool garbageAttachment;
3387 }));
3388 }
3389 #endif // CTS_USES_VULKANSC
3390
3391 parentGroup->addChild(group.release());
3392 }
3393 }
3394
3395 } // FragmentShadingRage
3396 } // vkt
3397