Allow geometry shader to reorder vertices in dEQP-VK.ray_query.ray_flags.geometry_sha...
authorSlawomir Cygan <slawomir.cygan@intel.com>
Wed, 23 Dec 2020 16:31:06 +0000 (17:31 +0100)
committerSlawomir Cygan <slawomir.cygan@intel.com>
Wed, 23 Dec 2020 16:32:42 +0000 (17:32 +0100)
This fixes the geometry shader used in the test to allow gl_in[] to start from
arbitrary vertex from the triangle primitive.

According to spec:

"""
24.1. Geometry Shader Input Primitives
...
Vertices may be in a different absolute order to that specified by the topology,
but must adhere to the specified winding order.
"""

The test does some ray query computation in geometry shader, using elements
of gl_in[] as inputs, and storing the outputs in consecutive pixels of storage image.
The test than verifies the image contents using some predefined vertex order.
As gl_in is not queranteed to follow this order, vertex index from vertex shader is now
used to calculate starting index, from which gl_in is iterated.

Components: Vulkan

VK-GL-CTS Issue: 2707

Affects: dEQP-VK.ray_query.ray_flags.geometry_shader.*

Change-Id: I81029d88f5b1f3462a8c5058298ee8a850020d06

external/vulkancts/modules/vulkan/ray_query/vktRayQueryCullRayFlagsTests.cpp

index e90195a..15a6841 100644 (file)
@@ -377,7 +377,7 @@ void GraphicsConfiguration::initConfiguration (Context&                                             context,
                {       SST_VERTEX_SHADER,                                      {       "vert_%s",              "",                             "",                             "",                             "",                     }       },
                {       SST_TESSELATION_CONTROL_SHADER,         {       "vert",                 "tesc_%s",              "tese",                 "",                             "",                     }       },
                {       SST_TESSELATION_EVALUATION_SHADER,      {       "vert",                 "tesc",                 "tese_%s",              "",                             "",                     }       },
-               {       SST_GEOMETRY_SHADER,                            {       "vert",                 "",                             "",                             "geom_%s",              "",                     }       },
+               {       SST_GEOMETRY_SHADER,                            {       "vert_vid",             "",                             "",                             "geom_%s",              "",                     }       },
                {       SST_FRAGMENT_SHADER,                            {       "vert",                 "",                             "",                             "",                             "frag_%s",      }       },
        };
 
@@ -1335,6 +1335,24 @@ void RayQueryCullRayFlagsTestCase::initPrograms (SourceCollections& programColle
                        std::stringstream css;
                        css <<
                                "#version 460 core\n"
+                               "layout (location = 0) in vec3 position;\n"
+                               "out gl_PerVertex\n"
+                               "{\n"
+                               "  vec4 gl_Position;\n"
+                               "};\n"
+                               "layout(location = 0) out int vertexIndex;\n"
+                               "void main()\n"
+                               "{\n"
+                               "  gl_Position = vec4(position, 1.0);\n"
+                               "  vertexIndex = gl_VertexIndex;\n"
+                               "}\n";
+                       programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str());
+               }
+
+               {
+                       std::stringstream css;
+                       css <<
+                               "#version 460 core\n"
                                "#extension GL_EXT_ray_query : require\n"
                                "layout (location = 0) in vec3 position;\n"
                                "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
@@ -1466,19 +1484,36 @@ void RayQueryCullRayFlagsTestCase::initPrograms (SourceCollections& programColle
                                "in gl_PerVertex {\n"
                                "  vec4  gl_Position;\n"
                                "} gl_in[];\n"
+                               "layout(location = 0) in int vertexIndex[];\n"
                                "out gl_PerVertex {\n"
                                "  vec4 gl_Position;\n"
                                "};\n"
                                "void main (void)\n"
                                "{\n"
+                               "  // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
+                               "  // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
+                               "  // smallest vertex index value.\n"
+                               "  int minVertexIndex = 10000;"
+                               "  int firstVertex;"
                                "  for (int i = 0; i < gl_in.length(); ++i)\n"
                                "  {\n"
+                               "    if (minVertexIndex > vertexIndex[i])\n"
+                               "    {\n"
+                               "      minVertexIndex = vertexIndex[i];\n"
+                               "      firstVertex    = i;\n"
+                               "    }\n"
+                               "  }\n"
+                               "  for (int j = 0; j < gl_in.length(); ++j)\n"
+                               "  {\n"
+                               "    // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
+                               "    // always iterated starting from the smallest vertex index, as found above.\n"
+                               "    int i = (firstVertex + j) % gl_in.length();\n"
                                "    vec3  origin   = vec3(gl_in[i].gl_Position.x, gl_in[i].gl_Position.y, 0.5f);\n"
                                "    uvec4 hitValue = uvec4(0,0,0,0);\n"
                                "    uint  rqFlags  = rayFlags.x;\n" <<
                                rayQueryTest[m_data.bottomType] <<
-                               "    imageStore(result, ivec3(gl_PrimitiveIDIn, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
-                               "    imageStore(result, ivec3(gl_PrimitiveIDIn, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
+                               "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
+                               "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
                                "    gl_Position      = gl_in[i].gl_Position;\n"
                                "    EmitVertex();\n"
                                "  }\n"