Test ViewportIndex SPIR-V builtin in frag shaders
authorRicardo Garcia <rgarcia@igalia.com>
Thu, 12 Mar 2020 14:52:13 +0000 (15:52 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 3 Apr 2020 09:21:14 +0000 (05:21 -0400)
Add new tests checking the ViewportIndex SPIR-V builtin, when used as
gl_ViewportIndex from GLSL, works properly in fragment shaders.

New tests:
dEQP-VK.draw.shader_viewport_index.fragment_shader_*

Affected tests:
dEQP-VK.draw.shader_viewport_index.*

Components: Vulkan
VK-GL-CTS issue: 2262

Change-Id: Ib66326bab17177d59bbc0802e1cdc7534d825a93

android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/draw/vktDrawShaderViewportIndexTests.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt

index 8baedb0..f6b5268 100644 (file)
@@ -113409,6 +113409,22 @@ dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan_
 dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan_attrib_divisor_2_multiview
 dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan_attrib_divisor_4_multiview
 dEQP-VK.draw.instanced.draw_indexed_indirect_vk_primitive_topology_triangle_fan_attrib_divisor_20_multiview
+dEQP-VK.draw.shader_viewport_index.fragment_shader_1
+dEQP-VK.draw.shader_viewport_index.fragment_shader_2
+dEQP-VK.draw.shader_viewport_index.fragment_shader_3
+dEQP-VK.draw.shader_viewport_index.fragment_shader_4
+dEQP-VK.draw.shader_viewport_index.fragment_shader_5
+dEQP-VK.draw.shader_viewport_index.fragment_shader_6
+dEQP-VK.draw.shader_viewport_index.fragment_shader_7
+dEQP-VK.draw.shader_viewport_index.fragment_shader_8
+dEQP-VK.draw.shader_viewport_index.fragment_shader_9
+dEQP-VK.draw.shader_viewport_index.fragment_shader_10
+dEQP-VK.draw.shader_viewport_index.fragment_shader_11
+dEQP-VK.draw.shader_viewport_index.fragment_shader_12
+dEQP-VK.draw.shader_viewport_index.fragment_shader_13
+dEQP-VK.draw.shader_viewport_index.fragment_shader_14
+dEQP-VK.draw.shader_viewport_index.fragment_shader_15
+dEQP-VK.draw.shader_viewport_index.fragment_shader_16
 dEQP-VK.draw.scissor.static_scissor_two_quads
 dEQP-VK.draw.scissor.static_scissor_two_clears
 dEQP-VK.draw.scissor.two_static_scissors_one_quad
index f47c882..422b6f3 100644 (file)
@@ -416368,6 +416368,22 @@ dEQP-VK.draw.shader_viewport_index.vertex_shader_13
 dEQP-VK.draw.shader_viewport_index.vertex_shader_14
 dEQP-VK.draw.shader_viewport_index.vertex_shader_15
 dEQP-VK.draw.shader_viewport_index.vertex_shader_16
+dEQP-VK.draw.shader_viewport_index.fragment_shader_1
+dEQP-VK.draw.shader_viewport_index.fragment_shader_2
+dEQP-VK.draw.shader_viewport_index.fragment_shader_3
+dEQP-VK.draw.shader_viewport_index.fragment_shader_4
+dEQP-VK.draw.shader_viewport_index.fragment_shader_5
+dEQP-VK.draw.shader_viewport_index.fragment_shader_6
+dEQP-VK.draw.shader_viewport_index.fragment_shader_7
+dEQP-VK.draw.shader_viewport_index.fragment_shader_8
+dEQP-VK.draw.shader_viewport_index.fragment_shader_9
+dEQP-VK.draw.shader_viewport_index.fragment_shader_10
+dEQP-VK.draw.shader_viewport_index.fragment_shader_11
+dEQP-VK.draw.shader_viewport_index.fragment_shader_12
+dEQP-VK.draw.shader_viewport_index.fragment_shader_13
+dEQP-VK.draw.shader_viewport_index.fragment_shader_14
+dEQP-VK.draw.shader_viewport_index.fragment_shader_15
+dEQP-VK.draw.shader_viewport_index.fragment_shader_16
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_1
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_2
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_3
index 53275e5..47f9605 100644 (file)
@@ -38,6 +38,8 @@
 #include "vkQueryUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkObjUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkBufferWithMemory.hpp"
 
 #include "tcuTestLog.hpp"
 #include "tcuVector.hpp"
@@ -48,6 +50,7 @@
 #include "deMath.h"
 
 #include <vector>
+#include <memory>
 
 namespace vkt
 {
@@ -457,6 +460,49 @@ void initVertexTestPrograms (SourceCollections& programCollection, const int num
        }
 }
 
+void initFragmentTestPrograms (SourceCollections& programCollection, const int numViewports)
+{
+       // Vertex shader.
+       {
+               std::ostringstream src;
+               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                       << "#extension GL_ARB_shader_viewport_layer_array : require\n"
+                       << "\n"
+                       << "layout(location = 0) in  vec4 in_position;\n"
+                       << "layout(location = 1) in  vec4 in_color;\n"
+                       << "layout(location = 0) out vec4 out_color;\n"
+                       << "\n"
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    gl_ViewportIndex = gl_VertexIndex / 6;\n"
+                       << "    gl_Position = in_position;\n"
+                       << "    out_color = in_color;\n"
+                       << "}\n";
+
+               programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+       }
+
+       // Fragment shader
+       {
+               // Ignore input color and choose one using the viewport index.
+               std::ostringstream src;
+               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                       << "\n"
+                       << "layout(location = 0) in  vec4 in_color;\n"
+                       << "layout(location = 0) out vec4 out_color;\n"
+                       << "layout(set=0, binding=0) uniform Colors {\n"
+                       << "    vec4 color[" << numViewports << "];\n"
+                       << "};\n"
+                       << "\n"
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    out_color = color[gl_ViewportIndex];\n"
+                       << "}\n";
+
+               programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+       }
+}
+
 void initTessellationTestPrograms (SourceCollections& programCollection, const int numViewports)
 {
        DE_UNREF(numViewports);
@@ -586,6 +632,7 @@ public:
        enum Shader {
                VERTEX,
                TESSELLATION,
+               FRAGMENT,
        };
 
        Renderer (Context&                                              context,
@@ -601,7 +648,9 @@ public:
                , m_colorSubresourceRange       (makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u))
                , m_clearColor                          (clearColor)
                , m_numViewports                        (numViewports)
+               , m_colors                                      (colors)
                , m_vertices                            (generateVertices(colors))
+               , m_shader                                      (shader)
        {
                const DeviceInterface&          vk                                      = context.getDeviceInterface();
                const VkDevice                          device                          = context.getDevice();
@@ -631,7 +680,15 @@ public:
                m_renderPass            = makeRenderPass                (vk, device, m_colorFormat);
                m_framebuffer           = makeFramebuffer               (vk, device, *m_renderPass, m_colorAttachment.get(),
                                                                                                         static_cast<deUint32>(m_renderSize.x()),  static_cast<deUint32>(m_renderSize.y()));
-               m_pipelineLayout        = makePipelineLayout    (vk, device);
+
+               if (shader == FRAGMENT)
+               {
+                       vk::DescriptorSetLayoutBuilder builder;
+                       builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
+                       m_descriptorSetLayout = builder.build(vk, device);
+               }
+
+               m_pipelineLayout        = makePipelineLayout    (vk, device, (shader == FRAGMENT ? m_descriptorSetLayout.get() : DE_NULL));
                m_pipeline                      = makeGraphicsPipeline  (vk, device, *m_pipelineLayout, *m_renderPass, *m_vertexModule, *m_tessellationControlModule,
                                                                                                         *m_tessellationEvaluationModule, *m_fragmentModule, m_renderSize, m_numViewports, cells);
                m_cmdPool                       = createCommandPool             (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
@@ -643,6 +700,7 @@ public:
                const DeviceInterface&          vk                      = context.getDeviceInterface();
                const VkDevice                          device          = context.getDevice();
                const VkQueue                           queue           = context.getUniversalQueue();
+               Allocator&                                      allocator       = context.getDefaultAllocator();
 
                beginCommandBuffer(vk, *m_cmdBuffer);
 
@@ -654,6 +712,41 @@ public:
                        const VkDeviceSize vertexBufferOffset = 0ull;
                        vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &vertexBuffer, &vertexBufferOffset);
                }
+
+               // Prepare colors buffer if needed.
+               std::unique_ptr<vk::BufferWithMemory>   colorsBuffer;
+               vk::Move<vk::VkDescriptorPool>                  descriptorPool;
+               vk::Move<vk::VkDescriptorSet>                   descriptorSet;
+
+               if (m_shader == FRAGMENT)
+               {
+                       // Create buffer.
+                       const auto      colorsBufferSize                = m_colors.size() * sizeof(decltype(m_colors)::value_type);
+                       const auto      colorsBufferCreateInfo  = vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(colorsBufferSize), vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+                       colorsBuffer.reset(new vk::BufferWithMemory{vk, device, allocator, colorsBufferCreateInfo, MemoryRequirement::HostVisible});
+
+                       // Copy colors and flush allocation.
+                       auto& colorsBufferAlloc = colorsBuffer->getAllocation();
+                       deMemcpy(colorsBufferAlloc.getHostPtr(), m_colors.data(), colorsBufferSize);
+                       vk::flushAlloc(vk, device, colorsBufferAlloc);
+
+                       // Descriptor pool.
+                       vk::DescriptorPoolBuilder poolBuilder;
+                       poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u);
+                       descriptorPool = poolBuilder.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+                       // Descriptor set.
+                       descriptorSet = vk::makeDescriptorSet(vk, device, descriptorPool.get(), m_descriptorSetLayout.get());
+
+                       // Update and bind descriptor set.
+                       const auto                                              colorsBufferDescriptorInfo = vk::makeDescriptorBufferInfo(colorsBuffer->get(), 0ull, VK_WHOLE_SIZE);
+                       vk::DescriptorSetUpdateBuilder  updateBuilder;
+                       updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &colorsBufferDescriptorInfo);
+                       updateBuilder.update(vk, device);
+
+                       vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
+               }
+
                vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_numViewports * 6), 1u, 0u, 0u);        // two triangles per viewport
                endRenderPass(vk, *m_cmdBuffer);
 
