• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2023 LunarG, Inc.
6  * Copyright (c) 2023 Nintendo
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Shader Object Pipeline Interaction Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectCreateTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkBarrierUtil.hpp"
32 #include "vktShaderObjectCreateUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "deRandom.hpp"
35 #include "vkBuilderUtil.hpp"
36 
37 namespace vkt
38 {
39 namespace ShaderObject
40 {
41 
42 namespace
43 {
44 
45 enum TestType
46 {
47     SHADER_OBJECT = 0,
48     MAX_PIPELINE,
49     MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE,
50     SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT,
51     MIN_PIPELINE_SHADER_OBJECT,
52     RENDER_PASS_PIPELINE_SHADER_OBJECT,
53     RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN,
54     SHADER_OBJECT_MIN_PIPELINE,
55     COMPUTE_SHADER_OBJECT_MIN_PIPELINE,
56     SHADER_OBJECT_COMPUTE_PIPELINE,
57 };
58 
59 struct TestParams
60 {
61     TestType testType;
62 };
63 
64 struct StageTestParams
65 {
66     bool vertShader;
67     bool tessShader;
68     bool geomShader;
69     bool fragShader;
70 };
71 
72 class ShaderObjectPipelineInteractionInstance : public vkt::TestInstance
73 {
74 public:
ShaderObjectPipelineInteractionInstance(Context & context,const TestParams & params)75     ShaderObjectPipelineInteractionInstance(Context &context, const TestParams &params)
76         : vkt::TestInstance(context)
77         , m_params(params)
78     {
79     }
~ShaderObjectPipelineInteractionInstance(void)80     virtual ~ShaderObjectPipelineInteractionInstance(void)
81     {
82     }
83 
84     tcu::TestStatus iterate(void) override;
85 
86 private:
87     bool verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer, uint32_t drawCount);
88     uint32_t getDrawCount(void);
89     TestParams m_params;
90 
91     const vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
92     const vk::VkRect2D renderArea            = {{
93                                          0u,
94                                          0u,
95                                      },
96                                                 {
97                                          32u,
98                                          32u,
99                                      }};
100 };
101 
getDrawCount(void)102 uint32_t ShaderObjectPipelineInteractionInstance::getDrawCount(void)
103 {
104     switch (m_params.testType)
105     {
106     case SHADER_OBJECT:
107         return 1;
108     case MAX_PIPELINE:
109         return 1;
110     case MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE:
111         return 3;
112     case SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT:
113         return 3;
114     case MIN_PIPELINE_SHADER_OBJECT:
115         return 2;
116     case RENDER_PASS_PIPELINE_SHADER_OBJECT:
117         return 1;
118     case RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN:
119         return 1;
120     case SHADER_OBJECT_MIN_PIPELINE:
121         return 2;
122     case COMPUTE_SHADER_OBJECT_MIN_PIPELINE:
123         return 1;
124     case SHADER_OBJECT_COMPUTE_PIPELINE:
125         return 1;
126     }
127     return 0;
128 }
129 
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)130 bool extensionEnabled(const std::vector<std::string> &deviceExtensions, const std::string &ext)
131 {
132     return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
133 }
134 
iterate(void)135 tcu::TestStatus ShaderObjectPipelineInteractionInstance::iterate(void)
136 {
137     const vk::DeviceInterface &vk   = m_context.getDeviceInterface();
138     const vk::VkDevice device       = m_context.getDevice();
139     const vk::VkQueue queue         = m_context.getUniversalQueue();
140     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
141     auto &alloc                     = m_context.getDefaultAllocator();
142     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
143         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
144     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
145     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
146     const bool taskSupported         = m_context.getMeshShaderFeatures().taskShader;
147     const bool meshSupported         = m_context.getMeshShaderFeatures().meshShader;
148 
149     const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
150 
151     const vk::VkImageCreateInfo createInfo = {
152         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                // VkStructureType            sType
153         DE_NULL,                                                // const void*                pNext
154         0u,                                                     // VkImageCreateFlags        flags
155         vk::VK_IMAGE_TYPE_2D,                                   // VkImageType                imageType
156         colorAttachmentFormat,                                  // VkFormat                    format
157         {renderArea.extent.width, renderArea.extent.height, 1}, // VkExtent3D                extent
158         1u,                                                     // uint32_t                    mipLevels
159         1u,                                                     // uint32_t                    arrayLayers
160         vk::VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits    samples
161         vk::VK_IMAGE_TILING_OPTIMAL,                            // VkImageTiling            tiling
162         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
163         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
164         0,                             // uint32_t                    queueFamilyIndexCount
165         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
166         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
167     };
168 
169     de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
170         new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
171     const auto imageView =
172         vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
173 
174     const vk::VkDeviceSize colorOutputBufferSize =
175         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
176     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
177         vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
178         vk::MemoryRequirement::HostVisible));
179 
180     const vk::VkCommandPoolCreateInfo cmdPoolInfo = {
181         vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
182         DE_NULL,                                             // pNext
183         vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
184         queueFamilyIndex,                                    // queuefamilyindex
185     };
186 
187     const vk::Move<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
188     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
189         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
190     const vk::Move<vk::VkCommandBuffer> copyCmdBuffer(
191         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
192 
193     const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
194         vk::DescriptorSetLayoutBuilder()
195             .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
196             .build(vk, device));
197 
198     const vk::Unique<vk::VkDescriptorPool> descriptorPool(
199         vk::DescriptorPoolBuilder()
200             .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
201             .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
202 
203     const auto pipelineLayout        = makePipelineLayout(vk, device);
204     const auto computePipelineLayout = makePipelineLayout(vk, device, descriptorSetLayout.get());
205 
206     const auto &binaries = m_context.getBinaryCollection();
207     const auto &vert1    = binaries.get("vert1");
208     const auto &vert2    = binaries.get("vert2");
209     const auto &vert3    = binaries.get("vert3");
210     const auto &tesc     = binaries.get("tesc");
211     const auto &tese     = binaries.get("tese");
212     const auto &geom     = binaries.get("geom");
213     const auto &frag1    = binaries.get("frag1");
214     const auto &frag2    = binaries.get("frag2");
215     const auto &frag3    = binaries.get("frag3");
216     const auto &comp     = binaries.get("comp");
217 
218     // Todo
219     vk::VkDescriptorSetLayout layout = descriptorSetLayout.get();
220 
221     vk::VkShaderCreateInfoEXT vertCreateInfo1 =
222         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert1, tessellationSupported, geometrySupported);
223     vk::VkShaderCreateInfoEXT vertCreateInfo2 =
224         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert2, tessellationSupported, geometrySupported);
225     vk::VkShaderCreateInfoEXT vertCreateInfo3 =
226         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, vert3, tessellationSupported, geometrySupported);
227     vk::VkShaderCreateInfoEXT tescCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
228                                                                         tesc, tessellationSupported, geometrySupported);
229     vk::VkShaderCreateInfoEXT teseCreateInfo = vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
230                                                                         tese, tessellationSupported, geometrySupported);
231     vk::VkShaderCreateInfoEXT geomCreateInfo =
232         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported);
233     vk::VkShaderCreateInfoEXT fragCreateInfo1 =
234         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag1, tessellationSupported, geometrySupported);
235     vk::VkShaderCreateInfoEXT fragCreateInfo2 =
236         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag2, tessellationSupported, geometrySupported);
237     vk::VkShaderCreateInfoEXT fragCreateInfo3 =
238         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag3, tessellationSupported, geometrySupported);
239     vk::VkShaderCreateInfoEXT compCreateInfo = vk::makeShaderCreateInfo(
240         vk::VK_SHADER_STAGE_COMPUTE_BIT, comp, tessellationSupported, geometrySupported, &layout);
241 
242     vk::Move<vk::VkShaderEXT> vertShader1 = vk::createShader(vk, device, vertCreateInfo1);
243     vk::Move<vk::VkShaderEXT> vertShader2 = vk::createShader(vk, device, vertCreateInfo2);
244     vk::Move<vk::VkShaderEXT> vertShader3 = vk::createShader(vk, device, vertCreateInfo3);
245     vk::Move<vk::VkShaderEXT> tescShader  = vk::createShader(vk, device, tescCreateInfo);
246     vk::Move<vk::VkShaderEXT> teseShader  = vk::createShader(vk, device, teseCreateInfo);
247     vk::Move<vk::VkShaderEXT> geomShader  = vk::createShader(vk, device, geomCreateInfo);
248     vk::Move<vk::VkShaderEXT> fragShader1 = vk::createShader(vk, device, fragCreateInfo1);
249     vk::Move<vk::VkShaderEXT> fragShader2 = vk::createShader(vk, device, fragCreateInfo2);
250     vk::Move<vk::VkShaderEXT> fragShader3 = vk::createShader(vk, device, fragCreateInfo3);
251     vk::Move<vk::VkShaderEXT> compShader  = vk::createShader(vk, device, compCreateInfo);
252 
253     const auto vertShaderModule1 = createShaderModule(vk, device, vert1);
254     const auto vertShaderModule2 = createShaderModule(vk, device, vert2);
255     const auto vertShaderModule3 = createShaderModule(vk, device, vert3);
256     const auto tescShaderModule  = createShaderModule(vk, device, tesc);
257     const auto teseShaderModule  = createShaderModule(vk, device, tese);
258     const auto geomShaderModule  = createShaderModule(vk, device, geom);
259     const auto fragShaderModule1 = createShaderModule(vk, device, frag1);
260     const auto fragShaderModule2 = createShaderModule(vk, device, frag2);
261     const auto fragShaderModule3 = createShaderModule(vk, device, frag3);
262     const auto compShaderModule  = createShaderModule(vk, device, comp);
263 
264     const auto renderPass  = vk::makeRenderPass(vk, device, colorAttachmentFormat, vk::VK_FORMAT_UNDEFINED,
265                                                 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, vk::VK_IMAGE_LAYOUT_GENERAL);
266     const auto framebuffer = vk::makeFramebuffer(vk, device, *renderPass, 1u, &*imageView, renderArea.extent.width,
267                                                  renderArea.extent.height);
268 
269     const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
270         vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
271         DE_NULL,                                                       // const void* pNext;
272         0u,                                                            // VkPipelineVertexInputStateCreateFlags flags;
273         0u,                                                            // uint32_t vertexBindingDescriptionCount;
274         DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
275         0u,      // uint32_t vertexAttributeDescriptionCount;
276         DE_NULL  // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
277     };
278 
279     const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo = {
280         vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
281         DE_NULL,                                                       // const void* pNext;
282         0u,                                                            // VkPipelineTessellationStateCreateFlags flags;
283         4u,                                                            // uint32_t patchControlPoints;
284     };
285 
286     const vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
287         vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                             sType;
288         DE_NULL,                                         // const void*                                 pNext;
289         (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags     flags;
290         vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,            // VkPrimitiveTopology                         topology;
291         VK_FALSE, // VkBool32                                    primitiveRestartEnable;
292     };
293 
294     vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
295         vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType    sType
296         DE_NULL,                                              // const void*        pNext
297         0u,                                                   // uint32_t            viewMask
298         1u,                                                   // uint32_t            colorAttachmentCount
299         &colorAttachmentFormat,                               // const VkFormat*    pColorAttachmentFormats
300         vk::VK_FORMAT_UNDEFINED,                              // VkFormat            depthAttachmentFormat
301         vk::VK_FORMAT_UNDEFINED,                              // VkFormat            stencilAttachmentFormat
302     };
303 
304     const vk::VkViewport viewport = vk::makeViewport(renderArea.extent);
305     const vk::VkRect2D scissor    = vk::makeRect2D(renderArea.extent);
306 
307     bool createDynamicPipeline = m_params.testType != MIN_PIPELINE_SHADER_OBJECT &&
308                                  m_params.testType != SHADER_OBJECT_MIN_PIPELINE &&
309                                  m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE &&
310                                  m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT &&
311                                  m_params.testType != RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN;
312 
313     const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
314         vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                             sType
315         DE_NULL,                                                   // const void*                                 pNext
316         (vk::VkPipelineViewportStateCreateFlags)0u,                // VkPipelineViewportStateCreateFlags          flags
317         createDynamicPipeline ? 0u : 1u, // uint32_t                                    viewportCount
318         &viewport,                       // const VkViewport*                           pViewports
319         createDynamicPipeline ? 0u : 1u, // uint32_t                                    scissorCount
320         &scissor,                        // const VkRect2D*                             pScissors
321     };
322 
323     const auto &edsFeatures  = m_context.getExtendedDynamicStateFeaturesEXT();
324     const auto &eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
325     const auto &eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
326     const auto &viFeatures   = m_context.getVertexInputDynamicStateFeaturesEXT();
327 
328     std::vector<vk::VkDynamicState> dynamicStates = {
329         vk::VK_DYNAMIC_STATE_LINE_WIDTH,           vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
330         vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,      vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
331         vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
332         vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
333     };
334 
335     if (edsFeatures.extendedDynamicState)
336     {
337         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE_EXT);
338         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT);
339         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT);
340         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
341         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
342         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
343         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
344         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
345         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
346         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
347         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
348         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT);
349     }
350     else
351     {
352         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT);
353         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR);
354     }
355     if (eds2Features.extendedDynamicState2)
356     {
357         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
358         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
359         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE);
360     }
361     if (eds2Features.extendedDynamicState2LogicOp)
362         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
363     if (eds2Features.extendedDynamicState2PatchControlPoints)
364         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
365 
366     if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
367         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
368     if (eds3Features.extendedDynamicState3DepthClampEnable)
369         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
370     if (eds3Features.extendedDynamicState3PolygonMode)
371         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
372     if (eds3Features.extendedDynamicState3RasterizationSamples)
373         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
374     if (eds3Features.extendedDynamicState3SampleMask)
375         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
376     if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
377         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
378     if (eds3Features.extendedDynamicState3AlphaToOneEnable)
379         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
380     if (eds3Features.extendedDynamicState3LogicOpEnable)
381         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
382     if (eds3Features.extendedDynamicState3ColorBlendEnable)
383         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
384     if (eds3Features.extendedDynamicState3ColorBlendEquation)
385         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
386     if (eds3Features.extendedDynamicState3ColorWriteMask)
387         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
388     if (viFeatures.vertexInputDynamicState)
389         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
390 
391     if (extensionEnabled(deviceExtensions, "VK_EXT_transform_feedback") &&
392         eds3Features.extendedDynamicState3RasterizationStream)
393         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
394     if (extensionEnabled(deviceExtensions, "VK_EXT_blend_operation_advanced") &&
395         eds3Features.extendedDynamicState3ColorBlendAdvanced)
396         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
397     if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") &&
398         eds3Features.extendedDynamicState3ConservativeRasterizationMode)
399         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
400     if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
401         eds3Features.extendedDynamicState3CoverageModulationMode)
402         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
403     if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
404         eds3Features.extendedDynamicState3CoverageModulationTableEnable)
405         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
406     if (extensionEnabled(deviceExtensions, "VK_NV_framebuffer_mixed_samples") &&
407         eds3Features.extendedDynamicState3CoverageModulationTable)
408         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
409     if (extensionEnabled(deviceExtensions, "VK_NV_coverage_reduction_mode") &&
410         eds3Features.extendedDynamicState3CoverageReductionMode)
411         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
412     if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") &&
413         eds3Features.extendedDynamicState3CoverageToColorEnable)
414         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
415     if (extensionEnabled(deviceExtensions, "VK_NV_fragment_coverage_to_color") &&
416         eds3Features.extendedDynamicState3CoverageToColorLocation)
417         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
418     if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_enable") &&
419         eds3Features.extendedDynamicState3DepthClipEnable)
420         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
421     if (extensionEnabled(deviceExtensions, "VK_EXT_depth_clip_control") &&
422         eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
423         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
424     if (extensionEnabled(deviceExtensions, "VK_EXT_color_write_enable"))
425         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
426     if (extensionEnabled(deviceExtensions, "VK_EXT_conservative_rasterization") &&
427         eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize)
428         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
429     if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
430          extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) &&
431         eds3Features.extendedDynamicState3LineRasterizationMode)
432         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
433     if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
434          extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")) &&
435         eds3Features.extendedDynamicState3LineStippleEnable)
436         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
437     if ((extensionEnabled(deviceExtensions, "VK_KHR_line_rasterization") ||
438          extensionEnabled(deviceExtensions, "VK_EXT_line_rasterization")))
439         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
440     if (extensionEnabled(deviceExtensions, "VK_EXT_provoking_vertex") &&
441         eds3Features.extendedDynamicState3ProvokingVertexMode)
442         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
443     if (extensionEnabled(deviceExtensions, "VK_KHR_fragment_shading_rate"))
444         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
445     if (extensionEnabled(deviceExtensions, "VK_NV_representative_fragment_test") &&
446         eds3Features.extendedDynamicState3RepresentativeFragmentTestEnable)
447         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
448     if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations") &&
449         eds3Features.extendedDynamicState3SampleLocationsEnable)
450         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
451     if (extensionEnabled(deviceExtensions, "VK_EXT_sample_locations"))
452         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
453     if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image") &&
454         eds3Features.extendedDynamicState3ShadingRateImageEnable)
455         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
456     if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
457         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
458     if (extensionEnabled(deviceExtensions, "VK_NV_shading_rate_image"))
459         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);
460     if (extensionEnabled(deviceExtensions, "VK_NV_viewport_swizzle") &&
461         eds3Features.extendedDynamicState3ViewportSwizzle)
462         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
463     if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling") &&
464         eds3Features.extendedDynamicState3ViewportWScalingEnable)
465         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
466     if (extensionEnabled(deviceExtensions, "VK_NV_clip_space_w_scaling"))
467         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
468     if (extensionEnabled(deviceExtensions, "VK_NV_scissor_exclusive"))
469         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
470     if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
471         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
472     if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
473         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
474     if (extensionEnabled(deviceExtensions, "VK_EXT_discard_rectangles"))
475         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
476 
477     const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
478         vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
479         DE_NULL,                                                  // const void* pNext;
480         (vk::VkPipelineDynamicStateCreateFlags)0u,                // VkPipelineDynamicStateCreateFlags flags;
481         static_cast<uint32_t>(dynamicStates.size()),              // uint32_t dynamicStateCount;
482         dynamicStates.data(),                                     // const VkDynamicState* pDynamicStates;
483     };
484     const vk::VkPipelineDynamicStateCreateInfo *pipelineDynamicState =
485         (createDynamicPipeline) ? &dynamicStateCreateInfo : DE_NULL;
486 
487     const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
488 
489     const vk::Unique<vk::VkDescriptorSet> descriptorSet(
490         makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
491     const vk::BufferWithMemory outputBuffer(
492         vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
493         vk::MemoryRequirement::HostVisible);
494 
495     const vk::VkDescriptorBufferInfo descriptorInfo =
496         vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
497     vk::DescriptorSetUpdateBuilder()
498         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
499                      vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
500         .update(vk, device);
501 
502     vk::VkPipelineRenderingCreateInfo *pPipelineRenderingCreateInfo = &pipelineRenderingCreateInfo;
503     vk::VkRenderPass renderPassHandle                               = VK_NULL_HANDLE;
504     if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT ||
505         m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
506     {
507         pPipelineRenderingCreateInfo = DE_NULL;
508         renderPassHandle             = *renderPass;
509     }
510 
511     const auto pipeline1 = makeGraphicsPipeline(
512         vk, device, pipelineLayout.get(), vertShaderModule1.get(), tescShaderModule.get(), teseShaderModule.get(),
513         geomShaderModule.get(), fragShaderModule1.get(), renderPassHandle, 0u, &vertexInputStateParams,
514         &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
515         DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
516     const auto pipeline2 = makeGraphicsPipeline(
517         vk, device, pipelineLayout.get(), vertShaderModule2.get(), tescShaderModule.get(), teseShaderModule.get(),
518         geomShaderModule.get(), fragShaderModule2.get(), renderPassHandle, 0u, &vertexInputStateParams,
519         &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
520         DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
521     const auto pipeline3 = makeGraphicsPipeline(
522         vk, device, pipelineLayout.get(), vertShaderModule3.get(), tescShaderModule.get(), teseShaderModule.get(),
523         geomShaderModule.get(), fragShaderModule3.get(), renderPassHandle, 0u, &vertexInputStateParams,
524         &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
525         DE_NULL, pipelineDynamicState, pPipelineRenderingCreateInfo);
526     const auto computePipeline =
527         vk::makeComputePipeline(vk, device, computePipelineLayout.get(), compShaderModule.get());
528 
529     const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
530     vk::VkImageMemoryBarrier initialBarrier =
531         vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
532                                    vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
533 
534     const vk::VkDeviceSize bufferSize        = 64;
535     de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
536         vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
537         vk::MemoryRequirement::HostVisible));
538 
539     vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
540 
541     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
542                           vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
543                           &initialBarrier);
544 
545     if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
546     {
547         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
548     }
549 
550     if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
551         vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
552                            vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
553 
554     vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
555                                             false,
556                                             !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
557     vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT());
558 
559     vk::VkDeviceSize offset = 0u;
560     vk::VkDeviceSize stride = 16u;
561     vk.cmdBindVertexBuffers2(*cmdBuffer, 0u, 1u, &**buffer, &offset, &bufferSize, &stride);
562 
563     if (m_params.testType == SHADER_OBJECT)
564     {
565         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
566                                 taskSupported, meshSupported);
567         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
568     }
569     else if (m_params.testType == MAX_PIPELINE)
570     {
571         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
572         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
573     }
574     else if (m_params.testType == MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE)
575     {
576         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
577         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
578 
579         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
580                                 taskSupported, meshSupported);
581         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
582 
583         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline3);
584         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
585     }
586     else if (m_params.testType == SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT)
587     {
588         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
589                                 taskSupported, meshSupported);
590         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
591 
592         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
593         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
594 
595         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader3, *tescShader, *teseShader, *geomShader, *fragShader3,
596                                 taskSupported, meshSupported);
597         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
598     }
599     else if (m_params.testType == MIN_PIPELINE_SHADER_OBJECT)
600     {
601         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
602         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
603 
604         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader2, *tescShader, *teseShader, *geomShader, *fragShader2,
605                                 taskSupported, meshSupported);
606         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
607     }
608     else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT)
609     {
610         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
611                                 taskSupported, meshSupported);
612         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
613     }
614     else if (m_params.testType == RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN)
615     {
616         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
617         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
618                                 taskSupported, meshSupported);
619         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
620     }
621     else if (m_params.testType == SHADER_OBJECT_MIN_PIPELINE)
622     {
623         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
624                                 taskSupported, meshSupported);
625         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
626 
627         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline2);
628         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
629     }
630     else if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE)
631     {
632         vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
633                                  &descriptorSet.get(), 0, DE_NULL);
634 
635         vk::VkShaderStageFlagBits stages[] = {vk::VK_SHADER_STAGE_COMPUTE_BIT};
636         vk.cmdBindShadersEXT(*cmdBuffer, 1, stages, &*compShader);
637         vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
638 
639         vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
640                            vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
641         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
642         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
643         vk::endRendering(vk, *cmdBuffer);
644     }
645     else if (m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
646     {
647         vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, computePipelineLayout.get(), 0, 1,
648                                  &descriptorSet.get(), 0, DE_NULL);
649 
650         vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
651                            vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
652         vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader1, *tescShader, *teseShader, *geomShader, *fragShader1,
653                                 taskSupported, meshSupported);
654         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
655         vk::endRendering(vk, *cmdBuffer);
656 
657         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
658         vk.cmdDispatch(*cmdBuffer, 4, 1, 1);
659     }
660 
661     if (m_params.testType != COMPUTE_SHADER_OBJECT_MIN_PIPELINE && m_params.testType != SHADER_OBJECT_COMPUTE_PIPELINE)
662         vk::endRendering(vk, *cmdBuffer);
663 
664     vk::endCommandBuffer(vk, *cmdBuffer);
665 
666     submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
667 
668     const vk::VkBufferImageCopy copyRegion = {
669         0u, // VkDeviceSize bufferOffset;
670         0u, // uint32_t bufferRowLength;
671         0u, // uint32_t bufferImageHeight;
672         {
673             vk::VK_IMAGE_ASPECT_COLOR_BIT,                     // VkImageAspectFlags aspect;
674             0u,                                                // uint32_t mipLevel;
675             0u,                                                // uint32_t baseArrayLayer;
676             1u,                                                // uint32_t layerCount;
677         },                                                     // VkImageSubresourceLayers imageSubresource;
678         {0, 0, 0},                                             // VkOffset3D imageOffset;
679         {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
680     };
681 
682     vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
683     vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
684     vk::endCommandBuffer(vk, *copyCmdBuffer);
685     submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
686 
687     if (!verifyImage(colorOutputBuffer, getDrawCount()))
688         return tcu::TestStatus::fail("Fail");
689 
690     if (m_params.testType == COMPUTE_SHADER_OBJECT_MIN_PIPELINE || m_params.testType == SHADER_OBJECT_COMPUTE_PIPELINE)
691     {
692         const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
693         invalidateAlloc(vk, device, outputBufferAllocation);
694 
695         const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
696 
697         for (uint32_t i = 0; i < 4; ++i)
698         {
699             if (bufferPtr[i] != i)
700                 return tcu::TestStatus::fail("Fail");
701         }
702     }
703 
704     return tcu::TestStatus::pass("Pass");
705 }
706 
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer,uint32_t drawCount)707 bool ShaderObjectPipelineInteractionInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer,
708                                                           uint32_t drawCount)
709 {
710     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
711         vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
712         (const void *)outputBuffer->getAllocation().getHostPtr());
713 
714     const tcu::Vec4 red   = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
715     const tcu::Vec4 green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
716     const tcu::Vec4 blue  = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
717     const int32_t width   = resultBuffer.getWidth();
718     const int32_t height  = resultBuffer.getHeight();
719 
720     for (int32_t j = 0; j < height; ++j)
721     {
722         for (int32_t i = 0; i < width; ++i)
723         {
724             const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
725             if (i < width / 2 && j < height / 2 && drawCount > 0)
726             {
727                 if (color != red)
728                     return false;
729             }
730             else if (i >= width / 2 && j < height / 2 && drawCount > 1)
731             {
732                 if (color != green)
733                     return false;
734             }
735             else if (i < width / 2 && j >= height / 2 && drawCount > 2)
736             {
737                 if (color != blue)
738                     return false;
739             }
740         }
741     }
742 
743     return true;
744 }
745 
746 class ShaderObjectPipelineInteractionCase : public vkt::TestCase
747 {
748 public:
ShaderObjectPipelineInteractionCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)749     ShaderObjectPipelineInteractionCase(tcu::TestContext &testCtx, const std::string &name, const TestParams &params)
750         : vkt::TestCase(testCtx, name)
751         , m_params(params)
752     {
753     }
~ShaderObjectPipelineInteractionCase(void)754     virtual ~ShaderObjectPipelineInteractionCase(void)
755     {
756     }
757 
758     void checkSupport(vkt::Context &context) const override;
759     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const760     TestInstance *createInstance(Context &context) const override
761     {
762         return new ShaderObjectPipelineInteractionInstance(context, m_params);
763     }
764 
765 private:
766     TestParams m_params;
767 };
768 
initPrograms(vk::SourceCollections & programCollection) const769 void ShaderObjectPipelineInteractionCase::initPrograms(vk::SourceCollections &programCollection) const
770 {
771     std::stringstream vert1, vert2, vert3;
772     std::stringstream geom;
773     std::stringstream tesc;
774     std::stringstream tese;
775     std::stringstream frag1, frag2, frag3;
776     std::stringstream comp;
777 
778     vert1 << "#version 450\n"
779           << "void main() {\n"
780           << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
781           << "    gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.5f), 0.0f, 1.0f);\n"
782           << "}\n";
783     vert2 << "#version 450\n"
784           << "void main() {\n"
785           << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
786           << "    gl_Position = vec4(pos * 0.5f - vec2(0.0f, 0.5f), 0.0f, 1.0f);\n"
787           << "}\n";
788     vert3 << "#version 450\n"
789           << "void main() {\n"
790           << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
791           << "    gl_Position = vec4(pos * 0.5f - vec2(0.5f, 0.0f), 0.0f, 1.0f);\n"
792           << "}\n";
793 
794     tesc << "#version 450\n"
795          << "\n"
796          << "layout(vertices = 4) out;\n"
797          << "\n"
798          << "void main (void)\n"
799          << "{\n"
800          << "    if (gl_InvocationID == 0) {\n"
801          << "        gl_TessLevelInner[0] = 1.0;\n"
802          << "        gl_TessLevelInner[1] = 1.0;\n"
803          << "        gl_TessLevelOuter[0] = 1.0;\n"
804          << "        gl_TessLevelOuter[1] = 1.0;\n"
805          << "        gl_TessLevelOuter[2] = 1.0;\n"
806          << "        gl_TessLevelOuter[3] = 1.0;\n"
807          << "    }\n"
808          << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
809          << "}\n";
810 
811     tese << "#version 450\n"
812          << "\n"
813          << "layout(quads, equal_spacing) in;\n"
814          << "\n"
815          << "void main (void)\n"
816          << "{\n"
817          << "    float u = gl_TessCoord.x;\n"
818          << "    float v = gl_TessCoord.y;\n"
819          << "    float omu = 1.0f - u;\n"
820          << "    float omv = 1.0f - v;\n"
821          << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
822             "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
823          << "    gl_Position.x *= 2.0f;\n"
824          << "}\n";
825 
826     geom << "#version 450\n"
827          << "layout(triangles) in;\n"
828          << "layout(triangle_strip, max_vertices = 4) out;\n"
829          << "\n"
830          << "void main(void)\n"
831          << "{\n"
832          << "    gl_Position = gl_in[0].gl_Position;\n"
833          << "    gl_Position.y *= 2.0f;\n"
834          << "    EmitVertex();\n"
835          << "    gl_Position = gl_in[1].gl_Position;\n"
836          << "    gl_Position.y *= 2.0f;\n"
837          << "    EmitVertex();\n"
838          << "    gl_Position = gl_in[2].gl_Position;\n"
839          << "    gl_Position.y *= 2.0f;\n"
840          << "    EmitVertex();\n"
841          << "    EndPrimitive();\n"
842          << "}\n";
843 
844     frag1 << "#version 450\n"
845           << "layout (location=0) out vec4 outColor;\n"
846           << "void main() {\n"
847           << "    outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
848           << "}\n";
849     frag2 << "#version 450\n"
850           << "layout (location=0) out vec4 outColor;\n"
851           << "void main() {\n"
852           << "    outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
853           << "}\n";
854     frag3 << "#version 450\n"
855           << "layout (location=0) out vec4 outColor;\n"
856           << "void main() {\n"
857           << "    outColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
858           << "}\n";
859 
860     comp << "#version 450\n"
861          << "layout(local_size_x=16, local_size_x=1, local_size_x=1) in;\n"
862          << "layout(binding = 0) buffer Output {\n"
863          << "    uint values[16];\n"
864          << "} buffer_out;\n\n"
865          << "void main() {\n"
866          << "    buffer_out.values[gl_LocalInvocationID.x] = gl_LocalInvocationID.x;\n"
867          << "}\n";
868 
869     programCollection.glslSources.add("vert1") << glu::VertexSource(vert1.str());
870     programCollection.glslSources.add("vert2") << glu::VertexSource(vert2.str());
871     programCollection.glslSources.add("vert3") << glu::VertexSource(vert3.str());
872     programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
873     programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
874     programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
875     programCollection.glslSources.add("frag1") << glu::FragmentSource(frag1.str());
876     programCollection.glslSources.add("frag2") << glu::FragmentSource(frag2.str());
877     programCollection.glslSources.add("frag3") << glu::FragmentSource(frag3.str());
878     programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
879 }
880 
checkSupport(Context & context) const881 void ShaderObjectPipelineInteractionCase::checkSupport(Context &context) const
882 {
883     context.requireDeviceFunctionality("VK_EXT_shader_object");
884 
885     context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
886     context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
887 }
888 
889 class ShaderObjectStageBindingInstance : public vkt::TestInstance
890 {
891 public:
ShaderObjectStageBindingInstance(Context & context,const StageTestParams & params)892     ShaderObjectStageBindingInstance(Context &context, const StageTestParams &params)
893         : vkt::TestInstance(context)
894         , m_params(params)
895     {
896     }
~ShaderObjectStageBindingInstance(void)897     virtual ~ShaderObjectStageBindingInstance(void)
898     {
899     }
900 
901     tcu::TestStatus iterate(void) override;
902 
903 private:
904     bool verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer);
905     StageTestParams m_params;
906 
907     const vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
908     const vk::VkRect2D renderArea            = {{
909                                          0u,
910                                          0u,
911                                      },
912                                                 {
913                                          32u,
914                                          32u,
915                                      }};
916 };
917 
iterate(void)918 tcu::TestStatus ShaderObjectStageBindingInstance::iterate(void)
919 {
920     const vk::DeviceInterface &vk   = m_context.getDeviceInterface();
921     const vk::VkDevice device       = m_context.getDevice();
922     const vk::VkQueue queue         = m_context.getUniversalQueue();
923     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
924     auto &alloc                     = m_context.getDefaultAllocator();
925     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
926         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
927     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
928     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
929     const bool taskSupported         = m_context.getMeshShaderFeatures().taskShader;
930     const bool meshSupported         = m_context.getMeshShaderFeatures().meshShader;
931 
932     const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
933 
934     const vk::VkImageCreateInfo createInfo = {
935         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                // VkStructureType            sType
936         DE_NULL,                                                // const void*                pNext
937         0u,                                                     // VkImageCreateFlags        flags
938         vk::VK_IMAGE_TYPE_2D,                                   // VkImageType                imageType
939         colorAttachmentFormat,                                  // VkFormat                    format
940         {renderArea.extent.width, renderArea.extent.height, 1}, // VkExtent3D                extent
941         1u,                                                     // uint32_t                    mipLevels
942         1u,                                                     // uint32_t                    arrayLayers
943         vk::VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits    samples
944         vk::VK_IMAGE_TILING_OPTIMAL,                            // VkImageTiling            tiling
945         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
946         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
947         0,                             // uint32_t                    queueFamilyIndexCount
948         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
949         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
950     };
951 
952     de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
953         new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
954     const auto imageView =
955         vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
956 
957     const vk::VkDeviceSize colorOutputBufferSize =
958         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
959     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
960         vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
961         vk::MemoryRequirement::HostVisible));
962 
963     const vk::VkCommandPoolCreateInfo cmdPoolInfo = {
964         vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,      // sType
965         DE_NULL,                                             // pNext
966         vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
967         queueFamilyIndex,                                    // queuefamilyindex
968     };
969 
970     const vk::Move<vk::VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolInfo));
971     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
972         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
973     const vk::Move<vk::VkCommandBuffer> copyCmdBuffer(
974         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
975 
976     const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
977         vk::DescriptorSetLayoutBuilder()
978             .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_ALL_GRAPHICS)
979             .build(vk, device));
980 
981     const vk::Unique<vk::VkDescriptorPool> descriptorPool(
982         vk::DescriptorPoolBuilder()
983             .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
984             .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
985 
986     const auto topology =
987         m_params.tessShader ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
988 
989     const auto pipelineLayout      = makePipelineLayout(vk, device, descriptorSetLayout.get());
990     const auto emptyPipelineLayout = makePipelineLayout(vk, device);
991 
992     const auto &binaries = m_context.getBinaryCollection();
993     const auto &vert     = binaries.get("vert");
994     const auto &tesc     = binaries.get("tesc");
995     const auto &tese     = binaries.get("tese");
996     const auto &geom     = binaries.get("geom");
997     const auto &frag     = binaries.get("frag");
998 
999     const auto &pipeline_vert = binaries.get("pipeline_vert");
1000     const auto &pipeline_tesc = binaries.get("pipeline_tesc");
1001     const auto &pipeline_tese = binaries.get("pipeline_tese");
1002     const auto &pipeline_geom = binaries.get("pipeline_geom");
1003     const auto &pipeline_frag = binaries.get("pipeline_frag");
1004 
1005     vk::VkDescriptorSetLayout layout = descriptorSetLayout.get();
1006 
1007     vk::VkShaderCreateInfoEXT vertCreateInfo = vk::makeShaderCreateInfo(
1008         vk::VK_SHADER_STAGE_VERTEX_BIT, vert, tessellationSupported, geometrySupported, &layout);
1009     vk::VkShaderCreateInfoEXT tescCreateInfo = vk::makeShaderCreateInfo(
1010         vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, tesc, tessellationSupported, geometrySupported, &layout);
1011     vk::VkShaderCreateInfoEXT teseCreateInfo = vk::makeShaderCreateInfo(
1012         vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, tese, tessellationSupported, geometrySupported, &layout);
1013     vk::VkShaderCreateInfoEXT geomCreateInfo = vk::makeShaderCreateInfo(
1014         vk::VK_SHADER_STAGE_GEOMETRY_BIT, geom, tessellationSupported, geometrySupported, &layout);
1015     vk::VkShaderCreateInfoEXT fragCreateInfo = vk::makeShaderCreateInfo(
1016         vk::VK_SHADER_STAGE_FRAGMENT_BIT, frag, tessellationSupported, geometrySupported, &layout);
1017 
1018     vk::Move<vk::VkShaderEXT> vertShader = vk::createShader(vk, device, vertCreateInfo);
1019     vk::Move<vk::VkShaderEXT> tescShader;
1020     vk::Move<vk::VkShaderEXT> teseShader;
1021     vk::Move<vk::VkShaderEXT> geomShader;
1022     vk::Move<vk::VkShaderEXT> fragShader = vk::createShader(vk, device, fragCreateInfo);
1023 
1024     vk::Move<vk::VkShaderModule> vertShaderModule = createShaderModule(vk, device, pipeline_vert);
1025     vk::Move<vk::VkShaderModule> tescShaderModule;
1026     vk::Move<vk::VkShaderModule> teseShaderModule;
1027     vk::Move<vk::VkShaderModule> geomShaderModule;
1028     vk::Move<vk::VkShaderModule> fragShaderModule = createShaderModule(vk, device, pipeline_frag);
1029 
1030     if (m_params.tessShader)
1031     {
1032         tescShader = vk::createShader(vk, device, tescCreateInfo);
1033         teseShader = vk::createShader(vk, device, teseCreateInfo);
1034 
1035         tescShaderModule = createShaderModule(vk, device, pipeline_tesc);
1036         teseShaderModule = createShaderModule(vk, device, pipeline_tese);
1037     }
1038     if (m_params.geomShader)
1039     {
1040         geomShader = vk::createShader(vk, device, geomCreateInfo);
1041 
1042         geomShaderModule = createShaderModule(vk, device, pipeline_geom);
1043     }
1044 
1045     const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1046         vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1047         DE_NULL,                                                       // const void* pNext;
1048         0u,                                                            // VkPipelineVertexInputStateCreateFlags flags;
1049         0u,                                                            // uint32_t vertexBindingDescriptionCount;
1050         DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1051         0u,      // uint32_t vertexAttributeDescriptionCount;
1052         DE_NULL  // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1053     };
1054 
1055     const vk::VkPipelineTessellationStateCreateInfo tessStateCreateInfo = {
1056         vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1057         DE_NULL,                                                       // const void* pNext;
1058         0u,                                                            // VkPipelineTessellationStateCreateFlags flags;
1059         4u,                                                            // uint32_t patchControlPoints;
1060     };
1061 
1062     const vk::VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
1063         vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                             sType;
1064         DE_NULL,                                         // const void*                                 pNext;
1065         (vk::VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags     flags;
1066         topology,                                        // VkPrimitiveTopology                         topology;
1067         VK_FALSE, // VkBool32                                    primitiveRestartEnable;
1068     };
1069 
1070     vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
1071         vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType    sType
1072         DE_NULL,                                              // const void*        pNext
1073         0u,                                                   // uint32_t            viewMask
1074         1u,                                                   // uint32_t            colorAttachmentCount
1075         &colorAttachmentFormat,                               // const VkFormat*    pColorAttachmentFormats
1076         vk::VK_FORMAT_UNDEFINED,                              // VkFormat            depthAttachmentFormat
1077         vk::VK_FORMAT_UNDEFINED,                              // VkFormat            stencilAttachmentFormat
1078     };
1079 
1080     const vk::VkViewport viewport =
1081         vk::makeViewport((float)renderArea.extent.width, 0.0f, (float)renderArea.extent.width,
1082                          (float)renderArea.extent.height, 0.0f, 1.0f);
1083     const vk::VkRect2D scissor = vk::makeRect2D(renderArea.extent);
1084 
1085     const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
1086         vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                             sType
1087         DE_NULL,                                                   // const void*                                 pNext
1088         (vk::VkPipelineViewportStateCreateFlags)0u,                // VkPipelineViewportStateCreateFlags          flags
1089         1u,        // uint32_t                                    viewportCount
1090         &viewport, // const VkViewport*                           pViewports
1091         1u,        // uint32_t                                    scissorCount
1092         &scissor   // const VkRect2D*                             pScissors
1093     };
1094 
1095     const auto pipeline = makeGraphicsPipeline(
1096         vk, device, emptyPipelineLayout.get(), vertShaderModule.get(), tescShaderModule.get(), teseShaderModule.get(),
1097         geomShaderModule.get(), fragShaderModule.get(), VK_NULL_HANDLE, 0u, &vertexInputStateParams,
1098         &pipelineInputAssemblyStateInfo, &tessStateCreateInfo, &viewportStateCreateInfo, DE_NULL, DE_NULL, DE_NULL,
1099         DE_NULL, DE_NULL, &pipelineRenderingCreateInfo);
1100 
1101     const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 4;
1102 
1103     const vk::Unique<vk::VkDescriptorSet> descriptorSet(
1104         makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1105     const vk::BufferWithMemory outputBuffer(
1106         vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
1107         vk::MemoryRequirement::HostVisible);
1108 
1109     const vk::VkDescriptorBufferInfo descriptorInfo =
1110         vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1111     vk::DescriptorSetUpdateBuilder()
1112         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1113                      vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1114         .update(vk, device);
1115 
1116     const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 1.0f});
1117     vk::VkImageMemoryBarrier initialBarrier =
1118         vk::makeImageMemoryBarrier(0, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1119                                    vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1120 
1121     vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
1122 
1123     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1124                           vk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, DE_NULL, 0, DE_NULL, 1,
1125                           &initialBarrier);
1126 
1127     vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
1128                        vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1129 
1130     vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1131     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1132 
1133     vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
1134                              &descriptorSet.get(), 0, DE_NULL);
1135     vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, topology, false,
1136                                             !m_context.getExtendedDynamicStateFeaturesEXT().extendedDynamicState);
1137 
1138     vk::bindGraphicsShaders(vk, *cmdBuffer, (m_params.vertShader) ? *vertShader : VK_NULL_HANDLE,
1139                             (m_params.tessShader) ? *tescShader : VK_NULL_HANDLE,
1140                             (m_params.tessShader) ? *teseShader : VK_NULL_HANDLE,
1141                             (m_params.geomShader) ? *geomShader : VK_NULL_HANDLE,
1142                             (m_params.fragShader) ? *fragShader : VK_NULL_HANDLE, taskSupported, meshSupported);
1143 
1144     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1145 
1146     vk::endRendering(vk, *cmdBuffer);
1147 
1148     vk::endCommandBuffer(vk, *cmdBuffer);
1149 
1150     submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1151 
1152     if (m_params.fragShader)
1153     {
1154         const vk::VkBufferImageCopy copyRegion = {
1155             0u, // VkDeviceSize bufferOffset;
1156             0u, // uint32_t bufferRowLength;
1157             0u, // uint32_t bufferImageHeight;
1158             {
1159                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                     // VkImageAspectFlags aspect;
1160                 0u,                                                // uint32_t mipLevel;
1161                 0u,                                                // uint32_t baseArrayLayer;
1162                 1u,                                                // uint32_t layerCount;
1163             },                                                     // VkImageSubresourceLayers imageSubresource;
1164             {0, 0, 0},                                             // VkOffset3D imageOffset;
1165             {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
1166         };
1167 
1168         vk::beginCommandBuffer(vk, *copyCmdBuffer, 0u);
1169         vk.cmdCopyImageToBuffer(*copyCmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u,
1170                                 &copyRegion);
1171         vk::endCommandBuffer(vk, *copyCmdBuffer);
1172         submitCommandsAndWait(vk, device, queue, copyCmdBuffer.get());
1173 
1174         if (!verifyImage(colorOutputBuffer))
1175             return tcu::TestStatus::fail("Fail");
1176     }
1177 
1178     const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
1179     invalidateAlloc(vk, device, outputBufferAllocation);
1180 
1181     const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
1182 
1183     if (m_params.vertShader && bufferPtr[0] != 1u)
1184         return tcu::TestStatus::fail("Fail");
1185     if (m_params.tessShader && bufferPtr[1] != 2u)
1186         return tcu::TestStatus::fail("Fail");
1187     if (m_params.geomShader && bufferPtr[2] != 3u)
1188         return tcu::TestStatus::fail("Fail");
1189 
1190     return tcu::TestStatus::pass("Pass");
1191 }
1192 
verifyImage(de::MovePtr<vk::BufferWithMemory> & outputBuffer)1193 bool ShaderObjectStageBindingInstance::verifyImage(de::MovePtr<vk::BufferWithMemory> &outputBuffer)
1194 {
1195     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1196         vk::mapVkFormat(vk::VK_FORMAT_R8G8B8A8_UNORM), renderArea.extent.width, renderArea.extent.height, 1,
1197         (const void *)outputBuffer->getAllocation().getHostPtr());
1198 
1199     const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1200     const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
1201     const int32_t width   = resultBuffer.getWidth();
1202     const int32_t height  = resultBuffer.getHeight();
1203 
1204     const int32_t xOffset = m_params.tessShader ? 4 : 8;
1205     const int32_t yOffset = m_params.geomShader ? 4 : 8;
1206 
1207     for (int32_t j = 0; j < height; ++j)
1208     {
1209         for (int32_t i = 0; i < width; ++i)
1210         {
1211             const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1212             if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
1213             {
1214                 if (color != white)
1215                     return false;
1216             }
1217             else
1218             {
1219                 if (color != black)
1220                     return false;
1221             }
1222         }
1223     }
1224 
1225     return true;
1226 }
1227 
1228 class ShaderObjectStageBindingCase : public vkt::TestCase
1229 {
1230 public:
ShaderObjectStageBindingCase(tcu::TestContext & testCtx,const std::string & name,const StageTestParams & params)1231     ShaderObjectStageBindingCase(tcu::TestContext &testCtx, const std::string &name, const StageTestParams &params)
1232         : vkt::TestCase(testCtx, name)
1233         , m_params(params)
1234     {
1235     }
~ShaderObjectStageBindingCase(void)1236     virtual ~ShaderObjectStageBindingCase(void)
1237     {
1238     }
1239 
1240     void checkSupport(vkt::Context &context) const override;
1241     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const1242     TestInstance *createInstance(Context &context) const override
1243     {
1244         return new ShaderObjectStageBindingInstance(context, m_params);
1245     }
1246 
1247 private:
1248     StageTestParams m_params;
1249 };
1250 
checkSupport(Context & context) const1251 void ShaderObjectStageBindingCase::checkSupport(Context &context) const
1252 {
1253     context.requireDeviceFunctionality("VK_EXT_shader_object");
1254 
1255     if (m_params.tessShader)
1256         context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
1257 
1258     if (m_params.geomShader)
1259         context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
1260 }
1261 
initPrograms(vk::SourceCollections & programCollection) const1262 void ShaderObjectStageBindingCase::initPrograms(vk::SourceCollections &programCollection) const
1263 {
1264     std::stringstream vert;
1265     std::stringstream geom;
1266     std::stringstream tesc;
1267     std::stringstream tese;
1268     std::stringstream frag;
1269 
1270     std::stringstream pipeline_vert;
1271     std::stringstream pipeline_geom;
1272     std::stringstream pipeline_tesc;
1273     std::stringstream pipeline_tese;
1274     std::stringstream pipeline_frag;
1275 
1276     vert << "#version 450\n"
1277          << "layout(set = 0, binding = 0) buffer Output {\n"
1278          << "    uint values[4];\n"
1279          << "} buffer_out;\n\n"
1280          << "void main() {\n"
1281          << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1282          << "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1283          << "    if (gl_VertexIndex == 0u)\n"
1284          << "        buffer_out.values[0] = 1u;\n"
1285          << "}\n";
1286 
1287     tesc << "#version 450\n"
1288          << "\n"
1289          << "layout(vertices = 4) out;\n"
1290          << "layout(set = 0, binding = 0) buffer Output {\n"
1291          << "    uint values[4];\n"
1292          << "} buffer_out;\n\n"
1293          << "\n"
1294          << "void main (void)\n"
1295          << "{\n"
1296          << "    if (gl_InvocationID == 0) {\n"
1297          << "        gl_TessLevelInner[0] = 1.0;\n"
1298          << "        gl_TessLevelInner[1] = 1.0;\n"
1299          << "        gl_TessLevelOuter[0] = 1.0;\n"
1300          << "        gl_TessLevelOuter[1] = 1.0;\n"
1301          << "        gl_TessLevelOuter[2] = 1.0;\n"
1302          << "        gl_TessLevelOuter[3] = 1.0;\n"
1303          << "        buffer_out.values[1] = 2u;\n"
1304          << "    }\n"
1305          << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1306          << "}\n";
1307 
1308     tese << "#version 450\n"
1309          << "\n"
1310          << "layout(quads, equal_spacing) in;\n"
1311          << "\n"
1312          << "void main (void)\n"
1313          << "{\n"
1314          << "    float u = gl_TessCoord.x;\n"
1315          << "    float v = gl_TessCoord.y;\n"
1316          << "    float omu = 1.0f - u;\n"
1317          << "    float omv = 1.0f - v;\n"
1318          << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1319             "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1320          << "    gl_Position.x *= 1.5f;\n"
1321          << "}\n";
1322 
1323     geom << "#version 450\n"
1324          << "layout(triangles) in;\n"
1325          << "layout(triangle_strip, max_vertices = 4) out;\n"
1326          << "layout(set = 0, binding = 0) buffer Output {\n"
1327          << "    uint values[4];\n"
1328          << "} buffer_out;\n\n"
1329          << "\n"
1330          << "void main(void)\n"
1331          << "{\n"
1332          << "    gl_Position = gl_in[0].gl_Position;\n"
1333          << "    gl_Position.y *= 1.5f;\n"
1334          << "    EmitVertex();\n"
1335          << "    gl_Position = gl_in[1].gl_Position;\n"
1336          << "    gl_Position.y *= 1.5f;\n"
1337          << "    EmitVertex();\n"
1338          << "    gl_Position = gl_in[2].gl_Position;\n"
1339          << "    gl_Position.y *= 1.5f;\n"
1340          << "    EmitVertex();\n"
1341          << "    EndPrimitive();\n"
1342          << "    if (gl_InvocationID == 0u)\n"
1343          << "        buffer_out.values[2] = 3u;\n"
1344          << "}\n";
1345 
1346     frag << "#version 450\n"
1347          << "layout (location=0) out vec4 outColor;\n"
1348          << "void main() {\n"
1349          << "    outColor = vec4(1.0f);\n"
1350          << "}\n";
1351 
1352     pipeline_vert << "#version 450\n"
1353                   << "void main() {\n"
1354                   << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
1355                   << "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
1356                   << "}\n";
1357 
1358     pipeline_tesc << "#version 450\n"
1359                   << "\n"
1360                   << "layout(vertices = 4) out;\n"
1361                   << "\n"
1362                   << "void main (void)\n"
1363                   << "{\n"
1364                   << "    if (gl_InvocationID == 0) {\n"
1365                   << "        gl_TessLevelInner[0] = 1.0;\n"
1366                   << "        gl_TessLevelInner[1] = 1.0;\n"
1367                   << "        gl_TessLevelOuter[0] = 1.0;\n"
1368                   << "        gl_TessLevelOuter[1] = 1.0;\n"
1369                   << "        gl_TessLevelOuter[2] = 1.0;\n"
1370                   << "        gl_TessLevelOuter[3] = 1.0;\n"
1371                   << "    }\n"
1372                   << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1373                   << "}\n";
1374 
1375     pipeline_tese << "#version 450\n"
1376                   << "\n"
1377                   << "layout(quads, equal_spacing) in;\n"
1378                   << "\n"
1379                   << "void main (void)\n"
1380                   << "{\n"
1381                   << "    float u = gl_TessCoord.x;\n"
1382                   << "    float v = gl_TessCoord.y;\n"
1383                   << "    float omu = 1.0f - u;\n"
1384                   << "    float omv = 1.0f - v;\n"
1385                   << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
1386                      "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
1387                   << "    gl_Position.x *= 0.5f;\n"
1388                   << "    gl_Position.y *= 0.5f;\n"
1389                   << "}\n";
1390 
1391     pipeline_geom << "#version 450\n"
1392                   << "layout(triangles) in;\n"
1393                   << "layout(triangle_strip, max_vertices = 4) out;\n"
1394                   << "\n"
1395                   << "void main(void)\n"
1396                   << "{\n"
1397                   << "    gl_Position = gl_in[0].gl_Position;\n"
1398                   << "    gl_Position.x += 0.25f;\n"
1399                   << "    gl_Position.y += 0.25f;\n"
1400                   << "    EmitVertex();\n"
1401                   << "    gl_Position = gl_in[1].gl_Position;\n"
1402                   << "    gl_Position.x += 0.25f;\n"
1403                   << "    gl_Position.y += 0.25f;\n"
1404                   << "    EmitVertex();\n"
1405                   << "    gl_Position = gl_in[2].gl_Position;\n"
1406                   << "    gl_Position.x += 0.25f;\n"
1407                   << "    gl_Position.y += 0.25f;\n"
1408                   << "    EmitVertex();\n"
1409                   << "    EndPrimitive();\n"
1410                   << "}\n";
1411 
1412     pipeline_frag << "#version 450\n"
1413                   << "layout (location=0) out vec4 outColor;\n"
1414                   << "void main() {\n"
1415                   << "    outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
1416                   << "}\n";
1417 
1418     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
1419     programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
1420     programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
1421     programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
1422     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1423 
1424     programCollection.glslSources.add("pipeline_vert") << glu::VertexSource(pipeline_vert.str());
1425     programCollection.glslSources.add("pipeline_tesc") << glu::TessellationControlSource(pipeline_tesc.str());
1426     programCollection.glslSources.add("pipeline_tese") << glu::TessellationEvaluationSource(pipeline_tese.str());
1427     programCollection.glslSources.add("pipeline_geom") << glu::GeometrySource(pipeline_geom.str());
1428     programCollection.glslSources.add("pipeline_frag") << glu::FragmentSource(pipeline_frag.str());
1429 }
1430 
1431 } // namespace
1432 
createShaderObjectPipelineInteractionTests(tcu::TestContext & testCtx)1433 tcu::TestCaseGroup *createShaderObjectPipelineInteractionTests(tcu::TestContext &testCtx)
1434 {
1435     de::MovePtr<tcu::TestCaseGroup> pipelineInteractionGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interaction"));
1436 
1437     const struct
1438     {
1439         TestType testType;
1440         const char *name;
1441     } tests[] = {
1442         {SHADER_OBJECT, "shader_object"},
1443         {MAX_PIPELINE, "max_pipeline"},
1444         {MAX_PIPELINE_SHADER_OBJECT_MAX_PIPELINE, "max_pipeline_shader_object_max_pipeline"},
1445         {SHADER_OBJECT_MAX_PIPELINE_SHADER_OBJECT, "shader_object_max_pipeline_shader_object"},
1446         {MIN_PIPELINE_SHADER_OBJECT, "min_pipeline_shader_object"},
1447         {SHADER_OBJECT_MIN_PIPELINE, "shader_object_min_pipeline"},
1448         {RENDER_PASS_PIPELINE_SHADER_OBJECT, "render_pass_pipeline_shader_object"},
1449         {RENDER_PASS_PIPELINE_SHADER_OBJECT_AFTER_BEGIN, "render_pass_pipeline_shader_object_after_begin"},
1450         {COMPUTE_SHADER_OBJECT_MIN_PIPELINE, "compute_shader_object_min_pipeline"},
1451         {SHADER_OBJECT_COMPUTE_PIPELINE, "shader_object_compute_pipeline"},
1452     };
1453 
1454     for (const auto &test : tests)
1455     {
1456         TestParams params;
1457         params.testType = test.testType;
1458 
1459         pipelineInteractionGroup->addChild(new ShaderObjectPipelineInteractionCase(testCtx, test.name, params));
1460     }
1461 
1462     const struct
1463     {
1464         StageTestParams shaders;
1465         const char *name;
1466     } shaderBindTests[] = {
1467         {{true, false, false, false}, "vert"},         {{true, true, false, false}, "vert_tess"},
1468         {{true, false, true, false}, "vert_geom"},     {{true, false, false, true}, "vert_frag"},
1469         {{true, true, true, false}, "vert_tess_geom"}, {{true, true, false, true}, "vert_tess_frag"},
1470         {{true, false, true, true}, "vert_geom_frag"}, {{true, true, true, true}, "vert_tess_geom_frag"},
1471     };
1472 
1473     for (const auto &shaderBindTest : shaderBindTests)
1474     {
1475         pipelineInteractionGroup->addChild(
1476             new ShaderObjectStageBindingCase(testCtx, shaderBindTest.name, shaderBindTest.shaders));
1477     }
1478 
1479     return pipelineInteractionGroup.release();
1480 }
1481 
1482 } // namespace ShaderObject
1483 } // namespace vkt
1484