Test Stream, XfbBuffer and XfbStride decorations on structs
authorRicardo Garcia <rgarcia@igalia.com>
Fri, 7 Feb 2020 12:10:31 +0000 (13:10 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 3 Apr 2020 09:02:08 +0000 (05:02 -0400)
This commit modifies the QUERY_GET transform feedback basic tests to use
an output interface block instead of a standalone output variable, so as
to test applying the Stream, XfbBuffer and XfbStride SPIR-V decorations
on struct members. Other basic transform feedback tests remain unchanged
and use the existing interfaces.

Due to glslang applying those decorations, when specified, to the output
block directly instead of struct members, the new shader is written in
manually-tuned SPIR-V assembly.

Affected tests:
dEQP-VK.transform_feedback.simple.query*

Components: Vulkan
VK-GL-CTS issue: 2211

Change-Id: I9c615c431783872f1c823c10da9a157795989e85

external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp

index 14505d4..4ab6328 100644 (file)
@@ -2411,22 +2411,113 @@ void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollecti
                        const deUint32          s       = m_parameters.streamId;
                        std::ostringstream      src;
 
-                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
-                               << "\n"
-                               << "layout(points) in;\n"
-                               << "layout(location = 0) in vec4 in0[];\n"
-                               << "\n"
-                               << "layout(points, max_vertices = 1) out;\n"
-                               << "layout(stream = " << s << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
-                               << "\n"
-                               << "void main(void)\n"
-                               << "{\n"
-                               << "    out0 = in0[0];\n"
-                               << "    EmitStreamVertex(" << s << ");\n"
-                               << "    EndStreamPrimitive(" << s << ");\n"
-                               << "}\n";
-
-                       programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
+                       if (m_parameters.testType == TEST_TYPE_QUERY_GET)
+                       {
+                               // The SPIR-V program below is roughly equivalent to the following GLSL code:
+                               //
+                               // #version 450
+                               // #extension GL_ARB_enhanced_layouts : require
+                               //
+                               // layout(points) in;
+                               // layout(location = 0) in vec4 in0[];
+                               //
+                               // layout(points, max_vertices = 1) out;
+                               // layout(location=0, stream=1, xfb_buffer=0, xfb_stride=16) out OutBlock {
+                               //     layout(xfb_offset=0, location=0) vec4 out0;
+                               // } outBlock;
+                               //
+                               // void main(void)
+                               // {
+                               //     outBlock.out0 = in0[0];
+                               //     EmitStreamVertex(1);
+                               //     EndStreamPrimitive(1);
+                               // }
+                               //
+                               // However, the stream number has been parametrized and the code generated by glslang has been tuned to move the
+                               // Stream, XfbBuffer and XfbStride decorations to the structure member instead of the block. This allows us to test
+                               // transform feedback decorations on structure members as part of these basic tests.
+                               src     << "; SPIR-V\n"
+                                       << "; Version: 1.0\n"
+                                       << "; Generator: Khronos Glslang Reference Front End; 8\n"
+                                       << "; Bound: 24\n"
+                                       << "; Schema: 0\n"
+                                       << "               OpCapability Geometry\n"
+                                       << "               OpCapability TransformFeedback\n"
+                                       << "               OpCapability GeometryStreams\n"
+                                       << "          %1 = OpExtInstImport \"GLSL.std.450\"\n"
+                                       << "               OpMemoryModel Logical GLSL450\n"
+                                       << "               OpEntryPoint Geometry %main \"main\" %outBlock %in0\n"
+                                       << "               OpExecutionMode %main Xfb\n"
+                                       << "               OpExecutionMode %main InputPoints\n"
+                                       << "               OpExecutionMode %main Invocations 1\n"
+                                       << "               OpExecutionMode %main OutputPoints\n"
+                                       << "               OpExecutionMode %main OutputVertices 1\n"
+                                       << "               OpSource GLSL 450\n"
+                                       << "               OpSourceExtension \"GL_ARB_enhanced_layouts\"\n"
+                                       << "               OpName %main \"main\"\n"
+                                       << "               OpName %OutBlock \"OutBlock\"\n"
+                                       << "               OpMemberName %OutBlock 0 \"out0\"\n"
+                                       << "               OpName %outBlock \"outBlock\"\n"
+                                       << "               OpName %in0 \"in0\"\n"
+                                       << "               OpMemberDecorate %OutBlock 0 Location 0\n"
+                                       << "               OpMemberDecorate %OutBlock 0 Offset 0\n"
+                                       // These Stream, XfbBuffer and XfbStride decorations have been moved to the struct member.
+                                       << "               OpMemberDecorate %OutBlock 0 Stream " << s << "\n"
+                                       << "               OpMemberDecorate %OutBlock 0 XfbBuffer 0\n"
+                                       << "               OpMemberDecorate %OutBlock 0 XfbStride 16\n"
+                                       << "               OpDecorate %OutBlock Block\n"
+                                       // The decorations mentioned above were using OpDecorate and assigned to %outBlock itself here.
+                                       << "               OpDecorate %in0 Location 0\n"
+                                       << "       %void = OpTypeVoid\n"
+                                       << "          %3 = OpTypeFunction %void\n"
+                                       << "      %float = OpTypeFloat 32\n"
+                                       << "    %v4float = OpTypeVector %float 4\n"
+                                       << "   %OutBlock = OpTypeStruct %v4float\n"
+                                       << "%_ptr_Output_OutBlock = OpTypePointer Output %OutBlock\n"
+                                       << "   %outBlock = OpVariable %_ptr_Output_OutBlock Output\n"
+                                       << "        %int = OpTypeInt 32 1\n"
+                                       << "      %int_0 = OpConstant %int 0\n"
+                                       << "       %uint = OpTypeInt 32 0\n"
+                                       << "     %uint_1 = OpConstant %uint 1\n"
+                                       << "%_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1\n"
+                                       << "%_ptr_Input__arr_v4float_uint_1 = OpTypePointer Input %_arr_v4float_uint_1\n"
+                                       << "        %in0 = OpVariable %_ptr_Input__arr_v4float_uint_1 Input\n"
+                                       << "%_ptr_Input_v4float = OpTypePointer Input %v4float\n"
+                                       << "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
+                                       << "  %streamNum = OpConstant %int " << s << "\n"
+                                       << "       %main = OpFunction %void None %3\n"
+                                       << "          %5 = OpLabel\n"
+                                       << "         %19 = OpAccessChain %_ptr_Input_v4float %in0 %int_0\n"
+                                       << "         %20 = OpLoad %v4float %19\n"
+                                       << "         %22 = OpAccessChain %_ptr_Output_v4float %outBlock %int_0\n"
+                                       << "               OpStore %22 %20\n"
+                                       << "               OpEmitStreamVertex %streamNum\n"
+                                       << "               OpEndStreamPrimitive %streamNum\n"
+                                       << "               OpReturn\n"
+                                       << "               OpFunctionEnd\n"
+                                       ;
+
+                               programCollection.spirvAsmSources.add("geom") << src.str();
+                       }
+                       else
+                       {
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                                       << "\n"
+                                       << "layout(points) in;\n"
+                                       << "layout(location = 0) in vec4 in0[];\n"
+                                       << "\n"
+                                       << "layout(points, max_vertices = 1) out;\n"
+                                       << "layout(stream = " << s << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "    out0 = in0[0];\n"
+                                       << "    EmitStreamVertex(" << s << ");\n"
+                                       << "    EndStreamPrimitive(" << s << ");\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
+                       }
                }
 
                return;