@@ -669,7 +762,9 @@ private:
        const VkImageSubresourceRange                   m_colorSubresourceRange;
        const Vec4                                                              m_clearColor;
        const int                                                               m_numViewports;
+       const std::vector<Vec4>                                 m_colors;
        const std::vector<PositionColorVertex>  m_vertices;
+       const Shader                                                    m_shader;
 
        Move<VkImage>                                                   m_colorImage;
        MovePtr<Allocation>                                             m_colorImageAlloc;
@@ -681,6 +776,7 @@ private:
        Move<VkShaderModule>                                    m_fragmentModule;
        Move<VkRenderPass>                                              m_renderPass;
        Move<VkFramebuffer>                                             m_framebuffer;
+       Move<VkDescriptorSetLayout>                             m_descriptorSetLayout;
        Move<VkPipelineLayout>                                  m_pipelineLayout;
        Move<VkPipeline>                                                m_pipeline;
        Move<VkCommandPool>                                             m_cmdPool;
@@ -691,7 +787,7 @@ private:
        Renderer&       operator=       (const Renderer&);
 };
 
-tcu::TestStatus testVertexShader (Context& context, const int numViewports)
+tcu::TestStatus testVertexFragmentShader (Context& context, const int numViewports, Renderer::Shader shader)
 {
        const DeviceInterface&                  vk                                      = context.getDeviceInterface();
        const VkDevice                                  device                          = context.getDevice();
@@ -722,7 +818,7 @@ tcu::TestStatus testVertexShader (Context& context, const int numViewports)
 
        // Draw
        {
-               const Renderer renderer (context, renderSize, numViewports, cells, colorFormat, clearColor, colors, Renderer::VERTEX);
+               const Renderer renderer (context, renderSize, numViewports, cells, colorFormat, clearColor, colors, shader);
                renderer.draw(context, colorBuffer->object());
        }
 
@@ -742,6 +838,16 @@ tcu::TestStatus testVertexShader (Context& context, const int numViewports)
        return tcu::TestStatus::pass("OK");
 }
 
