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