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 ¶ms)
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