+tcu::TestStatus testVertexShader (Context& context, const int numViewports)
+{
+       return testVertexFragmentShader(context, numViewports, Renderer::VERTEX);
+}
+
+tcu::TestStatus testFragmentShader (Context& context, const int numViewports)
+{
+       return testVertexFragmentShader(context, numViewports, Renderer::FRAGMENT);
+}
+
 tcu::TestStatus testTessellationShader (Context& context, const int numViewports)
 {
        const DeviceInterface&                  vk                                      = context.getDeviceInterface();
@@ -802,6 +908,11 @@ void checkSupportVertex (Context& context, const int)
                TCU_FAIL("multiViewport supported but maxViewports is less than the minimum required");
 }
 
+void checkSupportFragment (Context& context, const int)
+{
+       checkSupportVertex(context, 0);
+}
+
 void checkSupportTessellation (Context& context, const int)
 {
        context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
@@ -819,6 +930,9 @@ tcu::TestCaseGroup* createShaderViewportIndexTests  (tcu::TestContext& testCtx)
                addFunctionCaseWithPrograms(group.get(), "vertex_shader_" + de::toString(numViewports), "", checkSupportVertex, initVertexTestPrograms, testVertexShader, numViewports);
 
        for (int numViewports = 1; numViewports <= MIN_MAX_VIEWPORTS; ++numViewports)
+               addFunctionCaseWithPrograms(group.get(), "fragment_shader_" + de::toString(numViewports), "", checkSupportFragment, initFragmentTestPrograms, testFragmentShader, numViewports);
+
+       for (int numViewports = 1; numViewports <= MIN_MAX_VIEWPORTS; ++numViewports)
                addFunctionCaseWithPrograms(group.get(), "tessellation_shader_" + de::toString(numViewports), "", checkSupportTessellation, initTessellationTestPrograms, testTessellationShader, numViewports);
 
        return group.release();
index 262d1dd..ef01940 100644 (file)
@@ -416281,6 +416281,22 @@ dEQP-VK.draw.shader_viewport_index.vertex_shader_13
 dEQP-VK.draw.shader_viewport_index.vertex_shader_14
 dEQP-VK.draw.shader_viewport_index.vertex_shader_15
 dEQP-VK.draw.shader_viewport_index.vertex_shader_16
+dEQP-VK.draw.shader_viewport_index.fragment_shader_1
+dEQP-VK.draw.shader_viewport_index.fragment_shader_2
+dEQP-VK.draw.shader_viewport_index.fragment_shader_3
+dEQP-VK.draw.shader_viewport_index.fragment_shader_4
+dEQP-VK.draw.shader_viewport_index.fragment_shader_5
+dEQP-VK.draw.shader_viewport_index.fragment_shader_6
+dEQP-VK.draw.shader_viewport_index.fragment_shader_7
+dEQP-VK.draw.shader_viewport_index.fragment_shader_8
+dEQP-VK.draw.shader_viewport_index.fragment_shader_9
+dEQP-VK.draw.shader_viewport_index.fragment_shader_10
+dEQP-VK.draw.shader_viewport_index.fragment_shader_11
+dEQP-VK.draw.shader_viewport_index.fragment_shader_12
+dEQP-VK.draw.shader_viewport_index.fragment_shader_13
+dEQP-VK.draw.shader_viewport_index.fragment_shader_14
+dEQP-VK.draw.shader_viewport_index.fragment_shader_15
+dEQP-VK.draw.shader_viewport_index.fragment_shader_16
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_1
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_2
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_3
index c7c2e0c..6a07141 100644 (file)
@@ -416242,6 +416242,22 @@ dEQP-VK.draw.shader_viewport_index.vertex_shader_13
 dEQP-VK.draw.shader_viewport_index.vertex_shader_14
 dEQP-VK.draw.shader_viewport_index.vertex_shader_15
 dEQP-VK.draw.shader_viewport_index.vertex_shader_16
+dEQP-VK.draw.shader_viewport_index.fragment_shader_1
+dEQP-VK.draw.shader_viewport_index.fragment_shader_2
+dEQP-VK.draw.shader_viewport_index.fragment_shader_3
+dEQP-VK.draw.shader_viewport_index.fragment_shader_4
+dEQP-VK.draw.shader_viewport_index.fragment_shader_5
+dEQP-VK.draw.shader_viewport_index.fragment_shader_6
+dEQP-VK.draw.shader_viewport_index.fragment_shader_7
+dEQP-VK.draw.shader_viewport_index.fragment_shader_8
+dEQP-VK.draw.shader_viewport_index.fragment_shader_9
+dEQP-VK.draw.shader_viewport_index.fragment_shader_10
+dEQP-VK.draw.shader_viewport_index.fragment_shader_11
+dEQP-VK.draw.shader_viewport_index.fragment_shader_12
+dEQP-VK.draw.shader_viewport_index.fragment_shader_13
+dEQP-VK.draw.shader_viewport_index.fragment_shader_14
+dEQP-VK.draw.shader_viewport_index.fragment_shader_15
+dEQP-VK.draw.shader_viewport_index.fragment_shader_16
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_1
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_2
 dEQP-VK.draw.shader_viewport_index.tessellation_shader_3