1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief SPIR-V Assembly Tests for varying names.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsmVaryingNameTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28 
29 namespace vkt
30 {
31 namespace SpirVAssembly
32 {
33 
34 using namespace vk;
35 using std::map;
36 using std::string;
37 using std::vector;
38 using tcu::RGBA;
39 
40 namespace
41 {
42 
43 struct TestParams
44 {
45     string name;
46     FunctionPrograms1<InstanceContext>::Function createShaders;
47 };
48 
createShaders(SourceCollections & dst,InstanceContext & context,string dataNameVertShader,string dataNameFragShader)49 void createShaders(SourceCollections &dst, InstanceContext &context, string dataNameVertShader,
50                    string dataNameFragShader)
51 {
52     SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
53     const uint32_t vulkanVersion    = dst.usedVulkanVersion;
54     const string opNameVert         = dataNameVertShader.empty() ? "" :
55                                                                    string("                             OpName %dataOut \"") +
56                                                                dataNameVertShader + "\"\n";
57     const string opNameFrag         = dataNameFragShader.empty() ?
58                                           "" :
59                                           string("                        OpName %dataIn \"") + dataNameFragShader + "\"\n";
60 
61     // A float data of 1.0 is passed from vertex shader to fragment shader. This test checks the
62     // mapping between shaders is based on location index and not using the name of the varying.
63     // Variations of this test include same OpName in both shader, different OpNames and no
64     // OpNames at all.
65     const string vertexShader =
66         string(
67             "                             OpCapability Shader\n"
68             "                        %1 = OpExtInstImport \"GLSL.std.450\"\n"
69             "                             OpMemoryModel Logical GLSL450\n"
70             "                             OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %dataOut\n"
71             "                             OpSource GLSL 450\n"
72             "                             OpName %main \"main\"\n"
73             "                             OpName %gl_PerVertex \"gl_PerVertex\"\n"
74             "                             OpMemberName %gl_PerVertex 0 \"gl_Position\"\n"
75             "                             OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n"
76             "                             OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n"
77             "                             OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n"
78             "                             OpName %_ \"\"\n"
79             "                             OpName %position \"position\"\n"
80             "                             OpName %vtxColor \"vtxColor\"\n"
81             "                             OpName %color \"color\"\n") +
82         opNameVert +
83         "                             OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
84         "                             OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
85         "                             OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
86         "                             OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n"
87         "                             OpDecorate %gl_PerVertex Block\n"
88         "                             OpDecorate %position Location 0\n"
89         "                             OpDecorate %vtxColor Location 1\n"
90         "                             OpDecorate %color Location 1\n"
91         "                             OpDecorate %dataOut Location 0\n"
92         "                     %void = OpTypeVoid\n"
93         "                        %3 = OpTypeFunction %void\n"
94         "                    %float = OpTypeFloat 32\n"
95         "                  %v4float = OpTypeVector %float 4\n"
96         "                     %uint = OpTypeInt 32 0\n"
97         "                   %uint_1 = OpConstant %uint 1\n"
98         "        %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
99         "             %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n"
100         " %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
101         "                        %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
102         "                      %int = OpTypeInt 32 1\n"
103         "                    %int_0 = OpConstant %int 0\n"
104         "       %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
105         "                 %position = OpVariable %_ptr_Input_v4float Input\n"
106         "      %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
107         "                 %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
108         "                    %color = OpVariable %_ptr_Input_v4float Input\n"
109         "        %_ptr_Output_float = OpTypePointer Output %float\n"
110         "                  %dataOut = OpVariable %_ptr_Output_float Output\n"
111         "                  %float_1 = OpConstant %float 1\n"
112         "                     %main = OpFunction %void None %3\n"
113         "                        %5 = OpLabel\n"
114         "                       %18 = OpLoad %v4float %position\n"
115         "                       %20 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
116         "                             OpStore %20 %18\n"
117         "                       %23 = OpLoad %v4float %color\n"
118         "                             OpStore %vtxColor %23\n"
119         "                             OpStore %dataOut %float_1\n"
120         "                             OpReturn\n"
121         "                             OpFunctionEnd\n";
122 
123     const string fragmentShader =
124         string("                        OpCapability Shader\n"
125                "                   %1 = OpExtInstImport \"GLSL.std.450\"\n"
126                "                        OpMemoryModel Logical GLSL450\n"
127                "                        OpEntryPoint Fragment %main \"main\" %dataIn %fragColor %vtxColor\n"
128                "                        OpExecutionMode %main OriginUpperLeft\n"
129                "                        OpSource GLSL 450\n"
130                "                        OpName %main \"main\"\n"
131                "                        OpName %Output \"Output\"\n"
132                "                        OpMemberName %Output 0 \"dataOut\"\n"
133                "                        OpName %dataOutput \"dataOutput\"\n") +
134         opNameFrag +
135         "                        OpName %fragColor \"fragColor\"\n"
136         "                        OpName %vtxColor \"vtxColor\"\n"
137         "                        OpMemberDecorate %Output 0 Offset 0\n"
138         "                        OpDecorate %Output BufferBlock\n"
139         "                        OpDecorate %dataOutput DescriptorSet 0\n"
140         "                        OpDecorate %dataOutput Binding 0\n"
141         "                        OpDecorate %dataIn Location 0\n"
142         "                        OpDecorate %fragColor Location 0\n"
143         "                        OpDecorate %vtxColor Location 1\n"
144         "                %void = OpTypeVoid\n"
145         "                   %3 = OpTypeFunction %void\n"
146         "               %float = OpTypeFloat 32\n"
147         "              %Output = OpTypeStruct %float\n"
148         " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
149         "          %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
150         "                 %int = OpTypeInt 32 1\n"
151         "               %int_0 = OpConstant %int 0\n"
152         "    %_ptr_Input_float = OpTypePointer Input %float\n"
153         "              %dataIn = OpVariable %_ptr_Input_float Input\n"
154         "  %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
155         "             %v4float = OpTypeVector %float 4\n"
156         " %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
157         "           %fragColor = OpVariable %_ptr_Output_v4float Output\n"
158         "  %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
159         "            %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
160         "                %main = OpFunction %void None %3\n"
161         "                   %5 = OpLabel\n"
162         "                  %14 = OpLoad %float %dataIn\n"
163         "                  %16 = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0\n"
164         "                        OpStore %16 %14\n"
165         "                  %22 = OpLoad %v4float %vtxColor\n"
166         "                        OpStore %fragColor %22\n"
167         "                        OpReturn\n"
168         "                        OpFunctionEnd\n";
169 
170     dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
171     dst.spirvAsmSources.add("frag", DE_NULL)
172         << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
173 }
174 
createShadersNamesMatch(vk::SourceCollections & dst,InstanceContext context)175 void createShadersNamesMatch(vk::SourceCollections &dst, InstanceContext context)
176 {
177     createShaders(dst, context, "data", "data");
178 }
179 
createShadersNamesDiffer(vk::SourceCollections & dst,InstanceContext context)180 void createShadersNamesDiffer(vk::SourceCollections &dst, InstanceContext context)
181 {
182     createShaders(dst, context, "dataOut", "dataIn");
183 }
184 
createShadersNoNames(vk::SourceCollections & dst,InstanceContext context)185 void createShadersNoNames(vk::SourceCollections &dst, InstanceContext context)
186 {
187     createShaders(dst, context, "", "");
188 }
189 
addGraphicsVaryingNameTest(tcu::TestCaseGroup * group,const TestParams & params)190 void addGraphicsVaryingNameTest(tcu::TestCaseGroup *group, const TestParams &params)
191 {
192     map<string, string> fragments;
193     RGBA defaultColors[4];
194     SpecConstants noSpecConstants;
195     PushConstants noPushConstants;
196     GraphicsInterfaces noInterfaces;
197     vector<string> extensions;
198     VulkanFeatures features;
199     map<string, string> noFragments;
200     StageToSpecConstantMap specConstantMap;
201     GraphicsResources resources;
202     const vector<float> expectedOutput(1, 1.0f);
203 
204     const ShaderElement pipelineStages[] = {
205         ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
206         ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
207     };
208 
209     specConstantMap[VK_SHADER_STAGE_VERTEX_BIT]   = noSpecConstants;
210     specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = noSpecConstants;
211 
212     getDefaultColors(defaultColors);
213 
214     features.coreFeatures.fragmentStoresAndAtomics = VK_TRUE;
215     extensions.push_back("VK_KHR_storage_buffer_storage_class");
216 
217     resources.outputs.push_back(
218         Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
219 
220     {
221         const InstanceContext &instanceContext = createInstanceContext(
222             pipelineStages, defaultColors, defaultColors, noFragments, specConstantMap, noPushConstants, resources,
223             noInterfaces, extensions, features, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
224             QP_TEST_RESULT_FAIL, string());
225 
226         addFunctionCaseWithPrograms<InstanceContext>(group, params.name.c_str(), params.createShaders,
227                                                      runAndVerifyDefaultPipeline, instanceContext);
228     }
229 }
230 
231 } // namespace
232 
createVaryingNameGraphicsGroup(tcu::TestContext & testCtx)233 tcu::TestCaseGroup *createVaryingNameGraphicsGroup(tcu::TestContext &testCtx)
234 {
235     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "varying_name"));
236 
237     static const TestParams params[] = {{"names_match", createShadersNamesMatch},
238                                         {"names_differ", createShadersNamesDiffer},
239                                         {"no_names", createShadersNoNames}};
240 
241     for (uint32_t paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
242         addGraphicsVaryingNameTest(group.get(), params[paramIdx]);
243 
244     return group.release();
245 }
246 
247 } // namespace SpirVAssembly
248 } // namespace vkt
249