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, string dataNameFragShader)
50 {
51 SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
52 const deUint32 vulkanVersion = dst.usedVulkanVersion;
53 const string opNameVert = dataNameVertShader.empty() ? "" : string(" OpName %dataOut \"") + dataNameVertShader + "\"\n";
54 const string opNameFrag = dataNameFragShader.empty() ? "" : string(" OpName %dataIn \"") + dataNameFragShader + "\"\n";
55
56 // A float data of 1.0 is passed from vertex shader to fragment shader. This test checks the
57 // mapping between shaders is based on location index and not using the name of the varying.
58 // Variations of this test include same OpName in both shader, different OpNames and no
59 // OpNames at all.
60 const string vertexShader = string(
61 " OpCapability Shader\n"
62 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
63 " OpMemoryModel Logical GLSL450\n"
64 " OpEntryPoint Vertex %main \"main\" %_ %position %vtxColor %color %dataOut\n"
65 " OpSource GLSL 450\n"
66 " OpName %main \"main\"\n"
67 " OpName %gl_PerVertex \"gl_PerVertex\"\n"
68 " OpMemberName %gl_PerVertex 0 \"gl_Position\"\n"
69 " OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n"
70 " OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n"
71 " OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n"
72 " OpName %_ \"\"\n"
73 " OpName %position \"position\"\n"
74 " OpName %vtxColor \"vtxColor\"\n"
75 " OpName %color \"color\"\n")
76 + opNameVert +
77 " OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
78 " OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
79 " OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
80 " OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n"
81 " OpDecorate %gl_PerVertex Block\n"
82 " OpDecorate %position Location 0\n"
83 " OpDecorate %vtxColor Location 1\n"
84 " OpDecorate %color Location 1\n"
85 " OpDecorate %dataOut Location 0\n"
86 " %void = OpTypeVoid\n"
87 " %3 = OpTypeFunction %void\n"
88 " %float = OpTypeFloat 32\n"
89 " %v4float = OpTypeVector %float 4\n"
90 " %uint = OpTypeInt 32 0\n"
91 " %uint_1 = OpConstant %uint 1\n"
92 " %_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
93 " %gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n"
94 " %_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
95 " %_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
96 " %int = OpTypeInt 32 1\n"
97 " %int_0 = OpConstant %int 0\n"
98 " %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
99 " %position = OpVariable %_ptr_Input_v4float Input\n"
100 " %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
101 " %vtxColor = OpVariable %_ptr_Output_v4float Output\n"
102 " %color = OpVariable %_ptr_Input_v4float Input\n"
103 " %_ptr_Output_float = OpTypePointer Output %float\n"
104 " %dataOut = OpVariable %_ptr_Output_float Output\n"
105 " %float_1 = OpConstant %float 1\n"
106 " %main = OpFunction %void None %3\n"
107 " %5 = OpLabel\n"
108 " %18 = OpLoad %v4float %position\n"
109 " %20 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
110 " OpStore %20 %18\n"
111 " %23 = OpLoad %v4float %color\n"
112 " OpStore %vtxColor %23\n"
113 " OpStore %dataOut %float_1\n"
114 " OpReturn\n"
115 " OpFunctionEnd\n";
116
117 const string fragmentShader = string(
118 " OpCapability Shader\n"
119 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
120 " OpMemoryModel Logical GLSL450\n"
121 " OpEntryPoint Fragment %main \"main\" %dataIn %fragColor %vtxColor\n"
122 " OpExecutionMode %main OriginUpperLeft\n"
123 " OpSource GLSL 450\n"
124 " OpName %main \"main\"\n"
125 " OpName %Output \"Output\"\n"
126 " OpMemberName %Output 0 \"dataOut\"\n"
127 " OpName %dataOutput \"dataOutput\"\n")
128 + opNameFrag +
129 " OpName %fragColor \"fragColor\"\n"
130 " OpName %vtxColor \"vtxColor\"\n"
131 " OpMemberDecorate %Output 0 Offset 0\n"
132 " OpDecorate %Output BufferBlock\n"
133 " OpDecorate %dataOutput DescriptorSet 0\n"
134 " OpDecorate %dataOutput Binding 0\n"
135 " OpDecorate %dataIn Location 0\n"
136 " OpDecorate %fragColor Location 0\n"
137 " OpDecorate %vtxColor Location 1\n"
138 " %void = OpTypeVoid\n"
139 " %3 = OpTypeFunction %void\n"
140 " %float = OpTypeFloat 32\n"
141 " %Output = OpTypeStruct %float\n"
142 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
143 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
144 " %int = OpTypeInt 32 1\n"
145 " %int_0 = OpConstant %int 0\n"
146 " %_ptr_Input_float = OpTypePointer Input %float\n"
147 " %dataIn = OpVariable %_ptr_Input_float Input\n"
148 " %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
149 " %v4float = OpTypeVector %float 4\n"
150 " %_ptr_Output_v4float = OpTypePointer Output %v4float\n"
151 " %fragColor = OpVariable %_ptr_Output_v4float Output\n"
152 " %_ptr_Input_v4float = OpTypePointer Input %v4float\n"
153 " %vtxColor = OpVariable %_ptr_Input_v4float Input\n"
154 " %main = OpFunction %void None %3\n"
155 " %5 = OpLabel\n"
156 " %14 = OpLoad %float %dataIn\n"
157 " %16 = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0\n"
158 " OpStore %16 %14\n"
159 " %22 = OpLoad %v4float %vtxColor\n"
160 " OpStore %fragColor %22\n"
161 " OpReturn\n"
162 " OpFunctionEnd\n";
163
164 dst.spirvAsmSources.add("vert", DE_NULL) << vertexShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
165 dst.spirvAsmSources.add("frag", DE_NULL) << fragmentShader << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
166 }
167
createShadersNamesMatch(vk::SourceCollections & dst,InstanceContext context)168 void createShadersNamesMatch (vk::SourceCollections& dst, InstanceContext context)
169 {
170 createShaders(dst, context, "data", "data");
171 }
172
createShadersNamesDiffer(vk::SourceCollections & dst,InstanceContext context)173 void createShadersNamesDiffer (vk::SourceCollections& dst, InstanceContext context)
174 {
175 createShaders(dst, context, "dataOut", "dataIn");
176 }
177
createShadersNoNames(vk::SourceCollections & dst,InstanceContext context)178 void createShadersNoNames (vk::SourceCollections& dst, InstanceContext context)
179 {
180 createShaders(dst, context, "", "");
181 }
182
addGraphicsVaryingNameTest(tcu::TestCaseGroup * group,const TestParams & params)183 void addGraphicsVaryingNameTest (tcu::TestCaseGroup* group, const TestParams& params)
184 {
185 map<string, string> fragments;
186 RGBA defaultColors[4];
187 SpecConstants noSpecConstants;
188 PushConstants noPushConstants;
189 GraphicsInterfaces noInterfaces;
190 vector<string> extensions;
191 VulkanFeatures features;
192 map<string, string> noFragments;
193 StageToSpecConstantMap specConstantMap;
194 GraphicsResources resources;
195 const vector<float> expectedOutput(1, 1.0f);
196
197 const ShaderElement pipelineStages[] =
198 {
199 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
200 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
201 };
202
203 specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = noSpecConstants;
204 specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = noSpecConstants;
205
206 getDefaultColors(defaultColors);
207
208 features.coreFeatures.fragmentStoresAndAtomics = VK_TRUE;
209 extensions.push_back("VK_KHR_storage_buffer_storage_class");
210
211 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
212
213 {
214 const InstanceContext& instanceContext = createInstanceContext(pipelineStages,
215 defaultColors,
216 defaultColors,
217 noFragments,
218 specConstantMap,
219 noPushConstants,
220 resources,
221 noInterfaces,
222 extensions,
223 features,
224 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
225 QP_TEST_RESULT_FAIL,
226 string());
227
228 addFunctionCaseWithPrograms<InstanceContext>(group,
229 params.name.c_str(),
230 "",
231 params.createShaders,
232 runAndVerifyDefaultPipeline,
233 instanceContext);
234 }
235 }
236
237 } // anonymous
238
createVaryingNameGraphicsGroup(tcu::TestContext & testCtx)239 tcu::TestCaseGroup* createVaryingNameGraphicsGroup (tcu::TestContext& testCtx)
240 {
241 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "varying_name", "Graphics tests for varying names."));
242
243 static const TestParams params[] =
244 {
245 { "names_match", createShadersNamesMatch },
246 { "names_differ", createShadersNamesDiffer },
247 { "no_names", createShadersNoNames }
248 };
249
250 for (deUint32 paramIdx = 0; paramIdx < DE_LENGTH_OF_ARRAY(params); paramIdx++)
251 addGraphicsVaryingNameTest(group.get(), params[paramIdx]);
252
253 return group.release();
254 }
255
256 } // SpirVAssembly
257 } // vkt
258