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 Misc Tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktShaderObjectMiscTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuTestCase.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkShaderObjectUtil.hpp"
30 #include "vktShaderObjectCreateUtil.hpp"
31 #include "vkBufferWithMemory.hpp"
32 #include "vkImageWithMemory.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "deMath.hpp"
40 #include "vktCustomInstancesDevices.hpp"
41 #include "tcuCommandLine.hpp"
42 #include "tcuTextureUtil.hpp"
43 
44 namespace vkt
45 {
46 namespace ShaderObject
47 {
48 
49 namespace
50 {
51 
52 struct TestParams
53 {
54     bool blendEnabled[2];
55     bool vertexInputBefore;
56     bool vertexBuffersNullStride;
57     uint32_t stride;
58     bool destroyDescriptorSetLayout;
59 };
60 
findDSFormat(const vk::InstanceInterface & vki,const vk::VkPhysicalDevice physicalDevice)61 vk::VkFormat findDSFormat(const vk::InstanceInterface &vki, const vk::VkPhysicalDevice physicalDevice)
62 {
63     const vk::VkFormat dsFormats[] = {
64         vk::VK_FORMAT_D24_UNORM_S8_UINT,
65         vk::VK_FORMAT_D32_SFLOAT_S8_UINT,
66         vk::VK_FORMAT_D16_UNORM_S8_UINT,
67     };
68 
69     for (uint32_t i = 0; i < 3; ++i)
70     {
71         const vk::VkFormatProperties formatProperties =
72             getPhysicalDeviceFormatProperties(vki, physicalDevice, dsFormats[i]);
73         if ((formatProperties.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
74             return dsFormats[i];
75     }
76     return vk::VK_FORMAT_UNDEFINED;
77 }
78 
79 class ShaderObjectMiscInstance : public vkt::TestInstance
80 {
81 public:
ShaderObjectMiscInstance(Context & context,const TestParams & params)82     ShaderObjectMiscInstance(Context &context, const TestParams &params) : vkt::TestInstance(context), m_params(params)
83     {
84     }
~ShaderObjectMiscInstance(void)85     virtual ~ShaderObjectMiscInstance(void)
86     {
87     }
88 
89     tcu::TestStatus iterate(void) override;
90 
91 private:
92     void setVertexInput(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize stride) const;
93     void bindVertexBuffers(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkDeviceSize *stride,
94                            vk::VkBuffer buffer, vk::VkDeviceSize bufferSize) const;
95     TestParams m_params;
96 };
97 
setVertexInput(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkDeviceSize stride) const98 void ShaderObjectMiscInstance::setVertexInput(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
99                                               vk::VkDeviceSize stride) const
100 {
101     vk::VkVertexInputBindingDescription2EXT bindingDescription     = vk::initVulkanStructure();
102     bindingDescription.binding                                     = 0u;
103     bindingDescription.stride                                      = (uint32_t)stride;
104     bindingDescription.inputRate                                   = vk::VK_VERTEX_INPUT_RATE_VERTEX;
105     bindingDescription.divisor                                     = 1u;
106     vk::VkVertexInputAttributeDescription2EXT attributeDescription = vk::initVulkanStructure();
107     attributeDescription.location                                  = 0u;
108     attributeDescription.binding                                   = 0u;
109     attributeDescription.format                                    = vk::VK_FORMAT_R32G32B32A32_SFLOAT;
110     attributeDescription.offset                                    = 0u;
111     vk.cmdSetVertexInputEXT(cmdBuffer, 1u, &bindingDescription, 1u, &attributeDescription);
112 }
113 
bindVertexBuffers(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkDeviceSize * stride,vk::VkBuffer buffer,vk::VkDeviceSize bufferSize) const114 void ShaderObjectMiscInstance::bindVertexBuffers(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
115                                                  vk::VkDeviceSize *stride, vk::VkBuffer buffer,
116                                                  vk::VkDeviceSize bufferSize) const
117 {
118     vk::VkDeviceSize offset = 0u;
119     vk.cmdBindVertexBuffers2(cmdBuffer, 0u, 1u, &buffer, &offset, &bufferSize, stride);
120 }
121 
iterate(void)122 tcu::TestStatus ShaderObjectMiscInstance::iterate(void)
123 {
124     const vk::VkInstance instance = m_context.getInstance();
125     const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
126     const vk::DeviceInterface &vk   = m_context.getDeviceInterface();
127     const vk::VkDevice device       = m_context.getDevice();
128     const vk::VkQueue queue         = m_context.getUniversalQueue();
129     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
130     auto &alloc                     = m_context.getDefaultAllocator();
131     tcu::TestLog &log               = m_context.getTestContext().getLog();
132     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
133         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
134     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
135     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
136     const bool taskSupported         = m_context.getMeshShaderFeaturesEXT().taskShader;
137     const bool meshSupported         = m_context.getMeshShaderFeaturesEXT().meshShader;
138 
139     vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
140     const auto subresourceRange        = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
141     const auto subresourceLayers       = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
142     const vk::VkRect2D renderArea      = vk::makeRect2D(0, 0, 32, 32);
143     vk::VkExtent3D extent              = {renderArea.extent.width, renderArea.extent.height, 1};
144 
145     const vk::VkImageCreateInfo createInfo = {
146         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
147         DE_NULL,                                 // const void*                pNext
148         0u,                                      // VkImageCreateFlags        flags
149         vk::VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
150         colorAttachmentFormat,                   // VkFormat                    format
151         {32, 32, 1},                             // VkExtent3D                extent
152         1u,                                      // uint32_t                    mipLevels
153         1u,                                      // uint32_t                    arrayLayers
154         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
155         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
156         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
157         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
158         0,                             // uint32_t                    queueFamilyIndexCount
159         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
160         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
161     };
162 
163     const uint32_t colorAttachmentCount = 2;
164 
165     std::vector<de::MovePtr<vk::ImageWithMemory>> images(colorAttachmentCount);
166     std::vector<vk::Move<vk::VkImageView>> imageViews(colorAttachmentCount);
167     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
168     {
169         images[i] = de::MovePtr<vk::ImageWithMemory>(
170             new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
171         imageViews[i] = vk::makeImageView(vk, device, **images[i], vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat,
172                                           subresourceRange);
173     }
174 
175     const vk::VkDeviceSize colorOutputBufferSize =
176         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
177     std::vector<de::MovePtr<vk::BufferWithMemory>> colorOutputBuffers(colorAttachmentCount);
178     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
179     {
180         colorOutputBuffers[i] = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
181             vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
182             vk::MemoryRequirement::HostVisible));
183     }
184 
185     const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
186     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
187         vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
188 
189     vk::Move<vk::VkDescriptorSetLayout> descriptorSetLayout(
190         vk::DescriptorSetLayoutBuilder()
191             .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT)
192             .build(vk, device));
193 
194     const vk::Unique<vk::VkDescriptorPool> descriptorPool(
195         vk::DescriptorPoolBuilder()
196             .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
197             .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
198 
199     const vk::VkDeviceSize bufferSizeBytes = sizeof(tcu::Vec4);
200     const vk::Unique<vk::VkDescriptorSet> descriptorSet(
201         makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
202     const vk::BufferWithMemory inputBuffer(
203         vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
204         vk::MemoryRequirement::HostVisible);
205 
206     const vk::VkDescriptorBufferInfo descriptorInfo = vk::makeDescriptorBufferInfo(*inputBuffer, 0ull, bufferSizeBytes);
207     vk::DescriptorSetUpdateBuilder()
208         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
209                      vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
210         .update(vk, device);
211     const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
212 
213     float *inputDataPtr = reinterpret_cast<float *>(inputBuffer.getAllocation().getHostPtr());
214     memset(inputDataPtr, 0, bufferSizeBytes);
215     for (uint32_t i = 0; i < 4; ++i)
216         inputDataPtr[i] = 0.5f;
217     flushAlloc(vk, device, inputBuffer.getAllocation());
218 
219     const auto &binaries = m_context.getBinaryCollection();
220     const auto vertShader =
221         vk::createShader(vk, device,
222                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("inputVert"),
223                                                   tessellationSupported, geometrySupported, &*descriptorSetLayout));
224     const auto fragShader =
225         vk::createShader(vk, device,
226                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("multiFrag"),
227                                                   tessellationSupported, geometrySupported, &*descriptorSetLayout));
228 
229     const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
230     vk::beginCommandBuffer(vk, *cmdBuffer);
231 
232     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
233     {
234         vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
235             vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
236             vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
237         vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
238                               vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
239                               (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
240                               &preImageBarrier);
241     }
242 
243     std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(colorAttachmentCount);
244     vk::VkRenderingAttachmentInfoKHR colorAttachment{
245         vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
246         DE_NULL,                                             // const void* pNext;
247         VK_NULL_HANDLE,                                      // VkImageView imageView;
248         vk::VK_IMAGE_LAYOUT_GENERAL,                         // VkImageLayout imageLayout;
249         vk::VK_RESOLVE_MODE_NONE,                            // VkResolveModeFlagBits resolveMode;
250         DE_NULL,                                             // VkImageView resolveImageView;
251         vk::VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout resolveImageLayout;
252         vk::VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp loadOp;
253         vk::VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp storeOp;
254         clearValue                                           // VkClearValue clearValue;
255     };
256 
257     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
258     {
259         colorAttachment.imageView = *imageViews[i];
260         colorAttachments[i]       = colorAttachment;
261     }
262 
263     vk::VkRenderingInfoKHR renderingInfo{
264         vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
265         DE_NULL,
266         (vk::VkRenderingFlags)0u,          // VkRenderingFlagsKHR flags;
267         renderArea,                        // VkRect2D renderArea;
268         1u,                                // uint32_t layerCount;
269         0x0,                               // uint32_t viewMask;
270         (uint32_t)colorAttachments.size(), // uint32_t colorAttachmentCount;
271         colorAttachments.data(),           // const VkRenderingAttachmentInfoKHR* pColorAttachments;
272         DE_NULL,                           // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
273         DE_NULL,                           // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
274     };
275 
276     const vk::VkDeviceSize bufferSize        = 1024;
277     de::MovePtr<vk::BufferWithMemory> buffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
278         vk, device, alloc, vk::makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
279         vk::MemoryRequirement::HostVisible));
280     float *dataPtr                           = reinterpret_cast<float *>(buffer->getAllocation().getHostPtr());
281     memset(dataPtr, 0, bufferSize);
282     for (uint32_t i = 0; i < 4; ++i)
283     {
284         dataPtr[i * (m_params.stride / sizeof(float)) + 0] = float(i & 1);
285         dataPtr[i * (m_params.stride / sizeof(float)) + 1] = float((i >> 1) & 1);
286         dataPtr[i * (m_params.stride / sizeof(float)) + 2] = 0.0f;
287         dataPtr[i * (m_params.stride / sizeof(float)) + 3] = 1.0f;
288     }
289     flushAlloc(vk, device, buffer->getAllocation());
290 
291     vk::Move<vk::VkDescriptorSetLayout> null;
292     if (m_params.destroyDescriptorSetLayout)
293         descriptorSetLayout = null;
294 
295     vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
296     vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
297                                             false);
298 
299     vk::VkColorBlendEquationEXT colorBlendEquation = {
300         vk::VK_BLEND_FACTOR_ONE,                 // VkBlendFactor srcColorBlendFactor;
301         vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
302         vk::VK_BLEND_OP_ADD,                     // VkBlendOp colorBlendOp;
303         vk::VK_BLEND_FACTOR_ONE,                 // VkBlendFactor srcAlphaBlendFactor;
304         vk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
305         vk::VK_BLEND_OP_ADD,                     // VkBlendOp alphaBlendOp;
306     };
307     vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
308                                                vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
309     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
310     {
311         vk::VkBool32 colorBlendEnable = m_params.blendEnabled[i] ? VK_TRUE : VK_FALSE;
312         vk.cmdSetColorBlendEnableEXT(*cmdBuffer, i, 1u, &colorBlendEnable);
313         if (m_params.blendEnabled[i])
314         {
315             vk.cmdSetColorBlendEquationEXT(*cmdBuffer, i, 1u, &colorBlendEquation);
316         }
317         vk.cmdSetColorWriteMaskEXT(*cmdBuffer, i, 1u, &colorWriteMask);
318     }
319     const vk::VkPhysicalDeviceProperties properties =
320         vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
321     std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
322     for (uint32_t i = 0; i < properties.limits.maxColorAttachments; ++i)
323     {
324         colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
325     }
326     vk.cmdSetColorWriteEnableEXT(*cmdBuffer, properties.limits.maxColorAttachments, colorWriteEnables.data());
327 
328     if (m_params.vertexInputBefore)
329         setVertexInput(vk, *cmdBuffer, m_params.vertexBuffersNullStride ? m_params.stride : 100);
330 
331     vk::VkDeviceSize stride   = m_params.stride;
332     vk::VkDeviceSize *pStride = m_params.vertexBuffersNullStride ? DE_NULL : &stride;
333     bindVertexBuffers(vk, *cmdBuffer, pStride, **buffer, bufferSize);
334 
335     if (!m_params.vertexInputBefore)
336         setVertexInput(vk, *cmdBuffer, m_params.stride);
337 
338     vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
339                              &descriptorSet.get(), 0, DE_NULL);
340 
341     vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader,
342                             taskSupported, meshSupported);
343     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
344     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
345 
346     vk::endRendering(vk, *cmdBuffer);
347 
348     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
349     {
350         vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(
351             vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
352             vk::VK_IMAGE_LAYOUT_GENERAL, **images[i], subresourceRange);
353         vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
354                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
355                               (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
356                               &postImageBarrier);
357     }
358 
359     const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
360     for (uint32_t i = 0; i < colorAttachmentCount; ++i)
361         vk.cmdCopyImageToBuffer(*cmdBuffer, **images[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u,
362                                 &copyRegion);
363 
364     vk::endCommandBuffer(vk, *cmdBuffer);
365 
366     vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
367 
368     const int32_t width        = renderArea.extent.width;
369     const int32_t height       = renderArea.extent.height;
370     const float threshold      = 1.0f / 256.0f;
371     const int32_t xOffset      = width / 8;
372     const int32_t yOffset      = height / 8;
373     const tcu::Vec4 refColor1  = tcu::Vec4(0.75f, 0.75f, 0.75f, 0.75f);
374     const tcu::Vec4 refColor2  = tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f);
375     const tcu::Vec4 blackColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
376 
377     for (uint32_t k = 0; k < colorAttachmentCount; ++k)
378     {
379         tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
380             vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
381             (const void *)colorOutputBuffers[k]->getAllocation().getHostPtr());
382         for (int32_t j = 0; j < height; ++j)
383         {
384             for (int32_t i = 0; i < width; ++i)
385             {
386                 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
387 
388                 tcu::Vec4 expectedColor = blackColor;
389                 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
390                 {
391                     if (m_params.blendEnabled[k])
392                         expectedColor = refColor1;
393                     else
394                         expectedColor = refColor2;
395                 }
396 
397                 if (deFloatAbs(color.x() - expectedColor.x()) > threshold ||
398                     deFloatAbs(color.y() - expectedColor.y()) > threshold ||
399                     deFloatAbs(color.z() - expectedColor.z()) > threshold ||
400                     deFloatAbs(color.w() - expectedColor.w()) > threshold)
401                 {
402                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") was " << color
403                         << ", but expected color was " << expectedColor << tcu::TestLog::EndMessage;
404                     return tcu::TestStatus::fail("Fail");
405                 }
406             }
407         }
408     }
409 
410     return tcu::TestStatus::pass("Pass");
411 }
412 
413 class ShaderObjectMiscCase : public vkt::TestCase
414 {
415 public:
ShaderObjectMiscCase(tcu::TestContext & testCtx,const std::string & name,const TestParams & params)416     ShaderObjectMiscCase(tcu::TestContext &testCtx, const std::string &name, const TestParams &params)
417         : vkt::TestCase(testCtx, name)
418         , m_params(params)
419     {
420     }
~ShaderObjectMiscCase(void)421     virtual ~ShaderObjectMiscCase(void)
422     {
423     }
424 
425     void checkSupport(vkt::Context &context) const override;
426     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const427     TestInstance *createInstance(Context &context) const override
428     {
429         return new ShaderObjectMiscInstance(context, m_params);
430     }
431 
432 private:
433     TestParams m_params;
434 };
435 
checkSupport(Context & context) const436 void ShaderObjectMiscCase::checkSupport(Context &context) const
437 {
438     context.requireDeviceFunctionality("VK_EXT_shader_object");
439 }
440 
initPrograms(vk::SourceCollections & programCollection) const441 void ShaderObjectMiscCase::initPrograms(vk::SourceCollections &programCollection) const
442 {
443     std::stringstream inputVert;
444     std::stringstream multiFrag;
445 
446     inputVert << "#version 450\n"
447               << "layout(location = 0) in vec4 inPos;\n"
448               << "void main() {\n"
449               << "    gl_Position = vec4((inPos.xy - 0.5f) * 1.5f, inPos.zw);\n"
450               << "}\n";
451 
452     multiFrag << "#version 450\n"
453               << "layout(set=0, binding=0) readonly buffer inputBuf {\n"
454               << "    vec4 color;\n"
455               << "};\n"
456               << "layout (location=0) out vec4 outColor0;\n"
457               << "layout (location=1) out vec4 outColor1;\n"
458               << "void main() {\n"
459               << "    outColor0 = color;\n"
460               << "    outColor1 = color;\n"
461               << "}\n";
462 
463     programCollection.glslSources.add("inputVert") << glu::VertexSource(inputVert.str());
464     programCollection.glslSources.add("multiFrag") << glu::FragmentSource(multiFrag.str());
465 }
466 
readDepthAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,uint32_t queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)467 de::MovePtr<tcu::TextureLevel> readDepthAttachment(const vk::DeviceInterface &vk, vk::VkDevice device,
468                                                    vk::VkQueue queue, uint32_t queueFamilyIndex,
469                                                    vk::Allocator &allocator, vk::VkImage image, vk::VkFormat format,
470                                                    const tcu::UVec2 &renderSize, vk::VkImageLayout currentLayout)
471 {
472     vk::Move<vk::VkBuffer> buffer;
473     de::MovePtr<vk::Allocation> bufferAlloc;
474     vk::Move<vk::VkCommandPool> cmdPool;
475     vk::Move<vk::VkCommandBuffer> cmdBuffer;
476 
477     tcu::TextureFormat retFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
478     tcu::TextureFormat bufferFormat(tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST);
479     const vk::VkImageAspectFlags barrierAspect =
480         vk::VK_IMAGE_ASPECT_DEPTH_BIT |
481         (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT :
482                                                                (vk::VkImageAspectFlagBits)0);
483 
484     switch (format)
485     {
486     case vk::VK_FORMAT_D16_UNORM:
487     case vk::VK_FORMAT_D16_UNORM_S8_UINT:
488         bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16;
489         break;
490     case vk::VK_FORMAT_D24_UNORM_S8_UINT:
491     case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
492         retFormat.type = tcu::TextureFormat::UNORM_INT24;
493         // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
494         bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV;
495         break;
496     case vk::VK_FORMAT_D32_SFLOAT:
497     case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
498         bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT;
499         break;
500     default:
501         TCU_FAIL("unrecognized format");
502     }
503 
504     const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
505     de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
506 
507     // Create destination buffer
508     {
509         const vk::VkBufferCreateInfo bufferParams = {
510             vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
511             DE_NULL,                                  // const void* pNext;
512             0u,                                       // VkBufferCreateFlags flags;
513             pixelDataSize,                            // VkDeviceSize size;
514             vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
515             vk::VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
516             0u,                                       // uint32_t queueFamilyIndexCount;
517             DE_NULL                                   // const uint32_t* pQueueFamilyIndices;
518         };
519 
520         buffer = createBuffer(vk, device, &bufferParams);
521         bufferAlloc =
522             allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
523         VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
524     }
525 
526     // Create command pool and buffer
527     cmdPool   = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
528     cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
529 
530     beginCommandBuffer(vk, *cmdBuffer);
531     copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()),
532                       vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect,
533                       vk::VK_IMAGE_ASPECT_DEPTH_BIT);
534     endCommandBuffer(vk, *cmdBuffer);
535 
536     submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
537 
538     // Read buffer data
539     invalidateAlloc(vk, device, *bufferAlloc);
540     tcu::copy(*resultLevel,
541               tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
542 
543     return resultLevel;
544 }
545 
readStencilAttachment(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkQueue queue,uint32_t queueFamilyIndex,vk::Allocator & allocator,vk::VkImage image,vk::VkFormat format,const tcu::UVec2 & renderSize,vk::VkImageLayout currentLayout)546 de::MovePtr<tcu::TextureLevel> readStencilAttachment(const vk::DeviceInterface &vk, vk::VkDevice device,
547                                                      vk::VkQueue queue, uint32_t queueFamilyIndex,
548                                                      vk::Allocator &allocator, vk::VkImage image, vk::VkFormat format,
549                                                      const tcu::UVec2 &renderSize, vk::VkImageLayout currentLayout)
550 {
551     vk::Move<vk::VkBuffer> buffer;
552     de::MovePtr<vk::Allocation> bufferAlloc;
553     vk::Move<vk::VkCommandPool> cmdPool;
554     vk::Move<vk::VkCommandBuffer> cmdBuffer;
555 
556     tcu::TextureFormat retFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
557     tcu::TextureFormat bufferFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
558 
559     const vk::VkImageAspectFlags barrierAspect =
560         vk::VK_IMAGE_ASPECT_STENCIL_BIT |
561         (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_DEPTH_BIT :
562                                                                (vk::VkImageAspectFlagBits)0);
563     const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize();
564     de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y()));
565 
566     // Create destination buffer
567     {
568         const vk::VkBufferCreateInfo bufferParams = {
569             vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
570             DE_NULL,                                  // const void* pNext;
571             0u,                                       // VkBufferCreateFlags flags;
572             pixelDataSize,                            // VkDeviceSize size;
573             vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
574             vk::VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
575             0u,                                       // uint32_t queueFamilyIndexCount;
576             DE_NULL                                   // const uint32_t* pQueueFamilyIndices;
577         };
578 
579         buffer = createBuffer(vk, device, &bufferParams);
580         bufferAlloc =
581             allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible);
582         VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
583     }
584 
585     // Create command pool and buffer
586     cmdPool   = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
587     cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
588 
589     beginCommandBuffer(vk, *cmdBuffer);
590     copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()),
591                       vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect,
592                       vk::VK_IMAGE_ASPECT_STENCIL_BIT);
593     endCommandBuffer(vk, *cmdBuffer);
594 
595     submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
596 
597     // Read buffer data
598     invalidateAlloc(vk, device, *bufferAlloc);
599     tcu::copy(*resultLevel,
600               tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr()));
601 
602     return resultLevel;
603 }
604 
605 struct StateTestParams
606 {
607     bool pipeline;
608     bool meshShader;
609     bool vertShader;
610     bool tessShader;
611     bool geomShader;
612     bool fragShader;
613     bool logicOp;
614     bool alphaToOne;
615     bool depthBounds;
616     bool depthClamp;
617     bool depthClip;
618     bool depthClipControl;
619     bool colorWrite;
620     bool geometryStreams;
621     bool discardRectangles;
622     bool conservativeRasterization;
623     bool rasterizerDiscardEnable;
624     bool lines;
625     bool sampleLocations;
626     bool provokingVertex;
627     bool lineRasterization;
628     bool cull;
629     bool stencilTestEnable;
630     bool depthTestEnable;
631     bool depthBiasEnable;
632     bool depthBoundsTestEnable;
633     bool logicOpEnable;
634     bool colorBlendEnable;
635     bool discardRectanglesEnable;
636     bool sampleLocationsEnable;
637     bool conservativeRasterizationOverestimate;
638     bool stippledLineEnable;
639     bool colorWriteEnable;
640 
resetvkt::ShaderObject::__anon63aebed30111::StateTestParams641     void reset()
642     {
643         logicOp                               = false;
644         alphaToOne                            = false;
645         depthBounds                           = false;
646         depthClamp                            = false;
647         depthClip                             = false;
648         depthClipControl                      = false;
649         colorWrite                            = true;
650         geometryStreams                       = false;
651         discardRectangles                     = false;
652         conservativeRasterization             = false;
653         rasterizerDiscardEnable               = false;
654         lines                                 = false;
655         sampleLocations                       = false;
656         provokingVertex                       = false;
657         lineRasterization                     = false;
658         cull                                  = false;
659         stencilTestEnable                     = false;
660         depthTestEnable                       = false;
661         depthBiasEnable                       = false;
662         depthBoundsTestEnable                 = false;
663         logicOpEnable                         = false;
664         colorBlendEnable                      = false;
665         discardRectanglesEnable               = false;
666         sampleLocationsEnable                 = false;
667         conservativeRasterizationOverestimate = false;
668         stippledLineEnable                    = false;
669         colorWriteEnable                      = true;
670     }
671 };
672 
673 class ShaderObjectStateInstance : public vkt::TestInstance
674 {
675 public:
ShaderObjectStateInstance(Context & context,const StateTestParams & testParams)676     ShaderObjectStateInstance(Context &context, const StateTestParams &testParams)
677         : vkt::TestInstance(context)
678         , m_params(testParams)
679     {
680     }
~ShaderObjectStateInstance(void)681     virtual ~ShaderObjectStateInstance(void)
682     {
683     }
684 
685     tcu::TestStatus iterate(void) override;
686 
687 private:
688     void createDevice(void);
689     std::vector<vk::VkDynamicState> getDynamicStates(void) const;
690     bool hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates, const vk::VkDynamicState dynamicState);
691     void setDynamicStates(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer);
692     bool isInsidePrimitive(uint32_t i, uint32_t j, uint32_t width, uint32_t height);
693 
694     vk::Move<vk::VkDevice> m_customDevice;
695     de::MovePtr<vk::DeviceDriver> m_logicalDeviceInterface;
696     vk::VkQueue m_logicalDeviceQueue;
697     const StateTestParams m_params;
698 };
699 
createDevice(void)700 void ShaderObjectStateInstance::createDevice(void)
701 {
702     vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatuers               = vk::initVulkanStructure();
703     vk::VkPhysicalDeviceColorWriteEnableFeaturesEXT colorWriteEnableFeatures   = vk::initVulkanStructure();
704     vk::VkPhysicalDeviceDepthClipControlFeaturesEXT depthClipControlFeatures   = vk::initVulkanStructure();
705     vk::VkPhysicalDeviceDepthClipEnableFeaturesEXT depthClipEnableFeatures     = vk::initVulkanStructure();
706     vk::VkPhysicalDeviceTransformFeedbackFeaturesEXT transformFeedbackFeatures = vk::initVulkanStructure();
707     vk::VkPhysicalDeviceLineRasterizationFeaturesEXT lineRasterizationFeatures = vk::initVulkanStructure();
708 
709     vk::VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = m_context.getDynamicRenderingFeatures();
710     vk::VkPhysicalDeviceShaderObjectFeaturesEXT shaderObjectFeatures      = m_context.getShaderObjectFeaturesEXT();
711 
712     vk::VkPhysicalDeviceExtendedDynamicStateFeaturesEXT edsFeatures   = m_context.getExtendedDynamicStateFeaturesEXT();
713     vk::VkPhysicalDeviceExtendedDynamicState2FeaturesEXT eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
714     vk::VkPhysicalDeviceExtendedDynamicState3FeaturesEXT eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
715     vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT viFeatures =
716         m_context.getVertexInputDynamicStateFeaturesEXT();
717 
718     dynamicRenderingFeatures.pNext = DE_NULL;
719     shaderObjectFeatures.pNext     = DE_NULL;
720     edsFeatures.pNext              = DE_NULL;
721     eds2Features.pNext             = DE_NULL;
722     eds3Features.pNext             = DE_NULL;
723     viFeatures.pNext               = DE_NULL;
724 
725     vk::VkPhysicalDeviceFeatures2 features2           = vk::initVulkanStructure();
726     features2.features.vertexPipelineStoresAndAtomics = VK_TRUE;
727     void *pNext                                       = &dynamicRenderingFeatures;
728 
729     const float queuePriority                  = 1.0f;
730     std::vector<const char *> deviceExtensions = {"VK_KHR_dynamic_rendering"};
731     if (m_params.pipeline)
732     {
733         const auto &deviceExts = m_context.getDeviceExtensions();
734         if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state") != deviceExts.end())
735         {
736             deviceExtensions.push_back("VK_EXT_extended_dynamic_state");
737             edsFeatures.pNext = pNext;
738             pNext             = &edsFeatures;
739         }
740         if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state2") != deviceExts.end())
741         {
742             deviceExtensions.push_back("VK_EXT_extended_dynamic_state2");
743             eds2Features.pNext = pNext;
744             pNext              = &eds2Features;
745         }
746         if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_extended_dynamic_state3") != deviceExts.end())
747         {
748             deviceExtensions.push_back("VK_EXT_extended_dynamic_state3");
749             eds3Features.pNext = pNext;
750             pNext              = &eds3Features;
751         }
752         if (std::find(deviceExts.begin(), deviceExts.end(), "VK_EXT_vertex_input_dynamic_state") != deviceExts.end())
753         {
754             deviceExtensions.push_back("VK_EXT_vertex_input_dynamic_state");
755             viFeatures.pNext = pNext;
756             pNext            = &viFeatures;
757         }
758     }
759     else
760     {
761         deviceExtensions.push_back("VK_EXT_shader_object");
762         dynamicRenderingFeatures.pNext = &shaderObjectFeatures;
763     }
764 
765     if (m_params.tessShader)
766         features2.features.tessellationShader = VK_TRUE;
767     if (m_params.geomShader)
768         features2.features.geometryShader = VK_TRUE;
769 
770     if (m_params.logicOp)
771         features2.features.logicOp = VK_TRUE;
772     if (m_params.alphaToOne)
773         features2.features.alphaToOne = VK_TRUE;
774     if (m_params.depthBounds)
775         features2.features.depthBounds = VK_TRUE;
776     if (m_params.depthClamp)
777         features2.features.depthClamp = VK_TRUE;
778     if (m_params.depthBiasEnable)
779         features2.features.depthBiasClamp = VK_TRUE;
780     if (m_params.depthClip)
781     {
782         depthClipEnableFeatures.pNext           = pNext;
783         pNext                                   = &depthClipEnableFeatures;
784         depthClipEnableFeatures.depthClipEnable = VK_TRUE;
785         deviceExtensions.push_back("VK_EXT_depth_clip_enable");
786     }
787     if (m_params.depthClipControl)
788     {
789         depthClipControlFeatures.pNext            = pNext;
790         pNext                                     = &depthClipControlFeatures;
791         depthClipControlFeatures.depthClipControl = VK_TRUE;
792         deviceExtensions.push_back("VK_EXT_depth_clip_control");
793     }
794     if (m_params.colorWrite)
795     {
796         colorWriteEnableFeatures.pNext            = pNext;
797         pNext                                     = &colorWriteEnableFeatures;
798         colorWriteEnableFeatures.colorWriteEnable = VK_TRUE;
799         deviceExtensions.push_back("VK_EXT_color_write_enable");
800     }
801     if (m_params.geometryStreams)
802     {
803         transformFeedbackFeatures.pNext             = pNext;
804         pNext                                       = &transformFeedbackFeatures;
805         transformFeedbackFeatures.transformFeedback = VK_TRUE;
806         transformFeedbackFeatures.geometryStreams   = VK_TRUE;
807         deviceExtensions.push_back("VK_EXT_transform_feedback");
808     }
809     if (m_params.sampleLocations)
810         deviceExtensions.push_back("VK_EXT_sample_locations");
811     if (m_params.discardRectangles)
812         deviceExtensions.push_back("VK_EXT_discard_rectangles");
813     if (m_params.conservativeRasterization)
814         deviceExtensions.push_back("VK_EXT_conservative_rasterization");
815     if (m_params.sampleLocations)
816         deviceExtensions.push_back("VK_EXT_sample_locations");
817     if (m_params.provokingVertex)
818         deviceExtensions.push_back("VK_EXT_provoking_vertex");
819     if (m_params.lineRasterization)
820     {
821         lineRasterizationFeatures.pNext            = pNext;
822         pNext                                      = &lineRasterizationFeatures;
823         lineRasterizationFeatures.rectangularLines = VK_TRUE;
824         const auto &deviceExts                     = m_context.getDeviceExtensions();
825         if (std::find(deviceExts.begin(), deviceExts.end(), "VK_KHR_line_rasterization") != deviceExts.end())
826         {
827             deviceExtensions.push_back("VK_KHR_line_rasterization");
828         }
829         else
830         {
831             deviceExtensions.push_back("VK_EXT_line_rasterization");
832         }
833     }
834     if (m_params.meshShader)
835     {
836         meshShaderFeatuers.pNext      = pNext;
837         pNext                         = &meshShaderFeatuers;
838         meshShaderFeatuers.meshShader = VK_TRUE;
839         deviceExtensions.push_back("VK_EXT_mesh_shader");
840     }
841 
842     features2.pNext = pNext;
843 
844     vk::VkDeviceQueueCreateInfo queueInfo = {
845         vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
846         DE_NULL,                                        // const void* pNext;
847         0u,                                             // VkDeviceQueueCreateFlags flags;
848         0u,                                             // uint32_t queueFamilyIndex;
849         1u,                                             // uint32_t queueCount;
850         &queuePriority                                  // const float* pQueuePriorities;
851     };
852 
853     const vk::VkDeviceCreateInfo deviceInfo = {
854         vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
855         &features2,                               // const void* pNext;
856         (vk::VkDeviceCreateFlags)0,               // VkDeviceCreateFlags flags;
857         1u,                                       // uint32_t queueCreateInfoCount;
858         &queueInfo,                               // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
859         0u,                                       // uint32_t enabledLayerCount;
860         DE_NULL,                                  // const char* const* ppEnabledLayerNames;
861         uint32_t(deviceExtensions.size()),        // uint32_t enabledExtensionCount;
862         deviceExtensions.data(),                  // const char* const* ppEnabledExtensionNames;
863         DE_NULL                                   // const VkPhysicalDeviceFeatures* pEnabledFeatures;
864     };
865 
866     m_customDevice           = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(),
867                                                   m_context.getPlatformInterface(), m_context.getInstance(),
868                                                   m_context.getInstanceInterface(), m_context.getPhysicalDevice(), &deviceInfo);
869     m_logicalDeviceInterface = de::MovePtr<vk::DeviceDriver>(
870         new vk::DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_customDevice,
871                              m_context.getUsedApiVersion(), m_context.getTestContext().getCommandLine()));
872     m_logicalDeviceInterface->getDeviceQueue(*m_customDevice, m_context.getUniversalQueueFamilyIndex(), 0,
873                                              &m_logicalDeviceQueue);
874 }
875 
getDynamicStates(void) const876 std::vector<vk::VkDynamicState> ShaderObjectStateInstance::getDynamicStates(void) const
877 {
878     const auto &edsFeatures  = m_context.getExtendedDynamicStateFeaturesEXT();
879     const auto &eds2Features = m_context.getExtendedDynamicState2FeaturesEXT();
880     const auto &eds3Features = m_context.getExtendedDynamicState3FeaturesEXT();
881     const auto &viFeatures   = m_context.getVertexInputDynamicStateFeaturesEXT();
882 
883     std::vector<vk::VkDynamicState> dynamicStates;
884 
885     if (edsFeatures.extendedDynamicState)
886     {
887         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT);
888         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT);
889     }
890 
891     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_WIDTH);
892     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS);
893     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS);
894     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS);
895     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
896     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
897     dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE);
898     if (edsFeatures.extendedDynamicState && !m_params.meshShader && !m_params.pipeline)
899         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE);
900     if (edsFeatures.extendedDynamicState)
901         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CULL_MODE);
902     if (edsFeatures.extendedDynamicState)
903         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE);
904     if (edsFeatures.extendedDynamicState)
905         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP);
906     if (edsFeatures.extendedDynamicState)
907         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE);
908     if (edsFeatures.extendedDynamicState)
909         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE);
910     if (edsFeatures.extendedDynamicState)
911         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRONT_FACE);
912     if (edsFeatures.extendedDynamicState && !m_params.meshShader)
913         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY);
914     if (edsFeatures.extendedDynamicState)
915         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP);
916     if (edsFeatures.extendedDynamicState)
917         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE);
918     if (eds2Features.extendedDynamicState2)
919         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE);
920     if (eds2Features.extendedDynamicState2 && !m_params.meshShader)
921         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
922     if (eds2Features.extendedDynamicState2)
923         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT);
924     if (viFeatures.vertexInputDynamicState && !m_params.meshShader && !m_params.pipeline)
925         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
926     if (eds2Features.extendedDynamicState2LogicOp)
927         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT);
928     if (eds2Features.extendedDynamicState2PatchControlPoints && !m_params.meshShader)
929         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT);
930     if (eds3Features.extendedDynamicState3TessellationDomainOrigin)
931         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT);
932     if (eds3Features.extendedDynamicState3DepthClampEnable)
933         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT);
934     if (eds3Features.extendedDynamicState3PolygonMode)
935         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT);
936     if (eds3Features.extendedDynamicState3RasterizationSamples)
937         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT);
938     if (eds3Features.extendedDynamicState3SampleMask)
939         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT);
940     if (eds3Features.extendedDynamicState3AlphaToCoverageEnable)
941         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT);
942     if (eds3Features.extendedDynamicState3AlphaToOneEnable)
943         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT);
944     if (eds3Features.extendedDynamicState3LogicOpEnable)
945         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT);
946     if (eds3Features.extendedDynamicState3ColorBlendEnable)
947         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
948     if (eds3Features.extendedDynamicState3ColorBlendEquation)
949         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
950     if (eds3Features.extendedDynamicState3ColorWriteMask)
951         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
952     if (eds3Features.extendedDynamicState3RasterizationStream && m_params.geometryStreams)
953         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
954     if (m_params.discardRectangles)
955         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
956     if (m_params.discardRectangles)
957         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
958     if (m_params.discardRectangles)
959         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
960     if (eds3Features.extendedDynamicState3ConservativeRasterizationMode && m_params.conservativeRasterization)
961         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
962     if (eds3Features.extendedDynamicState3ExtraPrimitiveOverestimationSize && m_params.conservativeRasterization)
963         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
964     if (eds3Features.extendedDynamicState3DepthClipEnable && m_params.depthClip)
965         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
966     if (eds3Features.extendedDynamicState3SampleLocationsEnable && m_params.sampleLocations)
967         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
968     if (m_params.sampleLocations)
969         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
970     if (eds3Features.extendedDynamicState3ProvokingVertexMode && m_params.provokingVertex)
971         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
972     if (eds3Features.extendedDynamicState3LineRasterizationMode && m_params.lineRasterization)
973         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
974     if (eds3Features.extendedDynamicState3LineStippleEnable && m_params.lineRasterization)
975         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
976     if (m_params.lineRasterization)
977         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT);
978     if (eds3Features.extendedDynamicState3DepthClipNegativeOneToOne && m_params.depthClipControl)
979         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
980     if (m_params.colorWrite)
981         dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
982     return dynamicStates;
983 }
984 
hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates,const vk::VkDynamicState dynamicState)985 bool ShaderObjectStateInstance::hasDynamicState(const std::vector<vk::VkDynamicState> dynamicStates,
986                                                 const vk::VkDynamicState dynamicState)
987 {
988     if (!m_params.pipeline)
989         return false;
990     return std::find(dynamicStates.begin(), dynamicStates.end(), dynamicState) != dynamicStates.end();
991 }
992 
extensionEnabled(const std::vector<std::string> & deviceExtensions,const std::string & ext)993 bool extensionEnabled(const std::vector<std::string> &deviceExtensions, const std::string &ext)
994 {
995     return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
996 }
997 
setDynamicStates(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer)998 void ShaderObjectStateInstance::setDynamicStates(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer)
999 {
1000     const auto dynamicStates    = getDynamicStates();
1001     const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(
1002         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1003 
1004     vk::VkViewport viewport = {
1005         0, 0, 32, 32, 0.0f, 1.0f,
1006     };
1007     if (m_params.depthClamp)
1008         viewport.maxDepth = 0.5f;
1009     if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT))
1010         vk.cmdSetViewportWithCount(cmdBuffer, 1u, &viewport);
1011     vk::VkRect2D scissor = {
1012         {
1013             0,
1014             0,
1015         },
1016         {
1017             32,
1018             32,
1019         },
1020     };
1021     if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT))
1022         vk.cmdSetScissorWithCount(cmdBuffer, 1u, &scissor);
1023     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.lines) ||
1024         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_WIDTH))
1025         vk.cmdSetLineWidth(cmdBuffer, 1.0f);
1026     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBiasEnable))
1027         vk.cmdSetDepthBias(cmdBuffer, 4.0f, 1.0f, 4.0f);
1028     else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS))
1029         vk.cmdSetDepthBias(cmdBuffer, 1.0f, 0.0f, 1.0f);
1030     float blendConstants[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1031     if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.colorBlendEnable) ||
1032         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS))
1033         vk.cmdSetBlendConstants(cmdBuffer, blendConstants);
1034     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBoundsTestEnable) ||
1035         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS))
1036         vk.cmdSetDepthBounds(cmdBuffer, 0.2f, 0.3f);
1037     vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1038     vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1039     vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, 0xFFFFFFFF);
1040     if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
1041         vk.cmdBindVertexBuffers2(cmdBuffer, 0, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL);
1042     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1043         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CULL_MODE))
1044         vk.cmdSetCullMode(cmdBuffer, m_params.cull ? vk::VK_CULL_MODE_FRONT_AND_BACK : vk::VK_CULL_MODE_NONE);
1045     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthBounds) ||
1046         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE))
1047         vk.cmdSetDepthBoundsTestEnable(cmdBuffer, m_params.depthBoundsTestEnable ? VK_TRUE : VK_FALSE);
1048     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1049         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP))
1050         vk.cmdSetDepthCompareOp(cmdBuffer, vk::VK_COMPARE_OP_LESS);
1051     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1052         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE))
1053         vk.cmdSetDepthTestEnable(cmdBuffer, m_params.depthTestEnable ? VK_TRUE : VK_FALSE);
1054     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1055         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE))
1056         vk.cmdSetDepthWriteEnable(cmdBuffer, VK_TRUE);
1057     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && (m_params.cull || m_params.stencilTestEnable)) ||
1058         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_FRONT_FACE))
1059         vk.cmdSetFrontFace(cmdBuffer, vk::VK_FRONT_FACE_CLOCKWISE);
1060     if ((!m_params.pipeline && m_params.vertShader) ||
1061         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY))
1062     {
1063         if (m_params.tessShader)
1064             vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
1065         else if (m_params.lines)
1066             vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
1067         else
1068             vk.cmdSetPrimitiveTopology(cmdBuffer, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
1069     }
1070     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.stencilTestEnable) ||
1071         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_OP))
1072         vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_AND_BACK, vk::VK_STENCIL_OP_REPLACE,
1073                            vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_REPLACE, vk::VK_COMPARE_OP_GREATER);
1074     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1075         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE))
1076         vk.cmdSetStencilTestEnable(cmdBuffer, m_params.stencilTestEnable ? VK_TRUE : VK_FALSE);
1077     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1078         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE))
1079         vk.cmdSetDepthBiasEnable(cmdBuffer, m_params.depthBiasEnable ? VK_TRUE : VK_FALSE);
1080     if ((!m_params.pipeline && m_params.vertShader) ||
1081         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE))
1082         vk.cmdSetPrimitiveRestartEnable(cmdBuffer, VK_FALSE);
1083     if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE))
1084         vk.cmdSetRasterizerDiscardEnable(cmdBuffer, m_params.rasterizerDiscardEnable ? VK_TRUE : VK_FALSE);
1085     if ((!m_params.pipeline && m_params.vertShader) ||
1086         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE))
1087         if (extensionEnabled(deviceExtensions, "VK_EXT_shader_object") ||
1088             extensionEnabled(deviceExtensions, "VK_EXT_vertex_input_dynamic_state"))
1089             vk.cmdSetVertexInputEXT(cmdBuffer, 0u, DE_NULL, 0u, DE_NULL);
1090     if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOpEnable) ||
1091         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT))
1092         vk.cmdSetLogicOpEXT(cmdBuffer, vk::VK_LOGIC_OP_COPY);
1093     if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT))
1094         vk.cmdSetPatchControlPointsEXT(cmdBuffer, 4u);
1095     if ((!m_params.pipeline && m_params.tessShader) ||
1096         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT))
1097         vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, vk::VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT);
1098     if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.depthClamp)
1099         vk.cmdSetDepthClampEnableEXT(cmdBuffer, VK_TRUE);
1100     else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT))
1101         vk.cmdSetDepthClampEnableEXT(cmdBuffer, m_params.depthClamp ? VK_TRUE : VK_FALSE);
1102     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1103         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT))
1104         vk.cmdSetPolygonModeEXT(cmdBuffer, vk::VK_POLYGON_MODE_FILL);
1105     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1106         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT))
1107         vk.cmdSetRasterizationSamplesEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT);
1108     vk::VkSampleMask sampleMask = 0xFFFFFFFF;
1109     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1110         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT))
1111         vk.cmdSetSampleMaskEXT(cmdBuffer, vk::VK_SAMPLE_COUNT_1_BIT, &sampleMask);
1112     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable) ||
1113         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT))
1114         vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, VK_FALSE);
1115     if (!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.alphaToOne)
1116         vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, VK_TRUE);
1117     else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT))
1118         vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, m_params.alphaToOne ? VK_TRUE : VK_FALSE);
1119     if (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable && m_params.logicOp)
1120         vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1121     else if (hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT))
1122         vk.cmdSetLogicOpEnableEXT(cmdBuffer, m_params.logicOpEnable ? VK_TRUE : VK_FALSE);
1123     vk::VkBool32 colorBlendEnable = m_params.colorBlendEnable ? VK_TRUE : VK_FALSE;
1124     if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1125         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT))
1126         vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0u, 1u, &colorBlendEnable);
1127     vk::VkColorBlendEquationEXT colorBlendEquation = {
1128         vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1129         vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
1130         vk::VK_BLEND_OP_ADD,     // VkBlendOp colorBlendOp;
1131         vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1132         vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
1133         vk::VK_BLEND_OP_ADD,     // VkBlendOp alphaBlendOp;
1134     };
1135     if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1136         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT))
1137         vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0u, 1u, &colorBlendEquation);
1138     vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT |
1139                                                vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT;
1140     if ((!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1141         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT))
1142         vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0u, 1u, &colorWriteMask);
1143     if ((!m_params.pipeline && m_params.geomShader && m_params.geometryStreams) ||
1144         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT))
1145         vk.cmdSetRasterizationStreamEXT(cmdBuffer, 0u);
1146     if (m_params.discardRectangles)
1147         vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, m_params.discardRectanglesEnable ? VK_TRUE : VK_FALSE);
1148     if ((!m_params.pipeline && m_params.discardRectanglesEnable) ||
1149         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT))
1150         vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, vk::VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT);
1151     if ((!m_params.pipeline && m_params.discardRectanglesEnable) ||
1152         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT))
1153         vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0u, 1u, &scissor);
1154     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization) ||
1155         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT))
1156         vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer,
1157                                                   m_params.conservativeRasterizationOverestimate ?
1158                                                       vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT :
1159                                                       vk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT);
1160     if ((!m_params.pipeline && !m_params.rasterizerDiscardEnable && m_params.conservativeRasterization &&
1161          m_params.conservativeRasterizationOverestimate) ||
1162         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT))
1163         vk.cmdSetExtraPrimitiveOverestimationSizeEXT(
1164             cmdBuffer,
1165             de::min(1.0f, m_context.getConservativeRasterizationPropertiesEXT().maxExtraPrimitiveOverestimationSize));
1166     if ((!m_params.pipeline && m_params.depthClip) ||
1167         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT))
1168         vk.cmdSetDepthClipEnableEXT(cmdBuffer, VK_TRUE);
1169     if ((!m_params.pipeline && m_params.sampleLocations) ||
1170         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT))
1171         vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, m_params.sampleLocationsEnable ? VK_TRUE : VK_FALSE);
1172     vk::VkSampleLocationEXT sampleLocation                 = {0.5f, 0.5f};
1173     const vk::VkSampleLocationsInfoEXT sampleLocationsInfo = {
1174         vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType               sType;
1175         DE_NULL,                                         // const void*                   pNext;
1176         vk::VK_SAMPLE_COUNT_1_BIT,                       // VkSampleCountFlagBits         sampleLocationsPerPixel;
1177         {1u, 1u},                                        // VkExtent2D                    sampleLocationGridSize;
1178         1,                                               // uint32_t                      sampleLocationsCount;
1179         &sampleLocation,                                 // const VkSampleLocationEXT*    pSampleLocations;
1180     };
1181     if ((!m_params.pipeline && m_params.sampleLocations && m_params.sampleLocationsEnable) ||
1182         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT))
1183         vk.cmdSetSampleLocationsEXT(cmdBuffer, &sampleLocationsInfo);
1184     if ((!m_params.pipeline && m_params.provokingVertex) ||
1185         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT))
1186         vk.cmdSetProvokingVertexModeEXT(cmdBuffer, vk::VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
1187     if (m_params.pipeline || (!m_params.rasterizerDiscardEnable && m_params.lineRasterization && m_params.lines))
1188     {
1189         if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT))
1190             vk.cmdSetLineRasterizationModeEXT(cmdBuffer, vk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT);
1191         if (!m_params.pipeline || hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT))
1192             vk.cmdSetLineStippleEnableEXT(cmdBuffer, m_params.stippledLineEnable ? VK_TRUE : VK_FALSE);
1193         if ((!m_params.pipeline && m_params.stippledLineEnable) ||
1194             hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT))
1195             vk.cmdSetLineStippleKHR(cmdBuffer, 1u, 0x1);
1196     }
1197     if ((!m_params.pipeline && m_params.depthClipControl) ||
1198         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT))
1199         vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, VK_TRUE);
1200     vk::VkBool32 colorWriteEnable = m_params.colorWriteEnable ? VK_TRUE : VK_FALSE;
1201     if ((!m_params.pipeline && m_params.colorWrite) ||
1202         hasDynamicState(dynamicStates, vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT))
1203         vk.cmdSetColorWriteEnableEXT(cmdBuffer, 1u, &colorWriteEnable);
1204 }
1205 
isInsidePrimitive(uint32_t i,uint32_t j,uint32_t width,uint32_t height)1206 bool ShaderObjectStateInstance::isInsidePrimitive(uint32_t i, uint32_t j, uint32_t width, uint32_t height)
1207 {
1208     uint32_t xOffset = width / 4;
1209     uint32_t yOffset = height / 4;
1210     if (m_params.tessShader)
1211         xOffset /= 2;
1212     if (m_params.geomShader)
1213         yOffset /= 2;
1214 
1215     bool inside = false;
1216     if (m_params.lines)
1217     {
1218         if (m_params.stippledLineEnable)
1219         {
1220             if (m_params.tessShader && m_params.geomShader)
1221                 inside = (j == 4 && i == 3) || (j == 20 && i == 3);
1222             else if (m_params.tessShader)
1223                 inside = (j == 8 && i == 3);
1224             else if (m_params.geomShader)
1225                 inside = (j == 3 && i == 8) || (j == 27 && i == 8);
1226             else
1227                 inside = (j == 7 && i == 8) || (j == 23 && i == 8);
1228         }
1229         else
1230         {
1231             if (m_params.tessShader && m_params.geomShader)
1232                 inside = m_params.lines && (i == 3 && (j >= 4 && j < 28));
1233             else if (m_params.tessShader)
1234                 inside = m_params.lines && (i == 3 && (j >= 8 && j < 24));
1235             else if (m_params.geomShader)
1236                 inside = m_params.lines && ((j == 3 || j == 27) && (i >= 8 && i < 24));
1237             else
1238                 inside = m_params.lines && (i >= 8 && i < 24 && (j == 7 || j == 23));
1239         }
1240     }
1241     else
1242     {
1243         inside = !m_params.lines && (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset);
1244     }
1245     return inside;
1246 }
1247 
iterate(void)1248 tcu::TestStatus ShaderObjectStateInstance::iterate(void)
1249 {
1250     const vk::VkInstance instance = m_context.getInstance();
1251     const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
1252     createDevice();
1253     const vk::DeviceInterface &vk   = *m_logicalDeviceInterface;
1254     const vk::VkDevice device       = *m_customDevice;
1255     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1256     const vk::VkQueue queue         = m_logicalDeviceQueue;
1257     auto alloctor                   = de::MovePtr<vk::Allocator>(new vk::SimpleAllocator(
1258         vk, device, getPhysicalDeviceMemoryProperties(instanceDriver, m_context.getPhysicalDevice())));
1259     auto &alloc                     = *alloctor;
1260     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
1261         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
1262     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
1263     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
1264     tcu::TestLog &log                = m_context.getTestContext().getLog();
1265 
1266     vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
1267     vk::VkFormat depthStencilAttachmentFormat =
1268         findDSFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
1269     const auto subresourceRange  = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1270     const auto subresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1271     auto depthSubresourceRange =
1272         vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
1273     const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, 32, 32);
1274     vk::VkExtent3D extent         = {renderArea.extent.width, renderArea.extent.height, 1};
1275 
1276     const bool taskSupported = m_context.getMeshShaderFeaturesEXT().taskShader;
1277     const bool meshSupported = m_context.getMeshShaderFeaturesEXT().meshShader;
1278 
1279     const vk::VkImageCreateInfo createInfo = {
1280         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
1281         DE_NULL,                                 // const void*                pNext
1282         0u,                                      // VkImageCreateFlags        flags
1283         vk::VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
1284         colorAttachmentFormat,                   // VkFormat                    format
1285         {32, 32, 1},                             // VkExtent3D                extent
1286         1u,                                      // uint32_t                    mipLevels
1287         1u,                                      // uint32_t                    arrayLayers
1288         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
1289         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
1290         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
1291         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
1292         0,                             // uint32_t                    queueFamilyIndexCount
1293         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
1294         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
1295     };
1296 
1297     const vk::VkImageCreateInfo depthCreateInfo = {
1298         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
1299         DE_NULL,                                 // const void*                pNext
1300         0u,                                      // VkImageCreateFlags        flags
1301         vk::VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
1302         depthStencilAttachmentFormat,            // VkFormat                    format
1303         {32, 32, 1},                             // VkExtent3D                extent
1304         1u,                                      // uint32_t                    mipLevels
1305         1u,                                      // uint32_t                    arrayLayers
1306         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
1307         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
1308         vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
1309             vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
1310         vk::VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
1311         0,                                       // uint32_t                    queueFamilyIndexCount
1312         DE_NULL,                                 // const uint32_t*            pQueueFamilyIndices
1313         vk::VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
1314     };
1315 
1316     de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
1317         new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1318     const auto imageView =
1319         vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
1320 
1321     de::MovePtr<vk::ImageWithMemory> depthImage = de::MovePtr<vk::ImageWithMemory>(
1322         new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any));
1323     const auto depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D,
1324                                                   depthStencilAttachmentFormat, depthSubresourceRange);
1325 
1326     const vk::VkDeviceSize colorOutputBufferSize =
1327         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
1328     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
1329         vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
1330         vk::MemoryRequirement::HostVisible));
1331 
1332     const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
1333     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
1334         vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1335 
1336     const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout(
1337         vk::DescriptorSetLayoutBuilder()
1338             .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1339                               vk::VK_SHADER_STAGE_ALL_GRAPHICS | vk::VK_SHADER_STAGE_MESH_BIT_EXT)
1340             .build(vk, device));
1341 
1342     const vk::Unique<vk::VkDescriptorPool> descriptorPool(
1343         vk::DescriptorPoolBuilder()
1344             .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1345             .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1346 
1347     const vk::VkDeviceSize bufferSizeBytes = sizeof(uint32_t) * 8;
1348     const vk::Unique<vk::VkDescriptorSet> descriptorSet(
1349         makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1350     const vk::BufferWithMemory outputBuffer(
1351         vk, device, alloc, vk::makeBufferCreateInfo(bufferSizeBytes, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
1352         vk::MemoryRequirement::HostVisible);
1353 
1354     const vk::VkDescriptorBufferInfo descriptorInfo =
1355         vk::makeDescriptorBufferInfo(*outputBuffer, 0ull, bufferSizeBytes);
1356     vk::DescriptorSetUpdateBuilder()
1357         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1358                      vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1359         .update(vk, device);
1360 
1361     const auto pipelineLayout = makePipelineLayout(vk, device, *descriptorSetLayout);
1362 
1363     const auto &binaries = m_context.getBinaryCollection();
1364     vk::Move<vk::VkPipeline> pipeline;
1365     vk::Move<vk::VkShaderEXT> meshShader;
1366     vk::Move<vk::VkShaderEXT> vertShader;
1367     vk::Move<vk::VkShaderEXT> tescShader;
1368     vk::Move<vk::VkShaderEXT> teseShader;
1369     vk::Move<vk::VkShaderEXT> geomShader;
1370     vk::Move<vk::VkShaderEXT> fragShader;
1371 
1372     if (m_params.pipeline)
1373     {
1374         vk::Move<vk::VkShaderModule> meshShaderModule;
1375         vk::Move<vk::VkShaderModule> vertShaderModule;
1376         vk::Move<vk::VkShaderModule> tescShaderModule;
1377         vk::Move<vk::VkShaderModule> teseShaderModule;
1378         vk::Move<vk::VkShaderModule> geomShaderModule;
1379         vk::Move<vk::VkShaderModule> fragShaderModule;
1380         if (m_params.meshShader)
1381             meshShaderModule = vk::createShaderModule(vk, device, binaries.get("mesh"));
1382         if (m_params.vertShader)
1383             vertShaderModule = vk::createShaderModule(vk, device, binaries.get("vert"));
1384         if (m_params.tessShader)
1385             tescShaderModule = vk::createShaderModule(vk, device, binaries.get("tesc"));
1386         if (m_params.tessShader)
1387             teseShaderModule = vk::createShaderModule(vk, device, binaries.get("tese"));
1388         if (m_params.geomShader)
1389             geomShaderModule = vk::createShaderModule(vk, device, binaries.get("geom"));
1390         if (m_params.fragShader)
1391             fragShaderModule = vk::createShaderModule(vk, device, binaries.get("frag"));
1392 
1393         const vk::VkPipelineVertexInputStateCreateInfo vertexInputState = {
1394             vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1395             DE_NULL,                                                       // const void* pNext;
1396             (vk::VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1397             0u,                                           // uint32_t vertexBindingDescriptionCount;
1398             DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1399             0u,      // uint32_t vertexAttributeDescriptionCount;
1400             DE_NULL  // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1401         };
1402 
1403         vk::VkPrimitiveTopology topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1404         if (m_params.tessShader)
1405             topology = vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1406         else if (m_params.lines)
1407             topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1408 
1409         const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
1410             vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1411             DE_NULL,                                                         // const void* pNext;
1412             (vk::VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1413             topology,                                       // VkPrimitiveTopology topology;
1414             VK_FALSE                                        // VkBool32 primitiveRestartEnable;
1415         };
1416 
1417         const vk::VkPipelineTessellationStateCreateInfo tessellationState = {
1418             vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
1419             DE_NULL,                                                       // const void* pNext;
1420             (vk::VkPipelineTessellationStateCreateFlags)0u, // VkPipelineTessellationStateCreateFlags flags;
1421             4u                                              // uint32_t patchControlPoints;
1422         };
1423 
1424         const vk::VkPipelineRasterizationDepthClipStateCreateInfoEXT depthClipState = {
1425             vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1426             DE_NULL,                                                                       // const void* pNext;
1427             (vk::VkPipelineRasterizationDepthClipStateCreateFlagsEXT)0u, // VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags;
1428             m_params.depthClip                                           // VkBool32 depthClipEnable;
1429         };
1430 
1431         const vk::VkPipelineRasterizationStateCreateInfo rasterizationState = {
1432             vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1433             m_params.depthClip ? &depthClipState : DE_NULL,                 // const void* pNext;
1434             (vk::VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1435             m_params.depthClamp,                            // VkBool32 depthClampEnable;
1436             m_params.rasterizerDiscardEnable,               // VkBool32 rasterizerDiscardEnable;
1437             vk::VK_POLYGON_MODE_FILL,                       // VkPolygonMode polygonMode;
1438             m_params.cull ? (vk::VkCullModeFlags)vk::VK_CULL_MODE_FRONT_AND_BACK :
1439                             (vk::VkCullModeFlags)vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1440             vk::VK_FRONT_FACE_CLOCKWISE,                                // VkFrontFace frontFace;
1441             m_params.depthBiasEnable ? VK_TRUE : VK_FALSE,              // VkBool32 depthBiasEnable;
1442             0.0f,                                                       // float depthBiasConstantFactor;
1443             0.0f,                                                       // float depthBiasClamp;
1444             0.0f,                                                       // float depthBiasSlopeFactor;
1445             1.0f                                                        // float lineWidth;
1446         };
1447 
1448         const vk::VkPipelineMultisampleStateCreateInfo multisampleState = {
1449             vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                            sType
1450             DE_NULL,                                       // const void*                                pNext
1451             (vk::VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags    flags
1452             vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits                    rasterizationSamples
1453             VK_FALSE,                  // VkBool32                                    sampleShadingEnable
1454             1.0f,                      // float                                    minSampleShading
1455             DE_NULL,                   // const VkSampleMask*                        pSampleMask
1456             VK_FALSE,                  // VkBool32                                    alphaToCoverageEnable
1457             m_params.alphaToOne ? VK_TRUE : VK_FALSE // VkBool32                                    alphaToOneEnable
1458         };
1459 
1460         const auto stencilOp = (m_params.stencilTestEnable ? vk::VK_STENCIL_OP_REPLACE : vk::VK_STENCIL_OP_KEEP);
1461         const auto stencilCompareOp =
1462             (m_params.stencilTestEnable ? vk::VK_COMPARE_OP_GREATER : vk::VK_COMPARE_OP_ALWAYS);
1463 
1464         const vk::VkStencilOpState stencilOpState = vk::makeStencilOpState(stencilOp,        // stencil fail
1465                                                                            stencilOp,        // depth & stencil pass
1466                                                                            stencilOp,        // depth only fail
1467                                                                            stencilCompareOp, // compare op
1468                                                                            0u,               // compare mask
1469                                                                            0u,               // write mask
1470                                                                            0u);              // reference
1471 
1472         const vk::VkPipelineDepthStencilStateCreateInfo depthStencilState{
1473             vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                          sType
1474             DE_NULL,                                        // const void*                              pNext
1475             (vk::VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags   flags
1476             m_params.depthTestEnable ? VK_TRUE : VK_FALSE,  // VkBool32                                 depthTestEnable
1477             VK_TRUE,                                        // VkBool32                                 depthWriteEnable
1478             vk::VK_COMPARE_OP_LESS,                         // VkCompareOp                              depthCompareOp
1479             m_params.depthBoundsTestEnable ? VK_TRUE :
1480                                              VK_FALSE, // VkBool32                                 depthBoundsTestEnable
1481             m_params.stencilTestEnable ? VK_TRUE :
1482                                          VK_FALSE, // VkBool32                                 stencilTestEnable
1483             stencilOpState,                        // VkStencilOpState                         front
1484             stencilOpState,                        // VkStencilOpState                         back
1485             0.0f,                                  // float                                    minDepthBounds
1486             1.0f,                                  // float                                    maxDepthBounds
1487         };
1488 
1489         const vk::VkPipelineColorBlendAttachmentState colorBlendAttState = {
1490             m_params.colorBlendEnable ? VK_TRUE : VK_FALSE, // VkBool32 blendEnable;
1491             vk::VK_BLEND_FACTOR_ONE,                        // VkBlendFactor srcColorBlendFactor;
1492             vk::VK_BLEND_FACTOR_ZERO,                       // VkBlendFactor dstColorBlendFactor;
1493             vk::VK_BLEND_OP_ADD,                            // VkBlendOp colorBlendOp;
1494             vk::VK_BLEND_FACTOR_ONE,                        // VkBlendFactor srcAlphaBlendFactor;
1495             vk::VK_BLEND_FACTOR_ZERO,                       // VkBlendFactor dstAlphaBlendFactor;
1496             vk::VK_BLEND_OP_ADD,                            // VkBlendOp alphaBlendOp;
1497             vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | vk::VK_COLOR_COMPONENT_B_BIT |
1498                 vk::VK_COLOR_COMPONENT_A_BIT, // VkColorComponentFlags colorWriteMask;
1499         };
1500 
1501         const uint32_t colorAttachmentCount = 2;
1502         const vk::VkPhysicalDeviceProperties properties =
1503             vk::getPhysicalDeviceProperties(instanceDriver, m_context.getPhysicalDevice());
1504         std::vector<vk::VkBool32> colorWriteEnables(properties.limits.maxColorAttachments);
1505         for (uint32_t i = 0; i < properties.limits.maxColorAttachments; ++i)
1506         {
1507             colorWriteEnables[i] = i < colorAttachmentCount ? VK_TRUE : VK_FALSE;
1508         }
1509         const vk::VkPipelineColorWriteCreateInfoEXT colorWriteState = {
1510             vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, // VkStructureType sType;
1511             DE_NULL,                                                    // const void* pNext;
1512             (uint32_t)colorWriteEnables.size(),                         // uint32_t attachmentCount;
1513             colorWriteEnables.data()                                    // const VkBool32* pColorWriteEnables;
1514         };
1515 
1516         const vk::VkPipelineColorBlendStateCreateInfo colorBlendState = {
1517             vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1518             m_params.colorWrite ? &colorWriteState : DE_NULL,             // const void* pNext;
1519             (vk::VkPipelineColorBlendStateCreateFlags)0,                  // VkPipelineColorBlendStateCreateFlags flags;
1520             m_params.logicOpEnable ? VK_TRUE : VK_FALSE,                  // VkBool32 logicOpEnable;
1521             vk::VK_LOGIC_OP_COPY,                                         // VkLogicOp logicOp;
1522             1u,                                                           // uint32_t attachmentCount;
1523             &colorBlendAttState,      // const VkPipelineColorBlendAttachmentState* pAttachments;
1524             {0.0f, 0.0f, 0.0f, 0.0f}, // float blendConstants[4];
1525         };
1526 
1527         vk::VkViewport viewport = {
1528             0, 0, 32, 32, 0.0f, 1.0f,
1529         };
1530         vk::VkRect2D scissor = {
1531             {
1532                 0,
1533                 0,
1534             },
1535             {
1536                 32,
1537                 32,
1538             },
1539         };
1540 
1541         const auto &edsFeatures          = m_context.getExtendedDynamicStateFeaturesEXT();
1542         uint32_t viewportAndScissorCount = edsFeatures.extendedDynamicState ? 0u : 1u;
1543 
1544         const vk::VkPipelineViewportDepthClipControlCreateInfoEXT depthClipControlState = {
1545             vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT, // VkStructureType sType;
1546             DE_NULL,                                                                    // const void* pNext;
1547             VK_TRUE,                                                                    // VkBool32 negativeOneToOne;
1548         };
1549 
1550         const vk::VkPipelineViewportStateCreateInfo viewportState = {
1551             vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                                    sType
1552             m_params.depthClipControl ? &depthClipControlState :
1553                                         DE_NULL,       // const void*                                        pNext
1554             (vk::VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags                flags
1555             viewportAndScissorCount, // uint32_t                                            viewportCount
1556             &viewport,               // const VkViewport*                                pViewports
1557             viewportAndScissorCount, // uint32_t                                            scissorCount
1558             &scissor                 // const VkRect2D*                                    pScissors
1559         };
1560 
1561         const auto dynamicStates = getDynamicStates();
1562 
1563         const vk::VkPipelineDynamicStateCreateInfo dynamicState = {
1564             vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType                                sType
1565             DE_NULL,                        // const void*                                    pNext
1566             0u,                             // VkPipelineDynamicStateCreateFlags            flags
1567             (uint32_t)dynamicStates.size(), // uint32_t                                        dynamicStateCount
1568             dynamicStates.data(),           // const VkDynamicState*                        pDynamicStates
1569         };
1570 
1571         const vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {
1572             vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType    sType
1573             DE_NULL,                                              // const void*        pNext
1574             0u,                                                   // uint32_t            viewMask
1575             1u,                                                   // uint32_t            colorAttachmentCount
1576             &colorAttachmentFormat,                               // const VkFormat*    pColorAttachmentFormats
1577             depthStencilAttachmentFormat,                         // VkFormat            depthAttachmentFormat
1578             depthStencilAttachmentFormat,                         // VkFormat            stencilAttachmentFormat
1579         };
1580 
1581         if (m_params.meshShader)
1582             pipeline = vk::makeGraphicsPipeline(vk, device, *pipelineLayout, VK_NULL_HANDLE, *meshShaderModule,
1583                                                 *fragShaderModule, VK_NULL_HANDLE, {}, {}, 0u, &rasterizationState,
1584                                                 &multisampleState, &depthStencilState, &colorBlendState, &dynamicState,
1585                                                 0u, &pipelineRenderingCreateInfo);
1586         else
1587             pipeline = vk::makeGraphicsPipeline(
1588                 vk, device, *pipelineLayout, *vertShaderModule, *tescShaderModule, *teseShaderModule, *geomShaderModule,
1589                 *fragShaderModule, VK_NULL_HANDLE, 0u, &vertexInputState, &inputAssemblyState, &tessellationState,
1590                 &viewportState, &rasterizationState, &multisampleState, &depthStencilState, &colorBlendState,
1591                 &dynamicState, &pipelineRenderingCreateInfo);
1592     }
1593     else
1594     {
1595         if (m_params.meshShader)
1596         {
1597             auto meshShaderCreateInfo =
1598                 vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, binaries.get("mesh"), tessellationSupported,
1599                                          geometrySupported, &*descriptorSetLayout);
1600             meshShaderCreateInfo.flags = vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
1601             meshShader                 = vk::createShader(vk, device, meshShaderCreateInfo);
1602         }
1603         if (m_params.vertShader)
1604             vertShader = vk::createShader(vk, device,
1605                                           vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"),
1606                                                                    tessellationSupported, geometrySupported,
1607                                                                    &*descriptorSetLayout));
1608         if (m_params.tessShader)
1609             tescShader = vk::createShader(vk, device,
1610                                           vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1611                                                                    binaries.get("tesc"), tessellationSupported,
1612                                                                    geometrySupported, &*descriptorSetLayout));
1613         if (m_params.tessShader)
1614             teseShader = vk::createShader(vk, device,
1615                                           vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1616                                                                    binaries.get("tese"), tessellationSupported,
1617                                                                    geometrySupported, &*descriptorSetLayout));
1618         if (m_params.geomShader)
1619             geomShader = vk::createShader(vk, device,
1620                                           vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT,
1621                                                                    binaries.get("geom"), tessellationSupported,
1622                                                                    geometrySupported, &*descriptorSetLayout));
1623         if (m_params.fragShader)
1624             fragShader = vk::createShader(vk, device,
1625                                           vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1626                                                                    binaries.get("frag"), tessellationSupported,
1627                                                                    geometrySupported, &*descriptorSetLayout));
1628     }
1629 
1630     const vk::VkDeviceSize tfBufSize = 4 * sizeof(tcu::Vec4);
1631     vk::Move<vk::VkBuffer> tfBuf;
1632     de::MovePtr<vk::Allocation> tfBufAllocation;
1633     const vk::VkMemoryBarrier tfMemoryBarrier =
1634         vk::makeMemoryBarrier(vk::VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, vk::VK_ACCESS_HOST_READ_BIT);
1635     if (m_params.geometryStreams)
1636     {
1637         const vk::VkBufferCreateInfo tfBufCreateInfo = vk::makeBufferCreateInfo(
1638             tfBufSize, vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT | vk::VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
1639         tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
1640         tfBufAllocation =
1641             alloc.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), vk::MemoryRequirement::HostVisible);
1642         vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset());
1643     }
1644 
1645     const vk::VkClearValue clearValue      = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
1646     const vk::VkClearValue clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u);
1647     vk::beginCommandBuffer(vk, *cmdBuffer);
1648 
1649     vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, 1,
1650                              &descriptorSet.get(), 0, DE_NULL);
1651 
1652     vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
1653         vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1654         vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1655     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1656                           vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
1657                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1658                           &preImageBarrier);
1659 
1660     vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(
1661         vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
1662         vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1663     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1664                           vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u,
1665                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1666                           &preDepthImageBarrier);
1667 
1668     vk::beginRendering(vk, *cmdBuffer, *imageView, *depthImageView, true, renderArea, clearValue, clearDepthValue,
1669                        vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
1670 
1671     if (m_params.pipeline)
1672     {
1673         vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1674     }
1675     else
1676     {
1677         if (m_params.meshShader)
1678         {
1679             vk::VkShaderStageFlagBits stages[] = {
1680                 vk::VK_SHADER_STAGE_MESH_BIT_EXT,
1681                 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
1682             };
1683             vk::VkShaderEXT shaders[] = {
1684                 *meshShader,
1685                 *fragShader,
1686             };
1687             vk::bindNullRasterizationShaders(vk, *cmdBuffer, m_context.getDeviceFeatures());
1688             vk.cmdBindShadersEXT(*cmdBuffer, 2, stages, shaders);
1689         }
1690         else
1691         {
1692             vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, *geomShader, *fragShader,
1693                                     taskSupported, meshSupported);
1694         }
1695     }
1696     setDynamicStates(vk, *cmdBuffer);
1697 
1698     if (m_params.geometryStreams)
1699     {
1700         vk::VkDeviceSize offset = 0u;
1701         vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &offset, &tfBufSize);
1702         vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1703     }
1704 
1705     bool secondDraw = !m_params.depthClamp && !m_params.depthClip;
1706     if (m_params.meshShader)
1707     {
1708         if (secondDraw)
1709             vk.cmdDrawMeshTasksEXT(*cmdBuffer, 2, 1, 1);
1710         else
1711             vk.cmdDrawMeshTasksEXT(*cmdBuffer, 1, 1, 1);
1712     }
1713     else
1714     {
1715         vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
1716         if (secondDraw)
1717             vk.cmdDraw(*cmdBuffer, 4, 1, 0, 1);
1718     }
1719     if (m_params.geometryStreams)
1720         vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0u, DE_NULL, DE_NULL);
1721     vk::endRendering(vk, *cmdBuffer);
1722 
1723     vk::VkImageMemoryBarrier postImageBarrier =
1724         vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
1725                                    vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
1726     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1727                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
1728                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
1729                           &postImageBarrier);
1730 
1731     vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(
1732         vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL,
1733         vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange);
1734     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
1735                           (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier *)DE_NULL, 0u,
1736                           (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u, &postDepthImageBarrier);
1737 
1738     vk::VkBufferMemoryBarrier bufferBarrier = vk::makeBufferMemoryBarrier(
1739         vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, *outputBuffer, 0u, bufferSizeBytes);
1740     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
1741                           (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier *)DE_NULL, 1u, &bufferBarrier, 0u,
1742                           (const vk::VkImageMemoryBarrier *)DE_NULL);
1743 
1744     if (m_params.geometryStreams)
1745         vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
1746                               vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
1747 
1748     const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
1749     vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
1750 
1751     vk::endCommandBuffer(vk, *cmdBuffer);
1752     vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1753 
1754     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
1755         vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
1756         (const void *)colorOutputBuffer->getAllocation().getHostPtr());
1757 
1758     const int32_t width   = resultBuffer.getWidth();
1759     const int32_t height  = resultBuffer.getHeight();
1760     const float threshold = 1.0f / 256.0f;
1761     tcu::Vec4 whiteColor  = tcu::Vec4(0.75f);
1762     tcu::Vec4 blackColor  = tcu::Vec4(0.0f);
1763 
1764     const vk::Allocation &outputBufferAllocation = outputBuffer.getAllocation();
1765     invalidateAlloc(vk, device, outputBufferAllocation);
1766 
1767     const uint32_t *bufferPtr = static_cast<uint32_t *>(outputBufferAllocation.getHostPtr());
1768 
1769     if (m_params.geometryStreams)
1770     {
1771         invalidateAlloc(vk, device, *tfBufAllocation);
1772         const float *tfData = static_cast<float *>(tfBufAllocation->getHostPtr());
1773         uint32_t count      = m_params.lines ? 2 : 3;
1774         for (uint32_t i = 0; i < count; ++i)
1775         {
1776             for (uint32_t j = 0; j < 4; ++j)
1777             {
1778                 if (tfData[i * 4 + j] != float(i + 1))
1779                 {
1780                     return tcu::TestStatus::fail("Fail");
1781                 }
1782             }
1783         }
1784         return tcu::TestStatus::pass("Pass");
1785     }
1786 
1787     if (m_params.vertShader)
1788     {
1789         if (bufferPtr[0] != 1u)
1790         {
1791             log << tcu::TestLog::Message << "Buffer value at index 0 was expected to be 1, but was[" << bufferPtr[0]
1792                 << tcu::TestLog::EndMessage;
1793             return tcu::TestStatus::fail("Fail");
1794         }
1795     }
1796 
1797     if (m_params.tessShader)
1798     {
1799         if (bufferPtr[1] != 2u)
1800         {
1801             log << tcu::TestLog::Message << "Buffer value at index 1 was expected to be 2, but was[" << bufferPtr[1]
1802                 << tcu::TestLog::EndMessage;
1803             return tcu::TestStatus::fail("Fail");
1804         }
1805         if (bufferPtr[2] != 3u)
1806         {
1807             log << tcu::TestLog::Message << "Buffer value at index 2 was expected to be 3, but was[" << bufferPtr[2]
1808                 << tcu::TestLog::EndMessage;
1809             return tcu::TestStatus::fail("Fail");
1810         }
1811     }
1812 
1813     if (m_params.geomShader)
1814     {
1815         if (bufferPtr[3] != 4u)
1816         {
1817             log << tcu::TestLog::Message << "Buffer value at index 3 was expected to be 4, but was[" << bufferPtr[3]
1818                 << tcu::TestLog::EndMessage;
1819             return tcu::TestStatus::fail("Fail");
1820         }
1821     }
1822 
1823     if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1824     {
1825         bool usesSrcOneDstOneBlending =
1826             (!m_params.pipeline && m_params.fragShader && !m_params.rasterizerDiscardEnable) ||
1827             hasDynamicState(getDynamicStates(), vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
1828 
1829         for (int32_t j = 0; j < height; ++j)
1830         {
1831             for (int32_t i = 0; i < width; ++i)
1832             {
1833                 const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
1834 
1835                 tcu::Vec4 expectedColor = blackColor;
1836                 bool inside             = isInsidePrimitive(i, j, width, height);
1837                 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1838                     continue;
1839                 if (inside && (!m_params.cull || m_params.lines) && (!m_params.colorWrite || m_params.colorWriteEnable))
1840                 {
1841                     if (!m_params.depthBoundsTestEnable && (!m_params.depthClip || i < 16) &&
1842                         !m_params.discardRectanglesEnable)
1843                     {
1844                         expectedColor = whiteColor;
1845                         if (m_params.alphaToOne)
1846                             expectedColor.w() = 1.0f;
1847                         if (m_params.colorBlendEnable && secondDraw && !m_params.logicOpEnable &&
1848                             !m_params.stencilTestEnable)
1849                         {
1850                             if (usesSrcOneDstOneBlending)
1851                             {
1852                                 // using src_factor=ONE dst_factor=ONE blending from dynamic state
1853                                 expectedColor = tcu::Vec4(1.0f);
1854                             }
1855                             // otherwise dst_factor=ZERO, so expect 'whiteColor'
1856                         }
1857                     }
1858                 }
1859 
1860                 if (deFloatAbs(color.x() - expectedColor.x()) > threshold ||
1861                     deFloatAbs(color.y() - expectedColor.y()) > threshold ||
1862                     deFloatAbs(color.z() - expectedColor.z()) > threshold ||
1863                     deFloatAbs(color.w() - expectedColor.w()) > threshold)
1864                 {
1865                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be ("
1866                         << expectedColor << "), but was (" << color << ")" << tcu::TestLog::EndMessage;
1867                     return tcu::TestStatus::fail("Fail");
1868                 }
1869             }
1870         }
1871     }
1872 
1873     if (m_params.fragShader && !m_params.rasterizerDiscardEnable)
1874     {
1875         const auto depthBuffer =
1876             readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, depthStencilAttachmentFormat,
1877                                 tcu::UVec2(width, height), vk::VK_IMAGE_LAYOUT_GENERAL);
1878         const auto depthAccess   = depthBuffer->getAccess();
1879         const auto stencilBuffer = readStencilAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage,
1880                                                          depthStencilAttachmentFormat, tcu::UVec2(width, height),
1881                                                          vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1882         const auto stencilAccess = stencilBuffer->getAccess();
1883         const float depthEpsilon = 0.02f;
1884 
1885         for (int32_t j = 0; j < height; ++j)
1886         {
1887             for (int32_t i = 0; i < width; ++i)
1888             {
1889                 const float depth = depthAccess.getPixDepth(i, j);
1890                 const int stencil = stencilAccess.getPixStencil(i, j);
1891                 bool inside       = isInsidePrimitive(i, j, width, height);
1892                 if (m_params.conservativeRasterization && m_params.conservativeRasterizationOverestimate && !inside)
1893                     continue;
1894                 if (inside && !m_params.depthBoundsTestEnable && !m_params.discardRectanglesEnable &&
1895                     (!m_params.cull || m_params.lines))
1896                 {
1897                     float depthMin = 0.4f - depthEpsilon;
1898                     float depthMax = 0.6f + depthEpsilon;
1899                     if (m_params.stencilTestEnable)
1900                     {
1901                         depthMin = 0.7f - depthEpsilon;
1902                         depthMax = 0.9f + depthEpsilon;
1903                     }
1904                     if (m_params.depthClamp)
1905                     {
1906                         depthMin = 0.35f - depthEpsilon;
1907                         depthMax = 0.45f + depthEpsilon;
1908                     }
1909                     if (m_params.depthClip)
1910                     {
1911                         depthMin = 0.9f - depthEpsilon;
1912                         depthMax = 1.0f + depthEpsilon;
1913                     }
1914                     if (m_params.depthClipControl)
1915                     {
1916                         depthMin = 0.7f - depthEpsilon;
1917                         depthMax = 1.0f + depthEpsilon;
1918                     }
1919                     if (m_params.depthBiasEnable)
1920                     {
1921                         if (m_params.lines)
1922                         {
1923                             depthMin += 0.004f;
1924                             depthMax += 0.004f;
1925                         }
1926                         else
1927                         {
1928                             depthMin += 0.03f;
1929                             depthMax += 0.03f;
1930                         }
1931                     }
1932                     if (!m_params.depthTestEnable)
1933                     {
1934                         depthMin = 1.0f - depthEpsilon;
1935                         depthMax = 1.0f + depthEpsilon;
1936                     }
1937 
1938                     if (depth < depthMin || depth > depthMax)
1939                     {
1940                         log << tcu::TestLog::Message << "Depth at (" << i << ", " << j
1941                             << ") is expected to be between 0.4f and 0.6f, but was (" << depth << ")"
1942                             << tcu::TestLog::EndMessage;
1943                         return tcu::TestStatus::fail("Fail");
1944                     }
1945                     if (m_params.stencilTestEnable && (!m_params.depthClip || i < 16))
1946                     {
1947                         if (stencil != 255)
1948                         {
1949                             log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j
1950                                 << ") is expected to be 255, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1951                             return tcu::TestStatus::fail("Fail");
1952                         }
1953                     }
1954                 }
1955                 else
1956                 {
1957                     if (deFloatAbs(depth - 1.0f) > depthEpsilon)
1958                     {
1959                         log << tcu::TestLog::Message << "Depth at (" << i << ", " << j
1960                             << ") is expected to be 1.0f, but was (" << depth << ")" << tcu::TestLog::EndMessage;
1961                         return tcu::TestStatus::fail("Fail");
1962                     }
1963                     if (m_params.stencilTestEnable)
1964                     {
1965                         if (stencil != 0)
1966                         {
1967                             log << tcu::TestLog::Message << "Stencil at (" << i << ", " << j
1968                                 << ") is expected to be 0, but was (" << stencil << ")" << tcu::TestLog::EndMessage;
1969                             return tcu::TestStatus::fail("Fail");
1970                         }
1971                     }
1972                 }
1973             }
1974         }
1975     }
1976 
1977     if (m_params.meshShader)
1978     {
1979         if (bufferPtr[4] != 5u)
1980         {
1981             log << tcu::TestLog::Message << "Buffer value at index 5 was expected to be 6, but was[" << bufferPtr[5]
1982                 << tcu::TestLog::EndMessage;
1983             return tcu::TestStatus::fail("Fail");
1984         }
1985     }
1986 
1987     return tcu::TestStatus::pass("Pass");
1988 }
1989 
1990 class ShaderObjectStateCase : public vkt::TestCase
1991 {
1992 public:
ShaderObjectStateCase(tcu::TestContext & testCtx,const std::string & name,const StateTestParams & testParams)1993     ShaderObjectStateCase(tcu::TestContext &testCtx, const std::string &name, const StateTestParams &testParams)
1994         : vkt::TestCase(testCtx, name)
1995         , m_params(testParams)
1996     {
1997     }
~ShaderObjectStateCase(void)1998     virtual ~ShaderObjectStateCase(void)
1999     {
2000     }
2001 
2002     void checkSupport(vkt::Context &context) const override;
2003     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const2004     TestInstance *createInstance(Context &context) const override
2005     {
2006         return new ShaderObjectStateInstance(context, m_params);
2007     }
2008 
2009     const StateTestParams m_params;
2010 };
2011 
checkSupport(Context & context) const2012 void ShaderObjectStateCase::checkSupport(Context &context) const
2013 {
2014     const auto &edsFeatures  = context.getExtendedDynamicStateFeaturesEXT();
2015     const auto &eds2Features = context.getExtendedDynamicState2FeaturesEXT();
2016     const auto &eds3Features = context.getExtendedDynamicState3FeaturesEXT();
2017 
2018     const auto &vki           = context.getInstanceInterface();
2019     const auto physicalDevice = context.getPhysicalDevice();
2020     if (findDSFormat(vki, physicalDevice) == vk::VK_FORMAT_UNDEFINED)
2021         TCU_THROW(NotSupportedError, "Required depth/stencil format not supported");
2022 
2023     if (!m_params.pipeline)
2024         context.requireDeviceFunctionality("VK_EXT_shader_object");
2025     else
2026         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
2027 
2028     if (!context.getDeviceFeatures().vertexPipelineStoresAndAtomics)
2029         TCU_THROW(NotSupportedError, "vertexPipelineStoresAndAtomics not supported");
2030 
2031     if (m_params.logicOp)
2032     {
2033         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LOGIC_OP);
2034         if (m_params.pipeline && !eds2Features.extendedDynamicState2LogicOp)
2035             TCU_THROW(NotSupportedError, "extendedDynamicState2LogicOp not supported");
2036     }
2037     if (m_params.alphaToOne)
2038     {
2039         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
2040         if (m_params.pipeline && !eds3Features.extendedDynamicState3AlphaToOneEnable)
2041             TCU_THROW(NotSupportedError, "extendedDynamicState3AlphaToOneEnable not supported");
2042     }
2043     if (m_params.depthBounds)
2044     {
2045         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_BOUNDS);
2046         if (m_params.pipeline && !edsFeatures.extendedDynamicState)
2047             TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
2048     }
2049     if (m_params.depthClamp)
2050     {
2051         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
2052         if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClampEnable)
2053             TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClampEnable not supported");
2054     }
2055     if (m_params.depthClip)
2056     {
2057         context.requireDeviceFunctionality("VK_EXT_depth_clip_enable");
2058         if (!context.getDepthClipEnableFeaturesEXT().depthClipEnable)
2059             TCU_THROW(NotSupportedError, "depthClipEnable not supported");
2060         if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipEnable)
2061             TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipEnable not supported");
2062     }
2063     if (m_params.depthClipControl)
2064     {
2065         context.requireDeviceFunctionality("VK_EXT_depth_clip_control");
2066         if (!context.getDepthClipControlFeaturesEXT().depthClipControl)
2067             TCU_THROW(NotSupportedError, "depthClipControl not supported");
2068         if (m_params.pipeline && !eds3Features.extendedDynamicState3DepthClipNegativeOneToOne)
2069             TCU_THROW(NotSupportedError, "extendedDynamicState3DepthClipNegativeOneToOne not supported");
2070     }
2071     if (m_params.colorWrite)
2072     {
2073         context.requireDeviceFunctionality("VK_EXT_color_write_enable");
2074         if (!context.getColorWriteEnableFeaturesEXT().colorWriteEnable)
2075             TCU_THROW(NotSupportedError, "colorWriteEnable not supported");
2076     }
2077     if (m_params.geometryStreams)
2078     {
2079         context.requireDeviceFunctionality("VK_EXT_transform_feedback");
2080         if (!context.getTransformFeedbackFeaturesEXT().geometryStreams)
2081             TCU_THROW(NotSupportedError, "geometryStreams not supported");
2082         if (m_params.pipeline && !eds3Features.extendedDynamicState3RasterizationStream)
2083             TCU_THROW(NotSupportedError, "extendedDynamicState3RasterizationStream not supported");
2084     }
2085     if (m_params.discardRectangles)
2086     {
2087         context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
2088 
2089         uint32_t propertyCount = 0u;
2090         std::vector<vk::VkExtensionProperties> extensionsProperties;
2091         context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL,
2092                                                                           &propertyCount, DE_NULL);
2093         extensionsProperties.resize(propertyCount);
2094         context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), DE_NULL,
2095                                                                           &propertyCount, extensionsProperties.data());
2096 
2097         for (const auto &extProp : extensionsProperties)
2098         {
2099             if (strcmp(extProp.extensionName, "VK_EXT_discard_rectangles") == 0)
2100             {
2101                 if (extProp.specVersion < 2)
2102                     TCU_THROW(NotSupportedError, "VK_EXT_discard_rectangles is version 1. Needs version 2 or higher");
2103             }
2104         }
2105     }
2106     if (m_params.conservativeRasterization)
2107     {
2108         context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
2109         if (m_params.pipeline && !eds3Features.extendedDynamicState3ConservativeRasterizationMode)
2110             TCU_THROW(NotSupportedError, "extendedDynamicState3ConservativeRasterizationMode not supported");
2111     }
2112     if (m_params.sampleLocations)
2113     {
2114         context.requireDeviceFunctionality("VK_EXT_sample_locations");
2115         if (m_params.sampleLocationsEnable &&
2116             (context.getSampleLocationsPropertiesEXT().sampleLocationSampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) == 0)
2117             TCU_THROW(NotSupportedError, "VK_SAMPLE_COUNT_1_BIT not supported in sampleLocationSampleCounts");
2118     }
2119     if (m_params.provokingVertex)
2120     {
2121         context.requireDeviceFunctionality("VK_EXT_provoking_vertex");
2122         if (m_params.pipeline && !eds3Features.extendedDynamicState3ProvokingVertexMode)
2123             TCU_THROW(NotSupportedError, "extendedDynamicState3ProvokingVertexMode not supported");
2124     }
2125     if (m_params.lineRasterization)
2126     {
2127         if (!context.isDeviceFunctionalitySupported("VK_KHR_line_rasterization") &&
2128             !context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"))
2129             TCU_THROW(NotSupportedError, "VK_KHR_line_rasterization and VK_EXT_line_rasterization are not supported");
2130         if (!context.getLineRasterizationFeatures().rectangularLines)
2131             TCU_THROW(NotSupportedError, "rectangularLines not supported");
2132         if (m_params.pipeline && !eds3Features.extendedDynamicState3LineRasterizationMode)
2133             TCU_THROW(NotSupportedError, "extendedDynamicState3LineRasterizationMode not supported");
2134         if (m_params.pipeline && !eds3Features.extendedDynamicState3LineStippleEnable)
2135             TCU_THROW(NotSupportedError, "extendedDynamicState3LineStippleEnable not supported");
2136         if (m_params.stippledLineEnable && !context.getLineRasterizationFeatures().stippledRectangularLines)
2137             TCU_THROW(NotSupportedError, "stippledRectangularLines not supported");
2138     }
2139     if (m_params.geomShader)
2140         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2141     if (m_params.tessShader)
2142         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2143     if (m_params.meshShader)
2144     {
2145         context.requireDeviceFunctionality("VK_EXT_mesh_shader");
2146         if (!context.getMeshShaderFeaturesEXT().meshShader)
2147             TCU_THROW(NotSupportedError, "Mesh shaders not supported");
2148     }
2149     if (m_params.lines)
2150     {
2151         if (m_params.pipeline && !edsFeatures.extendedDynamicState)
2152             TCU_THROW(NotSupportedError, "extendedDynamicState not supported");
2153     }
2154     if (m_params.colorBlendEnable && m_params.pipeline)
2155     {
2156         context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state3");
2157         if (!eds3Features.extendedDynamicState3ColorBlendEnable)
2158             TCU_THROW(NotSupportedError, "extendedDynamicState3ColorBlendEnable not supported");
2159     }
2160 }
2161 
initPrograms(vk::SourceCollections & programCollection) const2162 void ShaderObjectStateCase::initPrograms(vk::SourceCollections &programCollection) const
2163 {
2164     std::stringstream vert;
2165     std::stringstream geom;
2166     std::stringstream tesc;
2167     std::stringstream tese;
2168     std::stringstream frag;
2169 
2170     vert << "#version 450\n"
2171          << "layout(binding = 0) buffer Output {\n"
2172          << "    uint values[8];\n"
2173          << "} buffer_out;\n\n"
2174          << "void main() {\n"
2175          << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1)) - vec2(0.0001f);\n";
2176     if (m_params.depthClip)
2177         vert << "    float z = 0.9f;\n";
2178     else
2179         vert << "    float z = 0.7f;\n";
2180     vert << "    if ((gl_VertexIndex & 1) > 0)\n"
2181          << "        z += 0.2f;\n"
2182          << "    if ((gl_InstanceIndex & 1) > 0)\n"
2183          << "        z -= 0.3f;\n"
2184          << "    gl_Position = vec4(pos - 0.5f, z, 1.0f);\n"
2185          << "    if (gl_VertexIndex == 0)\n"
2186          << "        buffer_out.values[0] = 1u;\n"
2187          << "}\n";
2188 
2189     tesc << "#version 450\n"
2190          << "layout(vertices = 4) out;\n"
2191          << "layout(binding = 0) buffer Output {\n"
2192          << "    uint values[8];\n"
2193          << "} buffer_out;\n\n"
2194          << "void main (void)\n"
2195          << "{\n"
2196          << "    if (gl_InvocationID == 0) {\n"
2197          << "        gl_TessLevelInner[0] = 1.0;\n"
2198          << "        gl_TessLevelInner[1] = 1.0;\n"
2199          << "        gl_TessLevelOuter[0] = 1.0;\n"
2200          << "        gl_TessLevelOuter[1] = 1.0;\n"
2201          << "        gl_TessLevelOuter[2] = 1.0;\n"
2202          << "        gl_TessLevelOuter[3] = 1.0;\n"
2203          << "        buffer_out.values[1] = 2u;\n"
2204          << "    }\n"
2205          << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2206          << "}\n";
2207 
2208     tese << "#version 450\n";
2209     if (m_params.lines)
2210         tese << "layout(isolines, equal_spacing) in;\n";
2211     else
2212         tese << "layout(quads, equal_spacing) in;\n";
2213     tese << "layout(binding = 0) buffer Output {\n"
2214          << "    uint values[8];\n"
2215          << "} buffer_out;\n\n"
2216          << "void main (void)\n"
2217          << "{\n"
2218          << "    float u = gl_TessCoord.x;\n"
2219          << "    float v = gl_TessCoord.y;\n"
2220          << "    float omu = 1.0f - u;\n"
2221          << "    float omv = 1.0f - v;\n"
2222          << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
2223             "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2224          << "    gl_Position.x *= 1.5f;\n"
2225          << "    if (gl_PrimitiveID == 0u)\n"
2226          << "        buffer_out.values[2] = 3u;\n"
2227          << "}\n";
2228 
2229     geom << "#version 450\n";
2230     if (m_params.lines)
2231         geom << "layout(lines) in;\n";
2232     else
2233         geom << "layout(triangles) in;\n";
2234     if (m_params.lines)
2235         geom << "layout(line_strip, max_vertices = 4) out;\n";
2236     else
2237         geom << "layout(triangle_strip, max_vertices = 4) out;\n";
2238     if (m_params.geometryStreams)
2239         geom << "layout(stream = 0, xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n";
2240     geom << "layout(binding = 0) buffer Output {\n"
2241          << "    uint values[8];\n"
2242          << "} buffer_out;\n\n"
2243          << "void main(void)\n"
2244          << "{\n"
2245          << "    gl_Position = gl_in[0].gl_Position;\n"
2246          << "    gl_Position.y *= 1.5f;\n";
2247     if (m_params.geometryStreams)
2248         geom << "    out0 = vec4(1.0f);\n"
2249              << "    EmitStreamVertex(0);\n";
2250     else
2251         geom << "    EmitVertex();\n";
2252     geom << "    gl_Position = gl_in[1].gl_Position;\n"
2253          << "    gl_Position.y *= 1.5f;\n";
2254     if (m_params.geometryStreams)
2255         geom << "    out0 = vec4(2.0f);\n"
2256              << "    EmitStreamVertex(0);\n";
2257     else
2258         geom << "    EmitVertex();\n";
2259     if (!m_params.lines)
2260     {
2261         geom << "    gl_Position = gl_in[2].gl_Position;\n"
2262              << "    gl_Position.y *= 1.5f;\n";
2263         if (m_params.geometryStreams)
2264             geom << "    out0 = vec4(3.0f);\n"
2265                  << "    EmitStreamVertex(0);\n";
2266         else
2267             geom << "    EmitVertex();\n";
2268     }
2269     if (m_params.geometryStreams)
2270         geom << "    EndStreamPrimitive(0);\n";
2271     else
2272         geom << "    EndPrimitive();\n";
2273     geom << "    buffer_out.values[3] = 4u;\n";
2274     geom << "}\n";
2275 
2276     frag << "#version 450\n"
2277          << "layout (location=0) out vec4 outColor;\n"
2278          << "void main() {\n"
2279          << "    outColor = vec4(0.75f);\n"
2280          << "}\n";
2281 
2282     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2283     programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2284     programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2285     programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2286     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2287 
2288     if (m_params.meshShader)
2289     {
2290         std::stringstream mesh;
2291 
2292         mesh << "#version 460\n"
2293              << "#extension GL_EXT_mesh_shader : require\n"
2294              << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2295              << "layout(max_vertices = 4) out;\n"
2296              << "layout(max_primitives = 2) out;\n";
2297         if (m_params.lines)
2298             mesh << "layout(lines) out;\n";
2299         else
2300             mesh << "layout(triangles) out;\n";
2301         mesh << "layout(binding = 0) buffer Output {\n"
2302              << "    uint values[8];\n"
2303              << "} buffer_out;\n\n"
2304              << "void main() {\n"
2305              << "    SetMeshOutputsEXT(4u, 2u);\n";
2306         if (m_params.depthClip)
2307             mesh << "    float z = 0.9f;\n";
2308         else
2309             mesh << "    float z = 0.7f;\n";
2310         mesh << "    if (gl_GlobalInvocationID.x == 1) z -= 0.3f;\n"
2311              << "    gl_MeshVerticesEXT[0].gl_Position = vec4(-0.5f, -0.5f, z, 1.0f);\n"
2312              << "    gl_MeshVerticesEXT[1].gl_Position = vec4(-0.5f, 0.5f, z, 1.0f);\n"
2313              << "    gl_MeshVerticesEXT[2].gl_Position = vec4(0.5f, -0.5f, z + 0.2f, 1.0f);\n"
2314              << "    gl_MeshVerticesEXT[3].gl_Position = vec4(0.5f, 0.5f, z + 0.2f, 1.0f);\n";
2315         if (m_params.lines)
2316             mesh << "    gl_PrimitiveLineIndicesEXT[0] = uvec2(0u, 2u);\n"
2317                  << "    gl_PrimitiveLineIndicesEXT[1] = uvec2(1u, 3u);\n";
2318         else
2319             mesh << "    gl_PrimitiveTriangleIndicesEXT[0] = uvec3(0u, 1u, 2u);\n"
2320                  << "    gl_PrimitiveTriangleIndicesEXT[1] = uvec3(1u, 3u, 2u);\n";
2321         mesh << "    buffer_out.values[4] = 5u;\n"
2322              << "}\n";
2323 
2324         programCollection.glslSources.add("mesh")
2325             << glu::MeshSource(mesh.str())
2326             << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2327     }
2328 }
2329 
2330 struct UnusedBuiltinParams
2331 {
2332     bool linked;
2333     vk::VkShaderStageFlagBits stage;
2334     bool builtin;
2335 };
2336 
2337 enum TessellationSpacing
2338 {
2339     EQUAL,
2340     EVEN,
2341     ODD,
2342 };
2343 
2344 struct TessellationModesParams
2345 {
2346     uint32_t subdivision;
2347     TessellationSpacing spacing;
2348 };
2349 
2350 class ShaderObjectUnusedBuiltinInstance : public vkt::TestInstance
2351 {
2352 public:
ShaderObjectUnusedBuiltinInstance(Context & context,const UnusedBuiltinParams & params)2353     ShaderObjectUnusedBuiltinInstance(Context &context, const UnusedBuiltinParams &params)
2354         : vkt::TestInstance(context)
2355         , m_params(params)
2356     {
2357     }
~ShaderObjectUnusedBuiltinInstance(void)2358     virtual ~ShaderObjectUnusedBuiltinInstance(void)
2359     {
2360     }
2361 
2362     tcu::TestStatus iterate(void) override;
2363 
2364 private:
2365     UnusedBuiltinParams m_params;
2366 };
2367 
iterate(void)2368 tcu::TestStatus ShaderObjectUnusedBuiltinInstance::iterate(void)
2369 {
2370     const vk::VkInstance instance = m_context.getInstance();
2371     const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
2372     const vk::DeviceInterface &vk   = m_context.getDeviceInterface();
2373     const vk::VkDevice device       = m_context.getDevice();
2374     const vk::VkQueue queue         = m_context.getUniversalQueue();
2375     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2376     auto &alloc                     = m_context.getDefaultAllocator();
2377     tcu::TestLog &log               = m_context.getTestContext().getLog();
2378     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
2379         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2380     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2381     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
2382     const bool taskSupported         = m_context.getMeshShaderFeaturesEXT().taskShader;
2383     const bool meshSupported         = m_context.getMeshShaderFeaturesEXT().meshShader;
2384 
2385     vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2386     const auto subresourceRange        = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2387     const auto subresourceLayers       = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2388     const vk::VkRect2D renderArea      = vk::makeRect2D(0, 0, 32, 32);
2389     vk::VkExtent3D extent              = {renderArea.extent.width, renderArea.extent.height, 1};
2390 
2391     const vk::VkImageCreateInfo createInfo = {
2392         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
2393         DE_NULL,                                 // const void*                pNext
2394         0u,                                      // VkImageCreateFlags        flags
2395         vk::VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
2396         colorAttachmentFormat,                   // VkFormat                    format
2397         {32, 32, 1},                             // VkExtent3D                extent
2398         1u,                                      // uint32_t                    mipLevels
2399         1u,                                      // uint32_t                    arrayLayers
2400         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
2401         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
2402         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
2403         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
2404         0,                             // uint32_t                    queueFamilyIndexCount
2405         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
2406         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
2407     };
2408 
2409     de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
2410         new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2411     const auto imageView =
2412         vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2413 
2414     const vk::VkDeviceSize colorOutputBufferSize =
2415         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2416     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2417         vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2418         vk::MemoryRequirement::HostVisible));
2419 
2420     const auto &binaries = m_context.getBinaryCollection();
2421     vk::VkShaderEXT shaders[5];
2422 
2423     vk::VkShaderCreateInfoEXT shaderCreateInfos[5]{
2424         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"), tessellationSupported,
2425                                  geometrySupported),
2426         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"),
2427                                  tessellationSupported, geometrySupported),
2428         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"),
2429                                  tessellationSupported, geometrySupported),
2430         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, binaries.get("geom"), tessellationSupported,
2431                                  geometrySupported),
2432         vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"), tessellationSupported,
2433                                  geometrySupported),
2434     };
2435 
2436     vk.createShadersEXT(device, 5u, shaderCreateInfos, DE_NULL, shaders);
2437 
2438     if (m_params.linked)
2439         for (auto &ci : shaderCreateInfos)
2440             ci.flags |= vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
2441 
2442     const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2443     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
2444         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2445 
2446     vk::beginCommandBuffer(vk, *cmdBuffer);
2447 
2448     vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
2449         vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
2450         vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2451     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2452                           vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
2453                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2454                           &preImageBarrier);
2455 
2456     const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
2457     vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
2458                        vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2459 
2460     vk::bindGraphicsShaders(vk, *cmdBuffer, shaders[0], shaders[1], shaders[2], shaders[3], shaders[4], taskSupported,
2461                             meshSupported);
2462     vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2463 
2464     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2465 
2466     vk::endRendering(vk, *cmdBuffer);
2467 
2468     vk::VkImageMemoryBarrier postImageBarrier =
2469         vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
2470                                    vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2471     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2472                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
2473                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2474                           &postImageBarrier);
2475 
2476     const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2477     vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
2478 
2479     vk::endCommandBuffer(vk, *cmdBuffer);
2480     vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2481 
2482     for (uint32_t i = 0u; i < 5u; ++i)
2483         vk.destroyShaderEXT(device, shaders[i], DE_NULL);
2484 
2485     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
2486         vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
2487         (const void *)colorOutputBuffer->getAllocation().getHostPtr());
2488 
2489     const tcu::Vec4 black  = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2490     const tcu::Vec4 white  = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2491     const uint32_t width   = resultBuffer.getWidth();
2492     const uint32_t height  = resultBuffer.getHeight();
2493     const uint32_t xOffset = 4u;
2494     const uint32_t yOffset = 4u;
2495 
2496     for (uint32_t j = 0; j < height; ++j)
2497     {
2498         for (uint32_t i = 0; i < width; ++i)
2499         {
2500             const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
2501             if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset)
2502             {
2503                 if (color != white)
2504                 {
2505                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j
2506                         << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")"
2507                         << tcu::TestLog::EndMessage;
2508                     return tcu::TestStatus::fail("Fail");
2509                 }
2510             }
2511             else
2512             {
2513                 if (color != black)
2514                 {
2515                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j
2516                         << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")"
2517                         << tcu::TestLog::EndMessage;
2518                     return tcu::TestStatus::fail("Fail");
2519                 }
2520             }
2521         }
2522     }
2523 
2524     return tcu::TestStatus::pass("Pass");
2525 }
2526 
2527 class ShaderObjectUnusedBuiltinCase : public vkt::TestCase
2528 {
2529 public:
ShaderObjectUnusedBuiltinCase(tcu::TestContext & testCtx,const std::string & name,const UnusedBuiltinParams & testParams)2530     ShaderObjectUnusedBuiltinCase(tcu::TestContext &testCtx, const std::string &name,
2531                                   const UnusedBuiltinParams &testParams)
2532         : vkt::TestCase(testCtx, name)
2533         , m_params(testParams)
2534     {
2535     }
~ShaderObjectUnusedBuiltinCase(void)2536     virtual ~ShaderObjectUnusedBuiltinCase(void)
2537     {
2538     }
2539 
2540     void checkSupport(vkt::Context &context) const override;
2541     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const2542     TestInstance *createInstance(Context &context) const override
2543     {
2544         return new ShaderObjectUnusedBuiltinInstance(context, m_params);
2545     }
2546 
2547 private:
2548     const UnusedBuiltinParams m_params;
2549 };
2550 
checkSupport(vkt::Context & context) const2551 void ShaderObjectUnusedBuiltinCase::checkSupport(vkt::Context &context) const
2552 {
2553     context.requireDeviceFunctionality("VK_EXT_shader_object");
2554     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2555     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
2556 }
2557 
initPrograms(vk::SourceCollections & programCollection) const2558 void ShaderObjectUnusedBuiltinCase::initPrograms(vk::SourceCollections &programCollection) const
2559 {
2560     std::stringstream vert;
2561     std::stringstream geom;
2562     std::stringstream tesc;
2563     std::stringstream tese;
2564     std::stringstream frag;
2565 
2566     vert << "#version 450\n";
2567     if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT && !m_params.builtin)
2568         vert << "layout(location = 0) out vec4 unused;\n";
2569     vert << "void main() {\n"
2570          << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
2571          << "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n";
2572     if (m_params.stage == vk::VK_SHADER_STAGE_VERTEX_BIT)
2573     {
2574         if (m_params.builtin)
2575         {
2576             vert << "    gl_PointSize = 16.0f;\n";
2577             vert << "    gl_ClipDistance[0] = 2.0f;\n";
2578         }
2579         else
2580         {
2581             vert << "    unused = vec4(1.0f);\n";
2582         }
2583     }
2584     vert << "}\n";
2585 
2586     tesc << "#version 450\n"
2587          << "\n"
2588          << "layout(vertices = 4) out;\n";
2589     if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT && !m_params.builtin)
2590         tesc << "layout(location = 0) out vec4 unused[];\n";
2591     tesc << "\n"
2592          << "void main (void)\n"
2593          << "{\n"
2594          << "    if (gl_InvocationID == 0) {\n"
2595          << "        gl_TessLevelInner[0] = 1.0;\n"
2596          << "        gl_TessLevelInner[1] = 1.0;\n"
2597          << "        gl_TessLevelOuter[0] = 1.0;\n"
2598          << "        gl_TessLevelOuter[1] = 1.0;\n"
2599          << "        gl_TessLevelOuter[2] = 1.0;\n"
2600          << "        gl_TessLevelOuter[3] = 1.0;\n"
2601          << "    }\n"
2602          << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
2603     if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2604     {
2605         if (m_params.builtin)
2606         {
2607             tesc << "    gl_out[gl_InvocationID].gl_PointSize = 16.0f;\n";
2608             tesc << "    gl_out[gl_InvocationID].gl_ClipDistance[0] = 2.0f;\n";
2609         }
2610         else
2611         {
2612             tesc << "    unused[gl_InvocationID] = vec4(1.0f);\n";
2613         }
2614     }
2615     tesc << "}\n";
2616 
2617     tese << "#version 450\n"
2618          << "\n"
2619          << "layout(quads, equal_spacing) in;\n";
2620     if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT && !m_params.builtin)
2621         tese << "layout(location = 0) out vec4 unused;\n";
2622     tese << "\n"
2623          << "void main (void)\n"
2624          << "{\n"
2625          << "    float u = gl_TessCoord.x;\n"
2626          << "    float v = gl_TessCoord.y;\n"
2627          << "    float omu = 1.0f - u;\n"
2628          << "    float omv = 1.0f - v;\n"
2629          << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
2630             "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
2631          << "    gl_Position.x *= 1.5f;\n";
2632     if (m_params.stage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2633     {
2634         if (m_params.builtin)
2635         {
2636             tese << "    gl_PointSize = 16.0f;\n";
2637             tese << "    gl_ClipDistance[0] = 2.0f;\n";
2638         }
2639         else
2640         {
2641             tese << "    unused = vec4(1.0f);\n";
2642         }
2643     }
2644     tese << "}\n";
2645 
2646     geom << "#version 450\n"
2647          << "layout(triangles) in;\n"
2648          << "layout(triangle_strip, max_vertices = 4) out;\n";
2649     if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT && !m_params.builtin)
2650         geom << "layout(location = 0) out vec4 unused;\n";
2651     geom << "\n"
2652          << "void main(void)\n"
2653          << "{\n"
2654          << "    gl_Position = gl_in[0].gl_Position;\n"
2655          << "    gl_Position.y *= 1.5f;\n"
2656          << "    gl_Position.z = 0.5f;\n"
2657          << "    EmitVertex();\n"
2658          << "    gl_Position = gl_in[1].gl_Position;\n"
2659          << "    gl_Position.y *= 1.5f;\n"
2660          << "    gl_Position.z = 0.5f;\n"
2661          << "    EmitVertex();\n"
2662          << "    gl_Position = gl_in[2].gl_Position;\n"
2663          << "    gl_Position.y *= 1.5f;\n"
2664          << "    gl_Position.z = 0.5f;\n"
2665          << "    EmitVertex();\n"
2666          << "    EndPrimitive();\n";
2667     if (m_params.stage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2668     {
2669         if (m_params.builtin)
2670             geom << "    gl_PointSize = 16.0f;\n";
2671         else
2672             geom << "    unused = vec4(1.0f);\n";
2673     }
2674     geom << "}\n";
2675 
2676     frag << "#version 450\n"
2677          << "layout (location=0) out vec4 outColor;\n"
2678          << "void main() {\n"
2679          << "    outColor = vec4(1.0f);\n"
2680          << "}\n";
2681 
2682     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
2683     programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
2684     programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
2685     programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
2686     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
2687 }
2688 
2689 class ShaderObjectTessellationModesInstance : public vkt::TestInstance
2690 {
2691 public:
ShaderObjectTessellationModesInstance(Context & context,const TessellationModesParams & params)2692     ShaderObjectTessellationModesInstance(Context &context, const TessellationModesParams &params)
2693         : vkt::TestInstance(context)
2694         , m_params(params)
2695     {
2696     }
~ShaderObjectTessellationModesInstance(void)2697     virtual ~ShaderObjectTessellationModesInstance(void)
2698     {
2699     }
2700 
2701     tcu::TestStatus iterate(void) override;
2702 
2703 private:
2704     TessellationModesParams m_params;
2705 };
2706 
iterate(void)2707 tcu::TestStatus ShaderObjectTessellationModesInstance::iterate(void)
2708 {
2709     const vk::VkInstance instance = m_context.getInstance();
2710     const vk::InstanceDriver instanceDriver(m_context.getPlatformInterface(), instance);
2711     const vk::DeviceInterface &vk   = m_context.getDeviceInterface();
2712     const vk::VkDevice device       = m_context.getDevice();
2713     const vk::VkQueue queue         = m_context.getUniversalQueue();
2714     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2715     auto &alloc                     = m_context.getDefaultAllocator();
2716     tcu::TestLog &log               = m_context.getTestContext().getLog();
2717     const auto deviceExtensions     = vk::removeUnsupportedShaderObjectExtensions(
2718         m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions());
2719     const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader;
2720     const bool geometrySupported     = m_context.getDeviceFeatures().geometryShader;
2721     const bool taskSupported         = m_context.getMeshShaderFeaturesEXT().taskShader;
2722     const bool meshSupported         = m_context.getMeshShaderFeaturesEXT().meshShader;
2723 
2724     vk::VkFormat colorAttachmentFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
2725     const auto subresourceRange        = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2726     const auto subresourceLayers       = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2727     const vk::VkRect2D renderArea      = vk::makeRect2D(0, 0, 32, 32);
2728     vk::VkExtent3D extent              = {renderArea.extent.width, renderArea.extent.height, 1};
2729 
2730     const vk::VkImageCreateInfo createInfo = {
2731         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
2732         DE_NULL,                                 // const void*                pNext
2733         0u,                                      // VkImageCreateFlags        flags
2734         vk::VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
2735         colorAttachmentFormat,                   // VkFormat                    format
2736         {32, 32, 1},                             // VkExtent3D                extent
2737         1u,                                      // uint32_t                    mipLevels
2738         1u,                                      // uint32_t                    arrayLayers
2739         vk::VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
2740         vk::VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
2741         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
2742         vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode
2743         0,                             // uint32_t                    queueFamilyIndexCount
2744         DE_NULL,                       // const uint32_t*            pQueueFamilyIndices
2745         vk::VK_IMAGE_LAYOUT_UNDEFINED  // VkImageLayout            initialLayout
2746     };
2747 
2748     de::MovePtr<vk::ImageWithMemory> image = de::MovePtr<vk::ImageWithMemory>(
2749         new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
2750     const auto imageView =
2751         vk::makeImageView(vk, device, **image, vk::VK_IMAGE_VIEW_TYPE_2D, colorAttachmentFormat, subresourceRange);
2752 
2753     const vk::VkDeviceSize colorOutputBufferSize =
2754         renderArea.extent.width * renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(colorAttachmentFormat));
2755     de::MovePtr<vk::BufferWithMemory> colorOutputBuffer = de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(
2756         vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2757         vk::MemoryRequirement::HostVisible));
2758 
2759     const auto &binaries = m_context.getBinaryCollection();
2760     const auto vertShader =
2761         vk::createShader(vk, device,
2762                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vert"),
2763                                                   tessellationSupported, geometrySupported));
2764     const auto tescShader =
2765         vk::createShader(vk, device,
2766                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, binaries.get("tesc"),
2767                                                   tessellationSupported, geometrySupported));
2768     const auto teseShader =
2769         vk::createShader(vk, device,
2770                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, binaries.get("tese"),
2771                                                   tessellationSupported, geometrySupported));
2772     const auto fragShader =
2773         vk::createShader(vk, device,
2774                          vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("frag"),
2775                                                   tessellationSupported, geometrySupported));
2776 
2777     const vk::Move<vk::VkCommandPool> cmdPool(vk::createCommandPool(vk, device, 0u, queueFamilyIndex));
2778     const vk::Move<vk::VkCommandBuffer> cmdBuffer(
2779         allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2780 
2781     vk::beginCommandBuffer(vk, *cmdBuffer);
2782 
2783     vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(
2784         vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED,
2785         vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2786     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2787                           vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u,
2788                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2789                           &preImageBarrier);
2790 
2791     const vk::VkClearValue clearValue = vk::makeClearValueColor({0.0f, 0.0f, 0.0f, 0.0f});
2792     vk::beginRendering(vk, *cmdBuffer, *imageView, renderArea, clearValue, vk::VK_IMAGE_LAYOUT_GENERAL,
2793                        vk::VK_ATTACHMENT_LOAD_OP_CLEAR);
2794 
2795     vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, *tescShader, *teseShader, VK_NULL_HANDLE, *fragShader,
2796                             taskSupported, meshSupported);
2797     vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
2798 
2799     vk.cmdSetPolygonModeEXT(*cmdBuffer, vk::VK_POLYGON_MODE_LINE);
2800 
2801     vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
2802 
2803     vk::endRendering(vk, *cmdBuffer);
2804 
2805     vk::VkImageMemoryBarrier postImageBarrier =
2806         vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT,
2807                                    vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **image, subresourceRange);
2808     vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2809                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u,
2810                           (const vk::VkMemoryBarrier *)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1u,
2811                           &postImageBarrier);
2812 
2813     const vk::VkBufferImageCopy copyRegion = vk::makeBufferImageCopy(extent, subresourceLayers);
2814     vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffer, 1u, &copyRegion);
2815 
2816     vk::endCommandBuffer(vk, *cmdBuffer);
2817     vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2818 
2819     tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(
2820         vk::mapVkFormat(colorAttachmentFormat), renderArea.extent.width, renderArea.extent.height, 1,
2821         (const void *)colorOutputBuffer->getAllocation().getHostPtr());
2822 
2823     const tcu::Vec4 black = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
2824     const tcu::Vec4 white = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2825     const uint32_t width  = resultBuffer.getWidth();
2826     const uint32_t height = resultBuffer.getHeight();
2827 
2828     const bool equal1[17][17] = {
2829         {
2830             0,
2831             1,
2832             1,
2833             1,
2834             1,
2835             1,
2836             1,
2837             1,
2838             1,
2839             1,
2840             1,
2841             1,
2842             1,
2843             1,
2844             1,
2845             1,
2846             1,
2847         },
2848         {
2849             1,
2850             0,
2851             0,
2852             0,
2853             0,
2854             0,
2855             0,
2856             0,
2857             0,
2858             0,
2859             0,
2860             0,
2861             0,
2862             0,
2863             0,
2864             0,
2865             1,
2866         },
2867         {
2868             1,
2869             0,
2870             0,
2871             0,
2872             0,
2873             0,
2874             0,
2875             0,
2876             0,
2877             0,
2878             0,
2879             0,
2880             0,
2881             0,
2882             0,
2883             1,
2884             1,
2885         },
2886         {
2887             1,
2888             0,
2889             0,
2890             0,
2891             0,
2892             0,
2893             0,
2894             0,
2895             0,
2896             0,
2897             0,
2898             0,
2899             0,
2900             0,
2901             1,
2902             0,
2903             1,
2904         },
2905         {
2906             1,
2907             0,
2908             0,
2909             0,
2910             0,
2911             0,
2912             0,
2913             0,
2914             0,
2915             0,
2916             0,
2917             0,
2918             0,
2919             1,
2920             0,
2921             0,
2922             1,
2923         },
2924         {
2925             1,
2926             0,
2927             0,
2928             0,
2929             0,
2930             0,
2931             0,
2932             0,
2933             0,
2934             0,
2935             0,
2936             0,
2937             1,
2938             0,
2939             0,
2940             0,
2941             1,
2942         },
2943         {
2944             1,
2945             0,
2946             0,
2947             0,
2948             0,
2949             0,
2950             0,
2951             0,
2952             0,
2953             0,
2954             0,
2955             1,
2956             0,
2957             0,
2958             0,
2959             0,
2960             1,
2961         },
2962         {
2963             1,
2964             0,
2965             0,
2966             0,
2967             0,
2968             0,
2969             0,
2970             0,
2971             0,
2972             0,
2973             1,
2974             0,
2975             0,
2976             0,
2977             0,
2978             0,
2979             1,
2980         },
2981         {
2982             1,
2983             0,
2984             0,
2985             0,
2986             0,
2987             0,
2988             0,
2989             0,
2990             0,
2991             1,
2992             0,
2993             0,
2994             0,
2995             0,
2996             0,
2997             0,
2998             1,
2999         },
3000         {
3001             1,
3002             0,
3003             0,
3004             0,
3005             0,
3006             0,
3007             0,
3008             0,
3009             1,
3010             0,
3011             0,
3012             0,
3013             0,
3014             0,
3015             0,
3016             0,
3017             1,
3018         },
3019         {
3020             1,
3021             0,
3022             0,
3023             0,
3024             0,
3025             0,
3026             0,
3027             1,
3028             0,
3029             0,
3030             0,
3031             0,
3032             0,
3033             0,
3034             0,
3035             0,
3036             1,
3037         },
3038         {
3039             1,
3040             0,
3041             0,
3042             0,
3043             0,
3044             0,
3045             1,
3046             0,
3047             0,
3048             0,
3049             0,
3050             0,
3051             0,
3052             0,
3053             0,
3054             0,
3055             1,
3056         },
3057         {
3058             1,
3059             0,
3060             0,
3061             0,
3062             0,
3063             1,
3064             0,
3065             0,
3066             0,
3067             0,
3068             0,
3069             0,
3070             0,
3071             0,
3072             0,
3073             0,
3074             1,
3075         },
3076         {
3077             1,
3078             0,
3079             0,
3080             0,
3081             1,
3082             0,
3083             0,
3084             0,
3085             0,
3086             0,
3087             0,
3088             0,
3089             0,
3090             0,
3091             0,
3092             0,
3093             1,
3094         },
3095         {
3096             1,
3097             0,
3098             0,
3099             1,
3100             0,
3101             0,
3102             0,
3103             0,
3104             0,
3105             0,
3106             0,
3107             0,
3108             0,
3109             0,
3110             0,
3111             0,
3112             1,
3113         },
3114         {
3115             1,
3116             0,
3117             1,
3118             0,
3119             0,
3120             0,
3121             0,
3122             0,
3123             0,
3124             0,
3125             0,
3126             0,
3127             0,
3128             0,
3129             0,
3130             0,
3131             1,
3132         },
3133         {
3134             1,
3135             1,
3136             1,
3137             1,
3138             1,
3139             1,
3140             1,
3141             1,
3142             1,
3143             1,
3144             1,
3145             1,
3146             1,
3147             1,
3148             1,
3149             1,
3150             1,
3151         },
3152     };
3153 
3154     const bool even1[17][17] = {
3155         {
3156             0,
3157             1,
3158             1,
3159             1,
3160             1,
3161             1,
3162             1,
3163             1,
3164             1,
3165             1,
3166             1,
3167             1,
3168             1,
3169             1,
3170             1,
3171             1,
3172             1,
3173         },
3174         {
3175             1,
3176             1,
3177             0,
3178             0,
3179             0,
3180             0,
3181             0,
3182             0,
3183             1,
3184             0,
3185             0,
3186             0,
3187             0,
3188             0,
3189             0,
3190             0,
3191             1,
3192         },
3193         {
3194             1,
3195             0,
3196             1,
3197             0,
3198             0,
3199             0,
3200             0,
3201             0,
3202             1,
3203             0,
3204             0,
3205             0,
3206             0,
3207             0,
3208             0,
3209             1,
3210             1,
3211         },
3212         {
3213             1,
3214             0,
3215             0,
3216             1,
3217             0,
3218             0,
3219             0,
3220             0,
3221             1,
3222             0,
3223             0,
3224             0,
3225             0,
3226             0,
3227             1,
3228             0,
3229             1,
3230         },
3231         {
3232             1,
3233             0,
3234             0,
3235             0,
3236             1,
3237             0,
3238             0,
3239             0,
3240             1,
3241             0,
3242             0,
3243             0,
3244             0,
3245             1,
3246             0,
3247             0,
3248             1,
3249         },
3250         {
3251             1,
3252             0,
3253             0,
3254             0,
3255             0,
3256             1,
3257             0,
3258             0,
3259             1,
3260             0,
3261             0,
3262             0,
3263             1,
3264             0,
3265             0,
3266             0,
3267             1,
3268         },
3269         {
3270             1,
3271             0,
3272             0,
3273             0,
3274             0,
3275             0,
3276             1,
3277             0,
3278             1,
3279             0,
3280             0,
3281             1,
3282             0,
3283             0,
3284             0,
3285             0,
3286             1,
3287         },
3288         {
3289             1,
3290             0,
3291             0,
3292             0,
3293             0,
3294             0,
3295             0,
3296             1,
3297             1,
3298             0,
3299             1,
3300             0,
3301             0,
3302             0,
3303             0,
3304             0,
3305             1,
3306         },
3307         {
3308             1,
3309             1,
3310             1,
3311             1,
3312             1,
3313             1,
3314             1,
3315             1,
3316             1,
3317             1,
3318             1,
3319             1,
3320             1,
3321             1,
3322             1,
3323             1,
3324             1,
3325         },
3326         {
3327             1,
3328             0,
3329             0,
3330             0,
3331             0,
3332             0,
3333             0,
3334             0,
3335             1,
3336             1,
3337             0,
3338             0,
3339             0,
3340             0,
3341             0,
3342             0,
3343             1,
3344         },
3345         {
3346             1,
3347             0,
3348             0,
3349             0,
3350             0,
3351             0,
3352             0,
3353             1,
3354             1,
3355             0,
3356             1,
3357             0,
3358             0,
3359             0,
3360             0,
3361             0,
3362             1,
3363         },
3364         {
3365             1,
3366             0,
3367             0,
3368             0,
3369             0,
3370             0,
3371             1,
3372             0,
3373             1,
3374             0,
3375             0,
3376             1,
3377             0,
3378             0,
3379             0,
3380             0,
3381             1,
3382         },
3383         {
3384             1,
3385             0,
3386             0,
3387             0,
3388             0,
3389             1,
3390             0,
3391             0,
3392             1,
3393             0,
3394             0,
3395             0,
3396             1,
3397             0,
3398             0,
3399             0,
3400             1,
3401         },
3402         {
3403             1,
3404             0,
3405             0,
3406             0,
3407             1,
3408             0,
3409             0,
3410             0,
3411             1,
3412             0,
3413             0,
3414             0,
3415             0,
3416             1,
3417             0,
3418             0,
3419             1,
3420         },
3421         {
3422             1,
3423             0,
3424             0,
3425             1,
3426             0,
3427             0,
3428             0,
3429             0,
3430             1,
3431             0,
3432             0,
3433             0,
3434             0,
3435             0,
3436             1,
3437             0,
3438             1,
3439         },
3440         {
3441             1,
3442             0,
3443             1,
3444             0,
3445             0,
3446             0,
3447             0,
3448             0,
3449             1,
3450             0,
3451             0,
3452             0,
3453             0,
3454             0,
3455             0,
3456             1,
3457             1,
3458         },
3459         {
3460             1,
3461             1,
3462             1,
3463             1,
3464             1,
3465             1,
3466             1,
3467             1,
3468             1,
3469             1,
3470             1,
3471             1,
3472             1,
3473             1,
3474             1,
3475             1,
3476             1,
3477         },
3478     };
3479 
3480     const bool odd2[17][17] = {
3481         {
3482             0,
3483             1,
3484             1,
3485             1,
3486             1,
3487             1,
3488             1,
3489             1,
3490             1,
3491             1,
3492             1,
3493             1,
3494             1,
3495             1,
3496             1,
3497             1,
3498             1,
3499         },
3500         {
3501             1,
3502             1,
3503             0,
3504             1,
3505             0,
3506             0,
3507             0,
3508             0,
3509             0,
3510             0,
3511             1,
3512             1,
3513             1,
3514             1,
3515             1,
3516             0,
3517             1,
3518         },
3519         {
3520             1,
3521             0,
3522             1,
3523             1,
3524             0,
3525             0,
3526             1,
3527             1,
3528             1,
3529             1,
3530             0,
3531             0,
3532             0,
3533             0,
3534             1,
3535             1,
3536             1,
3537         },
3538         {
3539             1,
3540             1,
3541             1,
3542             1,
3543             1,
3544             1,
3545             1,
3546             1,
3547             1,
3548             1,
3549             1,
3550             1,
3551             1,
3552             1,
3553             1,
3554             1,
3555             1,
3556         },
3557         {
3558             1,
3559             1,
3560             0,
3561             1,
3562             0,
3563             0,
3564             0,
3565             0,
3566             0,
3567             0,
3568             0,
3569             0,
3570             0,
3571             1,
3572             1,
3573             0,
3574             1,
3575         },
3576         {
3577             1,
3578             1,
3579             0,
3580             1,
3581             0,
3582             0,
3583             0,
3584             0,
3585             0,
3586             0,
3587             0,
3588             0,
3589             1,
3590             0,
3591             1,
3592             0,
3593             1,
3594         },
3595         {
3596             1,
3597             1,
3598             0,
3599             1,
3600             0,
3601             0,
3602             0,
3603             0,
3604             0,
3605             0,
3606             0,
3607             1,
3608             0,
3609             0,
3610             1,
3611             1,
3612             1,
3613         },
3614         {
3615             1,
3616             1,
3617             0,
3618             1,
3619             0,
3620             0,
3621             0,
3622             0,
3623             0,
3624             0,
3625             1,
3626             0,
3627             0,
3628             0,
3629             1,
3630             1,
3631             1,
3632         },
3633         {
3634             1,
3635             0,
3636             1,
3637             1,
3638             0,
3639             0,
3640             0,
3641             0,
3642             0,
3643             1,
3644             0,
3645             0,
3646             0,
3647             0,
3648             1,
3649             1,
3650             1,
3651         },
3652         {
3653             1,
3654             0,
3655             1,
3656             1,
3657             0,
3658             0,
3659             0,
3660             0,
3661             1,
3662             0,
3663             0,
3664             0,
3665             0,
3666             0,
3667             1,
3668             1,
3669             1,
3670         },
3671         {
3672             1,
3673             0,
3674             1,
3675             1,
3676             0,
3677             0,
3678             0,
3679             1,
3680             0,
3681             0,
3682             0,
3683             0,
3684             0,
3685             0,
3686             1,
3687             0,
3688             1,
3689         },
3690         {
3691             1,
3692             0,
3693             1,
3694             1,
3695             0,
3696             0,
3697             1,
3698             0,
3699             0,
3700             0,
3701             0,
3702             0,
3703             0,
3704             0,
3705             1,
3706             0,
3707             1,
3708         },
3709         {
3710             1,
3711             0,
3712             0,
3713             1,
3714             0,
3715             1,
3716             0,
3717             0,
3718             0,
3719             0,
3720             0,
3721             0,
3722             0,
3723             0,
3724             1,
3725             0,
3726             1,
3727         },
3728         {
3729             1,
3730             0,
3731             0,
3732             1,
3733             1,
3734             0,
3735             0,
3736             0,
3737             0,
3738             0,
3739             0,
3740             0,
3741             0,
3742             0,
3743             1,
3744             0,
3745             1,
3746         },
3747         {
3748             1,
3749             1,
3750             1,
3751             1,
3752             1,
3753             1,
3754             1,
3755             1,
3756             1,
3757             1,
3758             1,
3759             1,
3760             1,
3761             1,
3762             1,
3763             1,
3764             1,
3765         },
3766         {
3767             1,
3768             0,
3769             1,
3770             1,
3771             0,
3772             0,
3773             0,
3774             0,
3775             1,
3776             1,
3777             1,
3778             1,
3779             0,
3780             0,
3781             1,
3782             1,
3783             1,
3784         },
3785         {
3786             1,
3787             1,
3788             1,
3789             1,
3790             1,
3791             1,
3792             1,
3793             1,
3794             1,
3795             1,
3796             1,
3797             1,
3798             1,
3799             1,
3800             1,
3801             1,
3802             1,
3803         },
3804     };
3805 
3806     for (uint32_t j = 0; j < height; ++j)
3807     {
3808         for (uint32_t i = 0; i < width; ++i)
3809         {
3810             const tcu::Vec4 color = resultBuffer.getPixel(i, j).asFloat();
3811 
3812             bool inside = false;
3813             if (i >= 7 && i < 24 && j >= 7 && j < 24)
3814             {
3815                 if ((m_params.subdivision == 1 && m_params.spacing == EQUAL) ||
3816                     (m_params.subdivision == 1 && m_params.spacing == ODD))
3817                     inside |= equal1[j - 7][i - 7];
3818                 else if ((m_params.subdivision == 1 && m_params.spacing == EVEN) ||
3819                          (m_params.subdivision == 2 && m_params.spacing == EQUAL) ||
3820                          (m_params.subdivision == 2 && m_params.spacing == EVEN))
3821                     inside |= even1[j - 7][i - 7];
3822                 else if (m_params.subdivision == 2 && m_params.spacing == ODD)
3823                     inside |= odd2[j - 7][i - 7];
3824             }
3825 
3826             if (inside)
3827             {
3828                 if (color != white)
3829                 {
3830                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j
3831                         << ") is expected to be (1.0, 1.0, 1.0, 1.0), but was (" << color << ")"
3832                         << tcu::TestLog::EndMessage;
3833                     return tcu::TestStatus::fail("Fail");
3834                 }
3835             }
3836             else
3837             {
3838                 if (color != black)
3839                 {
3840                     log << tcu::TestLog::Message << "Color at (" << i << ", " << j
3841                         << ") is expected to be (0.0, 0.0, 0.0, 0.0), but was (" << color << ")"
3842                         << tcu::TestLog::EndMessage;
3843                     return tcu::TestStatus::fail("Fail");
3844                 }
3845             }
3846         }
3847     }
3848 
3849     return tcu::TestStatus::pass("Pass");
3850 }
3851 
3852 class ShaderObjectTessellationModesCase : public vkt::TestCase
3853 {
3854 public:
ShaderObjectTessellationModesCase(tcu::TestContext & testCtx,const std::string & name,const TessellationModesParams & testParams)3855     ShaderObjectTessellationModesCase(tcu::TestContext &testCtx, const std::string &name,
3856                                       const TessellationModesParams &testParams)
3857         : vkt::TestCase(testCtx, name)
3858         , m_params(testParams)
3859     {
3860     }
~ShaderObjectTessellationModesCase(void)3861     virtual ~ShaderObjectTessellationModesCase(void)
3862     {
3863     }
3864 
3865     void checkSupport(vkt::Context &context) const override;
3866     virtual void initPrograms(vk::SourceCollections &programCollection) const override;
createInstance(Context & context) const3867     TestInstance *createInstance(Context &context) const override
3868     {
3869         return new ShaderObjectTessellationModesInstance(context, m_params);
3870     }
3871 
3872 private:
3873     const TessellationModesParams m_params;
3874 };
3875 
checkSupport(vkt::Context & context) const3876 void ShaderObjectTessellationModesCase::checkSupport(vkt::Context &context) const
3877 {
3878     context.requireDeviceFunctionality("VK_EXT_shader_object");
3879     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
3880 }
3881 
initPrograms(vk::SourceCollections & programCollection) const3882 void ShaderObjectTessellationModesCase::initPrograms(vk::SourceCollections &programCollection) const
3883 {
3884     std::stringstream vert;
3885     std::stringstream tesc;
3886     std::stringstream tese;
3887     std::stringstream frag;
3888 
3889     vert << "#version 450\n"
3890          << "void main() {\n"
3891          << "    vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n"
3892          << "    gl_Position = vec4(pos - 0.5f, 0.0f, 1.0f);\n"
3893          << "}\n";
3894 
3895     tesc << "#version 450\n"
3896          << "\n"
3897          << "layout(vertices = 4) out;\n"
3898          << "\n"
3899          << "void main (void)\n"
3900          << "{\n"
3901          << "    if (gl_InvocationID == 0) {\n";
3902     if (m_params.subdivision == 1)
3903         tesc << "    float subdivision = 1.0f;\n";
3904     else
3905         tesc << "    float subdivision = 2.0f;\n";
3906     tesc << "        gl_TessLevelInner[0] = subdivision;\n"
3907          << "        gl_TessLevelInner[1] = subdivision;\n"
3908          << "        gl_TessLevelOuter[0] = subdivision;\n"
3909          << "        gl_TessLevelOuter[1] = subdivision;\n"
3910          << "        gl_TessLevelOuter[2] = subdivision;\n"
3911          << "        gl_TessLevelOuter[3] = subdivision;\n"
3912          << "    }\n"
3913          << "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3914          << "}\n";
3915 
3916     tese << "#version 450\n"
3917          << "\n";
3918     if (m_params.spacing == EQUAL)
3919         tese << "layout(quads, equal_spacing) in;\n";
3920     else if (m_params.spacing == EVEN)
3921         tese << "layout(quads, fractional_even_spacing) in;\n";
3922     else
3923         tese << "layout(quads, fractional_odd_spacing) in;\n";
3924     tese << "\n"
3925          << "void main (void)\n"
3926          << "{\n"
3927          << "    float u = gl_TessCoord.x;\n"
3928          << "    float v = gl_TessCoord.y;\n"
3929          << "    float omu = 1.0f - u;\n"
3930          << "    float omv = 1.0f - v;\n"
3931          << "    gl_Position = omu * omv * gl_in[0].gl_Position + u * omv * gl_in[2].gl_Position + u * v * "
3932             "gl_in[3].gl_Position + omu * v * gl_in[1].gl_Position;\n"
3933          << "}\n";
3934 
3935     frag << "#version 450\n"
3936          << "layout (location=0) out vec4 outColor;\n"
3937          << "void main() {\n"
3938          << "    outColor = vec4(1.0f);\n"
3939          << "}\n";
3940     programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
3941     programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
3942     programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
3943     programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
3944 }
3945 
3946 } // namespace
3947 
createShaderObjectMiscTests(tcu::TestContext & testCtx)3948 tcu::TestCaseGroup *createShaderObjectMiscTests(tcu::TestContext &testCtx)
3949 {
3950     de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc"));
3951 
3952     const struct
3953     {
3954         uint32_t stride;
3955         const char *name;
3956     } strideTests[] = {
3957         {
3958             16,
3959             "16",
3960         },
3961         {
3962             32,
3963             "32",
3964         },
3965         {
3966             48,
3967             "48",
3968         },
3969         {
3970             40,
3971             "40",
3972         },
3973     };
3974 
3975     for (uint32_t i = 0; i < 2; ++i)
3976     {
3977         bool blend1 = i == 0;
3978         de::MovePtr<tcu::TestCaseGroup> blend1Group(new tcu::TestCaseGroup(testCtx, blend1 ? "on" : "off"));
3979         for (uint32_t j = 0; j < 2; ++j)
3980         {
3981             bool blend2 = j == 0;
3982             de::MovePtr<tcu::TestCaseGroup> blend2Group(new tcu::TestCaseGroup(testCtx, blend2 ? "on" : "off"));
3983             for (uint32_t k = 0; k < 2; ++k)
3984             {
3985                 bool vertexInputBefore = k == 0;
3986                 de::MovePtr<tcu::TestCaseGroup> vertexInputBeforeGroup(
3987                     new tcu::TestCaseGroup(testCtx, vertexInputBefore ? "before" : "after"));
3988                 for (uint32_t l = 0; l < 2; ++l)
3989                 {
3990                     bool vertexBuffersNullStride = l == 0;
3991                     de::MovePtr<tcu::TestCaseGroup> vertexBuffersNullStrideGroup(
3992                         new tcu::TestCaseGroup(testCtx, vertexBuffersNullStride ? "null" : "non_null"));
3993                     for (const auto &strideTest : strideTests)
3994                     {
3995                         de::MovePtr<tcu::TestCaseGroup> strideGroup(new tcu::TestCaseGroup(testCtx, strideTest.name));
3996                         for (uint32_t m = 0; m < 2; ++m)
3997                         {
3998                             bool destroyDescriptorSetLayout = m == 1;
3999                             std::string destroyName         = destroyDescriptorSetLayout ? "set" : "destroyed";
4000 
4001                             TestParams params;
4002                             params.blendEnabled[0]            = blend1;
4003                             params.blendEnabled[1]            = blend2;
4004                             params.vertexInputBefore          = vertexInputBefore;
4005                             params.vertexBuffersNullStride    = vertexBuffersNullStride;
4006                             params.stride                     = strideTest.stride;
4007                             params.destroyDescriptorSetLayout = destroyDescriptorSetLayout;
4008                             strideGroup->addChild(new ShaderObjectMiscCase(testCtx, destroyName, params));
4009                         }
4010                         vertexBuffersNullStrideGroup->addChild(strideGroup.release());
4011                     }
4012                     vertexInputBeforeGroup->addChild(vertexBuffersNullStrideGroup.release());
4013                 }
4014                 blend2Group->addChild(vertexInputBeforeGroup.release());
4015             }
4016             blend1Group->addChild(blend2Group.release());
4017         }
4018         miscGroup->addChild(blend1Group.release());
4019     }
4020 
4021     const struct
4022     {
4023         bool pipeline;
4024         const char *name;
4025     } pipelineTests[] = {
4026         {false, "shaders"},
4027         {true, "pipeline"},
4028     };
4029 
4030     const struct
4031     {
4032         bool meshShader;
4033         bool vertShader;
4034         bool tessShader;
4035         bool geomShader;
4036         bool fragShader;
4037         const char *name;
4038     } shadersTests[] = {
4039         {
4040             false,
4041             true,
4042             false,
4043             false,
4044             false,
4045             "vert",
4046         },
4047         {
4048             false,
4049             true,
4050             false,
4051             false,
4052             true,
4053             "vert_frag",
4054         },
4055         {
4056             false,
4057             true,
4058             true,
4059             false,
4060             true,
4061             "vert_tess_frag",
4062         },
4063         {
4064             false,
4065             true,
4066             false,
4067             true,
4068             true,
4069             "vert_geom_frag",
4070         },
4071         {
4072             false,
4073             true,
4074             true,
4075             true,
4076             true,
4077             "vert_tess_geom_frag",
4078         },
4079         {
4080             true,
4081             false,
4082             false,
4083             false,
4084             true,
4085             "mesh_frag",
4086         },
4087     };
4088 
4089     const struct
4090     {
4091         bool alphaToOne;
4092         const char *name;
4093     } alphaToOneTests[] = {
4094         {false, "disabled"},
4095         {true, "enabled"},
4096     };
4097 
4098     const struct
4099     {
4100         bool depthTestEnable;
4101         bool depthBounds;
4102         bool depthBoundsTestEnable;
4103         bool depthClamp;
4104         bool depthClip;
4105         bool depthClipControl;
4106         bool depthBiasEnable;
4107         const char *name;
4108     } depthTests[]{
4109         {false, false, false, false, false, false, false, "none"},
4110         {true, true, false, false, false, false, false, "bounds_disabled"},
4111         {true, true, true, false, false, false, false, "bounds_enabled"},
4112         {true, false, false, true, false, false, false, "clamp"},
4113         {true, false, false, false, true, false, false, "clip"},
4114         {true, false, false, false, false, true, false, "clip_control"},
4115         {true, false, false, false, false, false, true, "bias"},
4116     };
4117 
4118     const struct
4119     {
4120         bool discardRectangles;
4121         bool discardRectanglesEnabled;
4122         const char *name;
4123     } discardRectanglesTests[] = {
4124         {false, false, "disabled"},
4125         {true, false, "enabled"},
4126         {true, true, "discard"},
4127     };
4128 
4129     const struct
4130     {
4131         bool rasterizationDiscardEnable;
4132         const char *name;
4133     } rasterizationDiscardEnableTests[] = {
4134         {false, "disabled"},
4135         {true, "enabled"},
4136     };
4137 
4138     const struct
4139     {
4140         bool colorBlendEnable;
4141         const char *name;
4142     } colorBlendTests[] = {
4143         {false, "disabled"},
4144         {true, "enabled"},
4145     };
4146 
4147     const struct
4148     {
4149         bool lines;
4150         const char *name;
4151     } primitiveTests[] = {
4152         {false, "triangles"},
4153         {true, "lines"},
4154     };
4155 
4156     const struct
4157     {
4158         bool stencilEnable;
4159         const char *name;
4160     } stencilTests[] = {
4161         {false, "disabled"},
4162         {true, "enabled"},
4163     };
4164 
4165     const struct
4166     {
4167         bool logicOp;
4168         bool logicOpEnable;
4169         const char *name;
4170     } logicOpTests[] = {
4171         {false, false, "disabled"},
4172         {true, false, "enabled"},
4173         {true, true, "copy"},
4174     };
4175 
4176     const struct
4177     {
4178         bool geometryStreams;
4179         const char *name;
4180     } geometryStreamsTests[] = {
4181         {false, "disabled"},
4182         {true, "enabled"},
4183     };
4184 
4185     const struct
4186     {
4187         bool provokingVertex;
4188         const char *name;
4189     } provokingVertexTests[] = {
4190         {false, "disabled"},
4191         {true, "enabled"},
4192     };
4193 
4194     const struct
4195     {
4196         bool sampleLocations;
4197         bool sampleLocationsEnable;
4198         const char *name;
4199     } sampleLocationsTests[] = {
4200         {false, false, "disabled"},
4201         {true, false, "enabled"},
4202         {true, true, "used"},
4203     };
4204 
4205     const struct
4206     {
4207         bool lineRasterization;
4208         bool stippledLineEnable;
4209         const char *name;
4210     } linesTests[] = {
4211         {false, false, "default"},
4212         {true, false, "rectangular"},
4213         {true, true, "rectangular_stippled"},
4214     };
4215 
4216     const struct
4217     {
4218         bool cull;
4219         const char *name;
4220     } cullTests[] = {
4221         {false, "none"},
4222         {true, "front_and_back"},
4223     };
4224 
4225     const struct
4226     {
4227         bool conservativeRasterization;
4228         bool conservativeRasterizationOverestimate;
4229         const char *name;
4230     } conservativeRasterizationTests[] = {
4231         {false, false, "disabled"},
4232         {true, false, "enabled"},
4233         {true, true, "overestimate"},
4234     };
4235 
4236     const struct
4237     {
4238         bool colorWrite;
4239         bool colorWriteEnable;
4240         const char *name;
4241     } colorWriteEnableTests[] = {
4242         {false, false, "disabled"},
4243         {true, false, "false"},
4244         {true, true, "true"},
4245     };
4246 
4247     de::MovePtr<tcu::TestCaseGroup> stateGroup(new tcu::TestCaseGroup(testCtx, "state"));
4248     for (const auto &pipelineTest : pipelineTests)
4249     {
4250         de::MovePtr<tcu::TestCaseGroup> pipelineGroup(new tcu::TestCaseGroup(testCtx, pipelineTest.name));
4251         for (const auto shadersTest : shadersTests)
4252         {
4253             de::MovePtr<tcu::TestCaseGroup> shadersGroup(new tcu::TestCaseGroup(testCtx, shadersTest.name));
4254 
4255             StateTestParams params;
4256             params.pipeline   = pipelineTest.pipeline;
4257             params.meshShader = shadersTest.meshShader;
4258             params.vertShader = shadersTest.vertShader;
4259             params.tessShader = shadersTest.tessShader;
4260             params.geomShader = shadersTest.geomShader;
4261             params.fragShader = shadersTest.fragShader;
4262             params.reset();
4263 
4264             de::MovePtr<tcu::TestCaseGroup> alphaToOneGroup(new tcu::TestCaseGroup(testCtx, "alphaToOne"));
4265             for (const auto &alphaToOneTest : alphaToOneTests)
4266             {
4267                 params.alphaToOne = alphaToOneTest.alphaToOne;
4268                 alphaToOneGroup->addChild(new ShaderObjectStateCase(testCtx, alphaToOneTest.name, params));
4269             }
4270             shadersGroup->addChild(alphaToOneGroup.release());
4271             params.reset();
4272 
4273             de::MovePtr<tcu::TestCaseGroup> depthGroup(new tcu::TestCaseGroup(testCtx, "depth"));
4274             for (const auto &depthTest : depthTests)
4275             {
4276                 params.depthTestEnable       = depthTest.depthTestEnable;
4277                 params.depthBounds           = depthTest.depthBounds;
4278                 params.depthBoundsTestEnable = depthTest.depthBoundsTestEnable;
4279                 params.depthClamp            = depthTest.depthClamp;
4280                 params.depthClip             = depthTest.depthClip;
4281                 params.depthClipControl      = depthTest.depthClipControl;
4282                 params.depthBiasEnable       = depthTest.depthBiasEnable;
4283                 depthGroup->addChild(new ShaderObjectStateCase(testCtx, depthTest.name, params));
4284             }
4285             shadersGroup->addChild(depthGroup.release());
4286             params.reset();
4287 
4288             de::MovePtr<tcu::TestCaseGroup> discardRectanglesGroup(
4289                 new tcu::TestCaseGroup(testCtx, "discard_rectangles"));
4290             for (const auto &discardRectangles : discardRectanglesTests)
4291             {
4292                 params.discardRectangles       = discardRectangles.discardRectangles;
4293                 params.discardRectanglesEnable = discardRectangles.discardRectanglesEnabled;
4294                 discardRectanglesGroup->addChild(new ShaderObjectStateCase(testCtx, discardRectangles.name, params));
4295             }
4296             shadersGroup->addChild(discardRectanglesGroup.release());
4297             params.reset();
4298 
4299             de::MovePtr<tcu::TestCaseGroup> rasterizationDiscardEnableGroup(
4300                 new tcu::TestCaseGroup(testCtx, "rasterization_discard"));
4301             for (const auto &rasterizationDiscardTest : rasterizationDiscardEnableTests)
4302             {
4303                 params.rasterizerDiscardEnable = rasterizationDiscardTest.rasterizationDiscardEnable;
4304                 rasterizationDiscardEnableGroup->addChild(
4305                     new ShaderObjectStateCase(testCtx, rasterizationDiscardTest.name, params));
4306             }
4307             shadersGroup->addChild(rasterizationDiscardEnableGroup.release());
4308             params.reset();
4309 
4310             de::MovePtr<tcu::TestCaseGroup> colorBlendGroup(new tcu::TestCaseGroup(testCtx, "color_blend"));
4311             for (const auto &colorBlendTest : colorBlendTests)
4312             {
4313                 params.colorBlendEnable = colorBlendTest.colorBlendEnable;
4314                 colorBlendGroup->addChild(new ShaderObjectStateCase(testCtx, colorBlendTest.name, params));
4315             }
4316             shadersGroup->addChild(colorBlendGroup.release());
4317             params.reset();
4318 
4319             de::MovePtr<tcu::TestCaseGroup> primitivesGroup(new tcu::TestCaseGroup(testCtx, "primitives"));
4320             for (const auto &primitivesTest : primitiveTests)
4321             {
4322                 params.lines = primitivesTest.lines;
4323                 primitivesGroup->addChild(new ShaderObjectStateCase(testCtx, primitivesTest.name, params));
4324             }
4325             shadersGroup->addChild(primitivesGroup.release());
4326             params.reset();
4327 
4328             de::MovePtr<tcu::TestCaseGroup> stencilGroup(new tcu::TestCaseGroup(testCtx, "stencil"));
4329             for (const auto &stencilTest : stencilTests)
4330             {
4331                 params.stencilTestEnable = stencilTest.stencilEnable;
4332                 stencilGroup->addChild(new ShaderObjectStateCase(testCtx, stencilTest.name, params));
4333             }
4334             shadersGroup->addChild(stencilGroup.release());
4335             params.reset();
4336 
4337             de::MovePtr<tcu::TestCaseGroup> logicOpGroup(new tcu::TestCaseGroup(testCtx, "logic_op"));
4338             for (const auto &logicOpTest : logicOpTests)
4339             {
4340                 params.logicOp       = logicOpTest.logicOp;
4341                 params.logicOpEnable = logicOpTest.logicOpEnable;
4342                 logicOpGroup->addChild(new ShaderObjectStateCase(testCtx, logicOpTest.name, params));
4343             }
4344             shadersGroup->addChild(logicOpGroup.release());
4345             params.reset();
4346 
4347             if (shadersTest.geomShader)
4348             {
4349                 de::MovePtr<tcu::TestCaseGroup> geometryStreamsGroup(
4350                     new tcu::TestCaseGroup(testCtx, "geometry_streams"));
4351                 for (const auto &geometryStreamsTest : geometryStreamsTests)
4352                 {
4353                     params.geometryStreams = geometryStreamsTest.geometryStreams;
4354                     geometryStreamsGroup->addChild(
4355                         new ShaderObjectStateCase(testCtx, geometryStreamsTest.name, params));
4356                 }
4357                 shadersGroup->addChild(geometryStreamsGroup.release());
4358                 params.reset();
4359             }
4360 
4361             de::MovePtr<tcu::TestCaseGroup> provokingVertexGroup(new tcu::TestCaseGroup(testCtx, "provoking_vertex"));
4362             for (const auto &provokingVertexTest : provokingVertexTests)
4363             {
4364                 params.provokingVertex = provokingVertexTest.provokingVertex;
4365                 provokingVertexGroup->addChild(new ShaderObjectStateCase(testCtx, provokingVertexTest.name, params));
4366             }
4367             shadersGroup->addChild(provokingVertexGroup.release());
4368             params.reset();
4369 
4370             de::MovePtr<tcu::TestCaseGroup> sampleLocationsGroup(new tcu::TestCaseGroup(testCtx, "sample_locations"));
4371             for (const auto &sampleLocationsTest : sampleLocationsTests)
4372             {
4373                 params.sampleLocations       = sampleLocationsTest.sampleLocations;
4374                 params.sampleLocationsEnable = sampleLocationsTest.sampleLocationsEnable;
4375                 sampleLocationsGroup->addChild(new ShaderObjectStateCase(testCtx, sampleLocationsTest.name, params));
4376             }
4377             shadersGroup->addChild(sampleLocationsGroup.release());
4378             params.reset();
4379 
4380             de::MovePtr<tcu::TestCaseGroup> linesGroup(new tcu::TestCaseGroup(testCtx, "lines"));
4381             for (const auto &linesTest : linesTests)
4382             {
4383                 params.lines              = true;
4384                 params.stippledLineEnable = linesTest.stippledLineEnable;
4385                 params.lineRasterization  = linesTest.lineRasterization;
4386                 linesGroup->addChild(new ShaderObjectStateCase(testCtx, linesTest.name, params));
4387             }
4388             shadersGroup->addChild(linesGroup.release());
4389             params.reset();
4390 
4391             de::MovePtr<tcu::TestCaseGroup> cullGroup(new tcu::TestCaseGroup(testCtx, "cull"));
4392             for (const auto &cullTest : cullTests)
4393             {
4394                 params.cull = cullTest.cull;
4395                 cullGroup->addChild(new ShaderObjectStateCase(testCtx, cullTest.name, params));
4396             }
4397             shadersGroup->addChild(cullGroup.release());
4398             params.reset();
4399 
4400             de::MovePtr<tcu::TestCaseGroup> conservativeRasterizationGroup(
4401                 new tcu::TestCaseGroup(testCtx, "conservative_rasterization"));
4402             for (const auto &conservativeRasterizationTest : conservativeRasterizationTests)
4403             {
4404                 params.conservativeRasterization = conservativeRasterizationTest.conservativeRasterization;
4405                 params.conservativeRasterizationOverestimate =
4406                     conservativeRasterizationTest.conservativeRasterizationOverestimate;
4407                 conservativeRasterizationGroup->addChild(
4408                     new ShaderObjectStateCase(testCtx, conservativeRasterizationTest.name, params));
4409             }
4410             shadersGroup->addChild(conservativeRasterizationGroup.release());
4411             params.reset();
4412 
4413             de::MovePtr<tcu::TestCaseGroup> colorWriteGroup(new tcu::TestCaseGroup(testCtx, "color_write"));
4414             for (const auto &colorWriteEnableTest : colorWriteEnableTests)
4415             {
4416                 params.colorWrite       = colorWriteEnableTest.colorWrite;
4417                 params.colorWriteEnable = colorWriteEnableTest.colorWriteEnable;
4418                 colorWriteGroup->addChild(new ShaderObjectStateCase(testCtx, colorWriteEnableTest.name, params));
4419             }
4420             shadersGroup->addChild(colorWriteGroup.release());
4421             params.reset();
4422 
4423             pipelineGroup->addChild(shadersGroup.release());
4424         }
4425         stateGroup->addChild(pipelineGroup.release());
4426     }
4427     miscGroup->addChild(stateGroup.release());
4428 
4429     const struct
4430     {
4431         bool linked;
4432         const char *name;
4433     } linkedTests[] = {
4434         {false, "unlinked"},
4435         {true, "linked"},
4436     };
4437 
4438     const struct
4439     {
4440         vk::VkShaderStageFlagBits stage;
4441         const char *name;
4442     } shaderStageTests[] = {
4443         {vk::VK_SHADER_STAGE_VERTEX_BIT, "vert"},
4444         {vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc"},
4445         {vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese"},
4446         {vk::VK_SHADER_STAGE_GEOMETRY_BIT, "geom"},
4447     };
4448 
4449     const struct
4450     {
4451         bool builtin;
4452         const char *name;
4453     } typeTests[] = {
4454         {false, "output"},
4455         {true, "builtin"},
4456     };
4457 
4458     de::MovePtr<tcu::TestCaseGroup> unusedVariableGroup(new tcu::TestCaseGroup(testCtx, "unused_variable"));
4459     for (const auto &linkedTest : linkedTests)
4460     {
4461         de::MovePtr<tcu::TestCaseGroup> linkedGroup(new tcu::TestCaseGroup(testCtx, linkedTest.name));
4462         for (const auto &typeTest : typeTests)
4463         {
4464             de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, typeTest.name));
4465             for (const auto &shaderStageTest : shaderStageTests)
4466             {
4467                 UnusedBuiltinParams params;
4468                 params.linked  = linkedTest.linked;
4469                 params.stage   = shaderStageTest.stage;
4470                 params.builtin = typeTest.builtin;
4471                 typeGroup->addChild(new ShaderObjectUnusedBuiltinCase(testCtx, shaderStageTest.name, params));
4472             }
4473             linkedGroup->addChild(typeGroup.release());
4474         }
4475         unusedVariableGroup->addChild(linkedGroup.release());
4476     }
4477     miscGroup->addChild(unusedVariableGroup.release());
4478 
4479     const struct
4480     {
4481         uint32_t subdivision;
4482         const char *name;
4483     } subdivisionTests[] = {
4484         {1, "one"},
4485         {2, "two"},
4486     };
4487 
4488     const struct
4489     {
4490         TessellationSpacing spacing;
4491         const char *name;
4492     } spacingTests[] = {
4493         {EQUAL, "equal"},
4494         {EVEN, "even"},
4495         {ODD, "odd"},
4496     };
4497 
4498     de::MovePtr<tcu::TestCaseGroup> tessellationModesGroup(new tcu::TestCaseGroup(testCtx, "tessellation_modes"));
4499     for (const auto &subdivisionTest : subdivisionTests)
4500     {
4501         de::MovePtr<tcu::TestCaseGroup> subdivisionGroup(new tcu::TestCaseGroup(testCtx, subdivisionTest.name));
4502 
4503         for (const auto &spacingTest : spacingTests)
4504         {
4505             TessellationModesParams params;
4506             params.subdivision = subdivisionTest.subdivision;
4507             params.spacing     = spacingTest.spacing;
4508             subdivisionGroup->addChild(new ShaderObjectTessellationModesCase(testCtx, spacingTest.name, params));
4509         }
4510         tessellationModesGroup->addChild(subdivisionGroup.release());
4511     }
4512     miscGroup->addChild(tessellationModesGroup.release());
4513 
4514     return miscGroup.release();
4515 }
4516 
4517 } // namespace ShaderObject
4518 } // namespace vkt
4519