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