1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2022,2023 The Khronos Group Inc.
6 * Copyright (c) 2022,2023 Valve Corporation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file vktDrawSampleAttributeTests.cpp
22 * \brief Tests for the sample interpolation attribute
23 *//*--------------------------------------------------------------------*/
24
25 #include "tcuStringTemplate.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkTypeUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vktDrawBaseClass.hpp"
31 #include "vktTestGroupUtil.hpp"
32 #include "tcuVectorUtil.hpp"
33
34 #include "vkPipelineConstructionUtil.hpp"
35 #include "vktTestGroupUtil.hpp"
36
37 #include "vkDefs.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "vkImageUtil.hpp"
40 #include "deStringUtil.hpp"
41 #include "vktTestCaseUtil.hpp"
42 #include "vkTypeUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkObjUtil.hpp"
45 #include "vkImageWithMemory.hpp"
46 #include "vkBarrierUtil.hpp"
47 #include "vkBufferWithMemory.hpp"
48 #include "vkBuilderUtil.hpp"
49
50 namespace vkt
51 {
52 namespace Draw
53 {
54 namespace
55 {
56
57 using namespace vk;
58
59 enum class Trigger
60 {
61 SAMPLE_ID_STATIC_USE = 0,
62 SAMPLE_POSITION_STATIC_USE,
63 SAMPLE_DECORATION_DYNAMIC_USE,
64 };
65
66 struct TestParameters
67 {
68 const SharedGroupParams general;
69
70 // Test case variant on the fragment shader.
71 Trigger trigger;
72 };
73
74 /*
75 * Test that sample interpolation correctly enables sample shading at a rate of 1.0
76 */
77 class SampleShadingSampleAttributeTestCase : public vkt::TestCase
78 {
79 public:
80 SampleShadingSampleAttributeTestCase (tcu::TestContext& context, const std::string& name, const TestParameters& params);
81 void initPrograms (SourceCollections& programCollection) const override;
82 TestInstance* createInstance (Context& context) const override;
83 void checkSupport (Context& context) const override;
84
85 private:
86 const TestParameters m_params;
87 };
88
89 class SampleShadingSampleAttributeTestInstance : public vkt::TestInstance
90 {
91 public:
92 SampleShadingSampleAttributeTestInstance (Context& context, const TestParameters& params);
93 tcu::TestStatus iterate (void) override;
94
95 private:
96 const TestParameters m_params;
97
98 static constexpr uint32_t width = 4u;
99 static constexpr uint32_t height = 4u;
100 static constexpr VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
101 static constexpr uint32_t expectedCounter = sampleCount * width * height;
102 };
103
SampleShadingSampleAttributeTestCase(tcu::TestContext & context,const std::string & name,const TestParameters & params)104 SampleShadingSampleAttributeTestCase::SampleShadingSampleAttributeTestCase(tcu::TestContext& context, const std::string& name, const TestParameters& params):
105 vkt::TestCase(context, name), m_params(params) { }
106
checkSupport(Context & context) const107 void SampleShadingSampleAttributeTestCase::checkSupport(Context& context) const
108 {
109 if (m_params.general->useDynamicRendering)
110 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
111 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS);
112 }
113
initPrograms(SourceCollections & collection) const114 void SampleShadingSampleAttributeTestCase::initPrograms(SourceCollections& collection) const
115 {
116 const bool sampleFragInput = (m_params.trigger == Trigger::SAMPLE_DECORATION_DYNAMIC_USE);
117 const bool declareSampleId = (m_params.trigger == Trigger::SAMPLE_ID_STATIC_USE);
118 const bool declareSamplePosition = (m_params.trigger == Trigger::SAMPLE_POSITION_STATIC_USE);
119
120 {
121 std::ostringstream src;
122 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
123 << "vec2 positions[3] = vec2[](\n"
124 << " vec2(-1.0, -1.0),\n"
125 << " vec2(3.0, -1.0),\n"
126 << " vec2(-1.0, 3.0)\n"
127 << ");\n"
128 << (sampleFragInput ? "layout (location = 0) out float verify;\n" : "")
129 << "void main() {\n"
130 << " const uint triIdx = gl_VertexIndex / 3u;\n" // In practice this will always be zero.
131 << " const uint triVertIdx = gl_VertexIndex % 3u;\n"
132 << " gl_Position = vec4(positions[triVertIdx], 0.0, 1.0);\n"
133 << (sampleFragInput ? " verify = float(triIdx) + float(triVertIdx) / 16.0 + 0.75;\n" : "") // In practice a number between 0.75 and 1.0.
134 << "}\n";
135 collection.glslSources.add("vert") << glu::VertexSource(src.str());
136 }
137
138 {
139 std::ostringstream src;
140 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
141 << "layout (location = 0) out vec4 outColor;\n"
142 << (sampleFragInput ? "layout (location = 0) sample in float verify;\n" : "")
143 << "layout (std430, binding = 0) buffer Output {\n"
144 << " uint invocationCount;\n"
145 << "} buf;\n"
146 << "void main() {\n"
147 << (declareSampleId ? " gl_SampleID;\n" : "")
148 << (declareSamplePosition ? " gl_SamplePosition;\n" : "")
149 << " uint one = " << (sampleFragInput ? "uint(ceil(verify))" : "1") << ";\n"
150 << " uint index = atomicAdd(buf.invocationCount, one);\n"
151 << " outColor = vec4(float(one), 1.0, 0.0, 1.0);\n"
152 << "}\n";
153 collection.glslSources.add("frag") << glu::FragmentSource(src.str());
154 }
155 }
156
createInstance(Context & context) const157 TestInstance* SampleShadingSampleAttributeTestCase::createInstance(Context& context) const
158 {
159 return new SampleShadingSampleAttributeTestInstance(context, m_params);
160 }
161
SampleShadingSampleAttributeTestInstance(Context & context,const TestParameters & params)162 SampleShadingSampleAttributeTestInstance::SampleShadingSampleAttributeTestInstance(Context& context, const TestParameters& params) : vkt::TestInstance(context), m_params(params) { }
163
iterate(void)164 tcu::TestStatus SampleShadingSampleAttributeTestInstance::iterate(void)
165 {
166 const auto ctx = m_context.getContextCommonData();
167
168 // Verification buffer.
169 const auto bufferSize = static_cast<VkDeviceSize>(sizeof(uint32_t));
170 BufferWithMemory buffer (ctx.vkd, ctx.device, ctx.allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
171 auto& bufferAlloc = buffer.getAllocation();
172 void* bufferData = bufferAlloc.getHostPtr();
173
174 deMemset(bufferData, 0, static_cast<size_t>(bufferSize));
175 flushAlloc(ctx.vkd, ctx.device, bufferAlloc);
176
177 // Color attachment.
178 const auto imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
179 const auto imageExtent = makeExtent3D(width, height, 1u);
180
181 const std::vector<VkViewport> viewports { makeViewport(imageExtent) };
182 const std::vector<VkRect2D> scissors { makeRect2D(imageExtent) };
183
184 const auto subresourceRange = makeDefaultImageSubresourceRange();
185 const auto imageUsage = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
186
187 const VkImageCreateInfo imageCreateInfo =
188 {
189 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
190 nullptr, // const void* pNext;
191 0u, // VkImageCreateFlags flags;
192 VK_IMAGE_TYPE_2D, // VkImageType imageType;
193 imageFormat, // VkFormat format;
194 imageExtent, // VkExtent3D extent;
195 1u, // deUint32 mipLevels;
196 1u, // deUint32 arrayLayers;
197 sampleCount, // VkSampleCountFlagBits samples;
198 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
199 imageUsage, // VkImageUsageFlags usage;
200 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
201 0u, // deUint32 queueFamilyIndexCount;
202 nullptr, // const deUint32* pQueueFamilyIndices;
203 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
204 };
205
206 ImageWithMemory colorAttachment (ctx.vkd, ctx.device, ctx.allocator, imageCreateInfo, MemoryRequirement::Any);
207 const auto colorAttachmentView = makeImageView(ctx.vkd, ctx.device, colorAttachment.get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
208
209 // Structures used for renderpasses and dynamic rendering.
210 RenderPassCreateInfo renderPassCreateInfo;
211
212 const VkAttachmentReference colorAttachmentReference =
213 {
214 0,
215 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
216 };
217
218 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
219 sampleCount,
220 VK_ATTACHMENT_LOAD_OP_CLEAR,
221 VK_ATTACHMENT_STORE_OP_STORE,
222 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
223 VK_ATTACHMENT_STORE_OP_DONT_CARE,
224 VK_IMAGE_LAYOUT_UNDEFINED,
225 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
226
227 renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
228 0,
229 0,
230 nullptr,
231 1,
232 &colorAttachmentReference,
233 nullptr,
234 AttachmentReference(),
235 0,
236 nullptr));
237
238 // Render pass and framebuffer.
239 const auto renderPass = createRenderPass(ctx.vkd, ctx.device, &renderPassCreateInfo);
240 const auto framebuffer = makeFramebuffer(ctx.vkd, ctx.device, renderPass.get(), colorAttachmentView.get(), imageExtent.width, imageExtent.height);
241 const auto clearValueColor = makeClearValueColor(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
242
243 #ifndef CTS_USES_VULKANSC
244 const VkRenderingAttachmentInfoKHR colorAttachments =
245 {
246 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
247 nullptr, // const void* pNext;
248 colorAttachmentView.get(), // VkImageView imageView;
249 VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, // VkImageLayout imageLayout;
250 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
251 VK_NULL_HANDLE, // VkImageView resolveImageView;
252 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout resolveImageLayout;
253 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
254 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
255 clearValueColor // VkClearValue clearValue;
256 };
257
258 const auto renderInfoFlags = (
259 (m_params.general->useDynamicRendering
260 && !m_params.general->secondaryCmdBufferCompletelyContainsDynamicRenderpass
261 && m_params.general->useSecondaryCmdBuffer)
262 ? static_cast<VkRenderingFlags>(VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT)
263 : 0u);
264
265 const VkRenderingInfoKHR renderInfo =
266 {
267 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, // VkStructureType sType;
268 0, // const void* pNext;
269 renderInfoFlags, // VkRenderingFlags flags;
270 scissors.at(0), // VkRect2D renderArea;
271 1, // uint32_t layerCount;
272 0, // uint32_t viewMask;
273 1, // uint32_t colorAttachmentCount;
274 &colorAttachments, // const VkRenderingAttachmentInfo* pColorAttachments;
275 VK_NULL_HANDLE, // const VkRenderingAttachmentInfo* pDepthAttachment;
276 VK_NULL_HANDLE // const VkRenderingAttachmentInfo* pStencilAttachment;
277 };
278
279 const VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
280 {
281 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
282 nullptr, // const void* pNext;
283 0, // VkRenderingFlagsKHR flags;
284 0u, // uint32_t viewMask;
285 1u, // uint32_t colorAttachmentCount;
286 &imageFormat, // const VkFormat* pColorAttachmentFormats;
287 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
288 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
289 sampleCount, // VkSampleCountFlagBits rasterizationSamples;
290 };
291
292 const VkCommandBufferInheritanceInfo bufferInheritanceInfo
293 {
294 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
295 &inheritanceRenderingInfo, // const void* pNext;
296 VK_NULL_HANDLE, // VkRenderPass renderPass;
297 0u, // deUint32 subpass;
298 VK_NULL_HANDLE, // VkFramebuffer framebuffer;
299 VK_FALSE, // VkBool32 occlusionQueryEnable;
300 (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags;
301 (VkQueryPipelineStatisticFlags)0u // VkQueryPipelineStatisticFlags pipelineStatistics;
302 };
303 #endif
304
305 DescriptorSetLayoutBuilder layoutBuilder;
306 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
307
308 const auto descriptorSetLayout = layoutBuilder.build(ctx.vkd, ctx.device);
309 const auto graphicsPipelineLayout = makePipelineLayout(ctx.vkd, ctx.device, descriptorSetLayout.get());
310
311 DescriptorPoolBuilder poolBuilder;
312 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
313 const auto descriptorPool = poolBuilder.build(ctx.vkd, ctx.device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
314 const auto descriptorSetBuffer = makeDescriptorSet(ctx.vkd, ctx.device, descriptorPool.get(), descriptorSetLayout.get());
315
316 // Update descriptor sets.
317 const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
318
319 DescriptorSetUpdateBuilder updater;
320 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
321 updater.update(ctx.vkd, ctx.device);
322
323 const auto vtxshader = createShaderModule(ctx.vkd, ctx.device, m_context.getBinaryCollection().get("vert"));
324 const auto frgshader = createShaderModule(ctx.vkd, ctx.device, m_context.getBinaryCollection().get("frag"));
325
326 const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
327
328 // Set up a default multisample state that doesn't use sample shading and with minSampleShading set to 0.0.
329 VkPipelineMultisampleStateCreateInfo multisampling = initVulkanStructure();
330 multisampling.sampleShadingEnable = VK_FALSE;
331 multisampling.minSampleShading = 0.0;
332 multisampling.rasterizationSamples = sampleCount;
333
334 const auto pass = (m_params.general->useDynamicRendering ? VK_NULL_HANDLE : renderPass.get());
335 const auto pipeline = makeGraphicsPipeline(
336 ctx.vkd, // const DeviceInterface& vk
337 ctx.device, // const VkDevice device
338 graphicsPipelineLayout.get(), // const VkPipelineLayout pipelineLayout
339 *vtxshader, // const VkShaderModule vertexShaderModule
340 VK_NULL_HANDLE, // const VkShaderModule tessellationControlModule
341 VK_NULL_HANDLE, // const VkShaderModule tessellationEvalModule
342 VK_NULL_HANDLE, // const VkShaderModule geometryShaderModule
343 *frgshader, // const VkShaderModule fragmentShaderModule
344 pass, // const VkRenderPass renderPass
345 viewports, // const std::vector<VkViewport>& viewports
346 scissors, // const std::vector<VkRect2D>& scissors
347 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
348 0u, // const deUint32 subpass
349 0u, // const deUint32 patchControlPoints
350 &vertexInputState, // VkPipelineVertexInputStateCreateInfo *vertexInputStateCreateInfo
351 VK_NULL_HANDLE, // VkPipelineRasterizationStateCreateInfo *rasterizationStateCreateInfo
352 &multisampling // VkPipelineMultisampleStateCreateInfo *multisampleStateCreateInfo
353 );
354
355 const auto commandPool = createCommandPool(ctx.vkd, ctx.device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, ctx.qfIndex);
356 const auto primaryCmdBufferPtr = allocateCommandBuffer(ctx.vkd, ctx.device, commandPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
357 const auto primaryCmdBuffer = *primaryCmdBufferPtr;
358 #ifndef CTS_USES_VULKANSC
359 const auto secondaryCmdBufferPtr = allocateCommandBuffer(ctx.vkd, ctx.device, commandPool.get(), VK_COMMAND_BUFFER_LEVEL_SECONDARY);
360 const auto secondaryCmdBuffer = *secondaryCmdBufferPtr;
361 #endif // CTS_USES_VULKANSC
362
363 beginCommandBuffer(ctx.vkd, primaryCmdBuffer);
364
365 if (m_params.general->useDynamicRendering)
366 {
367 #ifndef CTS_USES_VULKANSC
368 // Transition color attachment to the proper layout.
369 const auto initialBarrier = makeImageMemoryBarrier(
370 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
371 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
372 colorAttachment.get(), subresourceRange);
373 cmdPipelineImageMemoryBarrier(ctx.vkd, primaryCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, &initialBarrier);
374
375 if (m_params.general->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
376 {
377 const VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
378 const VkCommandBufferBeginInfo commandBufBeginParams =
379 {
380 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
381 nullptr, // const void* pNext;
382 usageFlags, // VkCommandBufferUsageFlags flags;
383 &bufferInheritanceInfo
384 };
385
386 ctx.vkd.beginCommandBuffer(secondaryCmdBuffer, &commandBufBeginParams);
387 ctx.vkd.cmdBeginRendering(secondaryCmdBuffer, &renderInfo);
388 ctx.vkd.cmdBindDescriptorSets(secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
389 ctx.vkd.cmdBindPipeline(secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
390 ctx.vkd.cmdDraw(secondaryCmdBuffer, 3u, 1u, 0u, 0u);
391 ctx.vkd.cmdEndRendering(secondaryCmdBuffer);
392 endCommandBuffer(ctx.vkd, secondaryCmdBuffer);
393 ctx.vkd.cmdExecuteCommands(primaryCmdBuffer, 1, &secondaryCmdBuffer);
394 }
395 else if (!m_params.general->secondaryCmdBufferCompletelyContainsDynamicRenderpass && m_params.general->useSecondaryCmdBuffer)
396 {
397 const VkCommandBufferUsageFlags usageFlags = (VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
398 const VkCommandBufferBeginInfo commandBufBeginParams =
399 {
400 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
401 nullptr, // const void* pNext;
402 usageFlags, // VkCommandBufferUsageFlags flags;
403 &bufferInheritanceInfo
404 };
405
406 ctx.vkd.cmdBeginRendering(primaryCmdBuffer, &renderInfo);
407 ctx.vkd.beginCommandBuffer(secondaryCmdBuffer, &commandBufBeginParams);
408 ctx.vkd.cmdBindDescriptorSets(secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
409 ctx.vkd.cmdBindPipeline(secondaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
410 ctx.vkd.cmdDraw(secondaryCmdBuffer, 3, 1, 0, 0);
411 endCommandBuffer(ctx.vkd, secondaryCmdBuffer);
412 ctx.vkd.cmdExecuteCommands(primaryCmdBuffer, 1, &secondaryCmdBuffer);
413 ctx.vkd.cmdEndRendering(primaryCmdBuffer);
414 }
415 else
416 {
417 ctx.vkd.cmdBeginRendering(primaryCmdBuffer, &renderInfo);
418 ctx.vkd.cmdBindDescriptorSets(primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
419 ctx.vkd.cmdBindPipeline(primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
420 ctx.vkd.cmdDraw(primaryCmdBuffer, 3, 1, 0, 0);
421 ctx.vkd.cmdEndRendering(primaryCmdBuffer);
422 }
423 #else
424 DE_ASSERT(false);
425 #endif
426 }
427 else
428 {
429 const VkRenderPassBeginInfo renderPassBeginInfo =
430 {
431 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
432 nullptr, // const void* pNext;
433 *renderPass, // VkRenderPass renderPass;
434 *framebuffer, // VkFramebuffer framebuffer;
435 scissors.at(0), // VkRect2D renderArea;
436 1, // uint32_t clearValueCount;
437 &clearValueColor, // const VkClearValue* pClearValues;
438 };
439 ctx.vkd.cmdBeginRenderPass(primaryCmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
440 ctx.vkd.cmdBindDescriptorSets(primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
441 ctx.vkd.cmdBindPipeline(primaryCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
442 ctx.vkd.cmdDraw(primaryCmdBuffer, 3, 1, 0, 0);
443 ctx.vkd.cmdEndRenderPass(primaryCmdBuffer);
444 }
445
446 const VkBufferMemoryBarrier renderBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, buffer.get(), 0ull, bufferSize);
447 cmdPipelineBufferMemoryBarrier(ctx.vkd, primaryCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &renderBufferBarrier);
448 endCommandBuffer(ctx.vkd, primaryCmdBuffer);
449 submitCommandsAndWait(ctx.vkd, ctx.device, m_context.getUniversalQueue(), primaryCmdBuffer);
450
451 invalidateAlloc(ctx.vkd, ctx.device, bufferAlloc);
452
453 uint32_t result = 0;
454 deMemcpy(&result, bufferData, sizeof(result));
455
456 if (result < expectedCounter)
457 {
458 std::stringstream output;
459 output << "Atomic counter value lower than expected: " << result;
460 return tcu::TestStatus::fail(output.str());
461 }
462
463 return tcu::TestStatus::pass("Pass");
464 }
465
466 } // anonoymous
467
createSampleAttributeTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)468 tcu::TestCaseGroup* createSampleAttributeTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
469 {
470 const struct
471 {
472 Trigger trigger;
473 const char* name;
474 } triggerCases[] =
475 {
476 // Dynamically use the sample decoration on a frag shader input variable
477 { Trigger::SAMPLE_DECORATION_DYNAMIC_USE, "sample_decoration_dynamic_use"},
478 // Declare SampleId built-in in the frag shader without using it
479 { Trigger::SAMPLE_ID_STATIC_USE, "sample_id_static_use"},
480 // Declare SamplePosition built-in in the frag shader without using it
481 { Trigger::SAMPLE_POSITION_STATIC_USE, "sample_position_static_use"},
482 };
483
484 de::MovePtr<tcu::TestCaseGroup> group {new tcu::TestCaseGroup{testCtx, "implicit_sample_shading"}};
485
486 for (const auto& triggerCase : triggerCases)
487 {
488 const TestParameters params { groupParams, triggerCase.trigger };
489 group->addChild(new SampleShadingSampleAttributeTestCase(testCtx, triggerCase.name, params));
490 }
491
492 return group.release();
493 }
494
495 } // Draw
496 } // vkt
497