blob: df0d8e270fc8468e77040995067a72ae1c5388ab [file] [log] [blame]
Karl Schultz6addd812016-02-02 17:17:23 -07001/*
Karl Schultz7b024b42018-08-30 16:18:18 -06002 * Copyright (c) 2015-2019 The Khronos Group Inc.
3 * Copyright (c) 2015-2019 Valve Corporation
4 * Copyright (c) 2015-2019 LunarG, Inc.
Karl Schultz6addd812016-02-02 17:17:23 -07005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Karl Schultz6addd812016-02-02 17:17:23 -07009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Karl Schultz6addd812016-02-02 17:17:23 -070011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Karl Schultz6addd812016-02-02 17:17:23 -070017 *
18 * Author: Chia-I Wu <olvaffe@gmail.com>
19 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
20 * Author: Tony Barbour <tony@LunarG.com>
21 */
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060022
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060023#include "vktestframework.h"
24#include "vkrenderframework.h"
Karl Schultz80b8aca2017-01-24 14:44:26 -080025
26// For versions prior to VS 2015, suppress the warning
27// caused by the inconsistent redefinition of snprintf
28// between a vulkan header and a glslang header.
29#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
30#pragma warning(push)
31#pragma warning(disable : 4005)
32#endif
Karl Schultz6addd812016-02-02 17:17:23 -070033// TODO FIXME remove this once glslang doesn't define this
Jon Ashburn94207e92015-12-04 17:03:59 -070034#undef BadValue
Cody Northrop5a95b472015-06-03 13:01:54 -060035#include "SPIRV/GlslangToSpv.h"
36#include "SPIRV/SPVRemapper.h"
Karl Schultz80b8aca2017-01-24 14:44:26 -080037#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
38#pragma warning(pop)
39#endif
Tony Barbour4ab45422014-12-10 17:00:20 -070040#include <limits.h>
orbea80ddc062019-09-10 10:33:19 -070041#include <cmath>
Jon Ashburn94207e92015-12-04 17:03:59 -070042
Tony Barbour3d69c9e2015-05-20 16:53:31 -060043#if defined(PATH_MAX) && !defined(MAX_PATH)
44#define MAX_PATH PATH_MAX
45#endif
46
Tony Barbour6a3faf02015-07-23 10:36:18 -060047#ifdef _WIN32
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070048#define ERR_EXIT(err_msg, err_class) \
49 do { \
50 MessageBox(NULL, err_msg, err_class, MB_OK); \
51 exit(1); \
Karl Schultz6addd812016-02-02 17:17:23 -070052 } while (0)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070053#else // _WIN32
Tony Barbour6a3faf02015-07-23 10:36:18 -060054
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070055#define ERR_EXIT(err_msg, err_class) \
56 do { \
57 printf(err_msg); \
58 fflush(stdout); \
59 exit(1); \
Karl Schultz6addd812016-02-02 17:17:23 -070060 } while (0)
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070061#endif // _WIN32
Tony Barbour6a3faf02015-07-23 10:36:18 -060062
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060063// Command-line options
64enum TOptions {
Karl Schultz6addd812016-02-02 17:17:23 -070065 EOptionNone = 0x000,
66 EOptionIntermediate = 0x001,
67 EOptionSuppressInfolog = 0x002,
68 EOptionMemoryLeakMode = 0x004,
69 EOptionRelaxedErrors = 0x008,
70 EOptionGiveWarnings = 0x010,
71 EOptionLinkProgram = 0x020,
72 EOptionMultiThreaded = 0x040,
73 EOptionDumpConfig = 0x080,
74 EOptionDumpReflection = 0x100,
75 EOptionSuppressWarnings = 0x200,
76 EOptionDumpVersions = 0x400,
77 EOptionSpv = 0x800,
78 EOptionDefaultDesktop = 0x1000,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060079};
80
Mark Lobodzinskib5ccf3f2016-05-19 17:26:51 -060081struct SwapchainBuffers {
Tony Barbour6a3faf02015-07-23 10:36:18 -060082 VkImage image;
Chia-I Wu3432a0c2015-10-27 18:04:07 +080083 VkCommandBuffer cmd;
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -060084 VkImageView view;
Mark Lobodzinskib5ccf3f2016-05-19 17:26:51 -060085};
Tony Barbour6a3faf02015-07-23 10:36:18 -060086
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060087#ifndef _WIN32
88
89#include <errno.h>
90
Karl Schultz6addd812016-02-02 17:17:23 -070091int fopen_s(FILE **pFile, const char *filename, const char *mode) {
92 if (!pFile || !filename || !mode) {
93 return EINVAL;
94 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060095
Karl Schultz6addd812016-02-02 17:17:23 -070096 FILE *f = fopen(filename, mode);
97 if (!f) {
98 if (errno != 0) {
99 return errno;
100 } else {
101 return ENOENT;
102 }
103 }
104 *pFile = f;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600105
Karl Schultz6addd812016-02-02 17:17:23 -0700106 return 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600107}
108
109#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600110
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600111// Set up environment for GLSL compiler
112// Must be done once per process
Karl Schultz6addd812016-02-02 17:17:23 -0700113void TestEnvironment::SetUp() {
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600114 // Initialize GLSL to SPV compiler utility
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600115 glslang::InitializeProcess();
Chia-I Wub76e0fa2014-12-28 14:27:28 +0800116
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600117 vk_testing::set_error_callback(test_error_callback);
Mark Lobodzinski91ee16c2019-09-27 11:44:52 -0600118
119 vk::InitDispatchTable();
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600120}
121
Karl Schultz6addd812016-02-02 17:17:23 -0700122void TestEnvironment::TearDown() { glslang::FinalizeProcess(); }
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600123
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600124VkTestFramework::VkTestFramework() : m_compile_options(0), m_num_shader_strings(0) {}
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600125
Karl Schultz6addd812016-02-02 17:17:23 -0700126VkTestFramework::~VkTestFramework() {}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600127
128// Define all the static elements
Karl Schultz6addd812016-02-02 17:17:23 -0700129bool VkTestFramework::m_canonicalize_spv = false;
130bool VkTestFramework::m_strip_spv = false;
Cody Northrop5a95b472015-06-03 13:01:54 -0600131bool VkTestFramework::m_do_everything_spv = false;
Tobin Ehlis72888642017-11-15 09:43:56 -0700132bool VkTestFramework::m_devsim_layer = false;
Tony Barbour6918cd52015-04-09 12:58:51 -0600133int VkTestFramework::m_width = 0;
134int VkTestFramework::m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600135
Karl Schultz6addd812016-02-02 17:17:23 -0700136bool VkTestFramework::optionMatch(const char *option, char *optionLine) {
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600137 if (strncmp(option, optionLine, strlen(option)) == 0)
138 return true;
139 else
140 return false;
141}
142
Karl Schultz6addd812016-02-02 17:17:23 -0700143void VkTestFramework::InitArgs(int *argc, char *argv[]) {
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600144 int i, n;
145
Karl Schultz6addd812016-02-02 17:17:23 -0700146 for (i = 1, n = 1; i < *argc; i++) {
Chris Forbesb5e22252017-04-04 15:51:36 -0700147 if (optionMatch("--strip-SPV", argv[i]))
Tony Barbour7b60e492016-02-02 14:43:55 -0700148 m_strip_spv = true;
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600149 else if (optionMatch("--canonicalize-SPV", argv[i]))
150 m_canonicalize_spv = true;
Tobin Ehlis72888642017-11-15 09:43:56 -0700151 else if (optionMatch("--devsim", argv[i]))
152 m_devsim_layer = true;
Karl Schultz6addd812016-02-02 17:17:23 -0700153 else if (optionMatch("--help", argv[i]) || optionMatch("-h", argv[i])) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700154 printf("\nOther options:\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700155 printf(
156 "\t--show-images\n"
157 "\t\tDisplay test images in viewer after tests complete.\n");
158 printf(
159 "\t--save-images\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700160 "\t\tSave tests images as ppm files in current working directory.\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700161 "\t\tUsed to generate golden images for compare-images.\n");
162 printf(
163 "\t--compare-images\n"
164 "\t\tCompare test images to 'golden' image in golden folder.\n"
165 "\t\tAlso saves the generated test image in current working\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700166 "\t\t\tdirectory but only if the image is different from the golden\n"
167 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700168 "\t\t\tdifferent directory for golden images\n"
169 "\t\tSignal test failure if different.\n");
170 printf(
171 "\t--no-SPV\n"
172 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
173 printf(
174 "\t--strip-SPV\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700175 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700176 printf(
177 "\t--canonicalize-SPV\n"
178 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600179 exit(0);
180 } else {
181 printf("\nUnrecognized option: %s\n", argv[i]);
182 printf("\nUse --help or -h for option list.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700183 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700184 }
185
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600186 /*
187 * Since the above "consume" inputs, update argv
188 * so that it contains the trimmed list of args for glutInit
189 */
190
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600191 argv[n] = argv[i];
192 n++;
193 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600194}
195
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600196VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device) {
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700197 VkFormatProperties format_props;
Tony Barbour7b60e492016-02-02 14:43:55 -0700198
Mark Lobodzinski1ad400e2019-09-27 13:53:29 -0600199 vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600200 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
201 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700202 return VK_FORMAT_B8G8R8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700203 }
Mark Lobodzinski1ad400e2019-09-27 13:53:29 -0600204 vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600205 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
206 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700207 return VK_FORMAT_R8G8B8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700208 }
Dave Houlton6c72f352018-02-06 17:49:16 -0700209 printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
Tobin Ehlise37e9732016-07-11 12:57:29 -0600210 exit(1);
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700211}
212
Karl Schultz6addd812016-02-02 17:17:23 -0700213void VkTestFramework::Finish() {}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600214
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600215//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600216// These are the default resources for TBuiltInResources, used for both
217// - parsing this string for the case where the user didn't supply one
218// - dumping out a template for user construction of a config file
219//
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700220static const char *DefaultConfig =
221 "MaxLights 32\n"
222 "MaxClipPlanes 6\n"
223 "MaxTextureUnits 32\n"
224 "MaxTextureCoords 32\n"
225 "MaxVertexAttribs 64\n"
226 "MaxVertexUniformComponents 4096\n"
227 "MaxVaryingFloats 64\n"
228 "MaxVertexTextureImageUnits 32\n"
229 "MaxCombinedTextureImageUnits 80\n"
230 "MaxTextureImageUnits 32\n"
231 "MaxFragmentUniformComponents 4096\n"
232 "MaxDrawBuffers 32\n"
233 "MaxVertexUniformVectors 128\n"
234 "MaxVaryingVectors 8\n"
235 "MaxFragmentUniformVectors 16\n"
236 "MaxVertexOutputVectors 16\n"
237 "MaxFragmentInputVectors 15\n"
238 "MinProgramTexelOffset -8\n"
239 "MaxProgramTexelOffset 7\n"
240 "MaxClipDistances 8\n"
241 "MaxComputeWorkGroupCountX 65535\n"
242 "MaxComputeWorkGroupCountY 65535\n"
243 "MaxComputeWorkGroupCountZ 65535\n"
244 "MaxComputeWorkGroupSizeX 1024\n"
245 "MaxComputeWorkGroupSizeY 1024\n"
246 "MaxComputeWorkGroupSizeZ 64\n"
247 "MaxComputeUniformComponents 1024\n"
248 "MaxComputeTextureImageUnits 16\n"
249 "MaxComputeImageUniforms 8\n"
250 "MaxComputeAtomicCounters 8\n"
251 "MaxComputeAtomicCounterBuffers 1\n"
252 "MaxVaryingComponents 60\n"
253 "MaxVertexOutputComponents 64\n"
254 "MaxGeometryInputComponents 64\n"
255 "MaxGeometryOutputComponents 128\n"
256 "MaxFragmentInputComponents 128\n"
257 "MaxImageUnits 8\n"
258 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
259 "MaxCombinedShaderOutputResources 8\n"
260 "MaxImageSamples 0\n"
261 "MaxVertexImageUniforms 0\n"
262 "MaxTessControlImageUniforms 0\n"
263 "MaxTessEvaluationImageUniforms 0\n"
264 "MaxGeometryImageUniforms 0\n"
265 "MaxFragmentImageUniforms 8\n"
266 "MaxCombinedImageUniforms 8\n"
267 "MaxGeometryTextureImageUnits 16\n"
268 "MaxGeometryOutputVertices 256\n"
269 "MaxGeometryTotalOutputComponents 1024\n"
270 "MaxGeometryUniformComponents 1024\n"
271 "MaxGeometryVaryingComponents 64\n"
272 "MaxTessControlInputComponents 128\n"
273 "MaxTessControlOutputComponents 128\n"
274 "MaxTessControlTextureImageUnits 16\n"
275 "MaxTessControlUniformComponents 1024\n"
276 "MaxTessControlTotalOutputComponents 4096\n"
277 "MaxTessEvaluationInputComponents 128\n"
278 "MaxTessEvaluationOutputComponents 128\n"
279 "MaxTessEvaluationTextureImageUnits 16\n"
280 "MaxTessEvaluationUniformComponents 1024\n"
281 "MaxTessPatchComponents 120\n"
282 "MaxPatchVertices 32\n"
283 "MaxTessGenLevel 64\n"
284 "MaxViewports 16\n"
285 "MaxVertexAtomicCounters 0\n"
286 "MaxTessControlAtomicCounters 0\n"
287 "MaxTessEvaluationAtomicCounters 0\n"
288 "MaxGeometryAtomicCounters 0\n"
289 "MaxFragmentAtomicCounters 8\n"
290 "MaxCombinedAtomicCounters 8\n"
291 "MaxAtomicCounterBindings 1\n"
292 "MaxVertexAtomicCounterBuffers 0\n"
293 "MaxTessControlAtomicCounterBuffers 0\n"
294 "MaxTessEvaluationAtomicCounterBuffers 0\n"
295 "MaxGeometryAtomicCounterBuffers 0\n"
296 "MaxFragmentAtomicCounterBuffers 1\n"
297 "MaxCombinedAtomicCounterBuffers 1\n"
298 "MaxAtomicCounterBufferSize 16384\n"
299 "MaxTransformFeedbackBuffers 4\n"
300 "MaxTransformFeedbackInterleavedComponents 64\n"
301 "MaxCullDistances 8\n"
302 "MaxCombinedClipAndCullDistances 8\n"
303 "MaxSamples 4\n"
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500304 "MaxMeshOutputVerticesNV 256\n"
305 "MaxMeshOutputPrimitivesNV 512\n"
306 "MaxMeshWorkGroupSizeX_NV 32\n"
307 "MaxMeshWorkGroupSizeY_NV 1\n"
308 "MaxMeshWorkGroupSizeZ_NV 1\n"
309 "MaxTaskWorkGroupSizeX_NV 32\n"
310 "MaxTaskWorkGroupSizeY_NV 1\n"
311 "MaxTaskWorkGroupSizeZ_NV 1\n"
312 "MaxMeshViewCountNV 4\n"
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600313
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700314 "nonInductiveForLoops 1\n"
315 "whileLoops 1\n"
316 "doWhileLoops 1\n"
317 "generalUniformIndexing 1\n"
318 "generalAttributeMatrixVectorIndexing 1\n"
319 "generalVaryingIndexing 1\n"
320 "generalSamplerIndexing 1\n"
321 "generalVariableIndexing 1\n"
322 "generalConstantMatrixVectorIndexing 1\n";
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600323
324//
325// *.conf => this is a config file that can set limits/resources
326//
Karl Schultz6addd812016-02-02 17:17:23 -0700327bool VkTestFramework::SetConfigFile(const std::string &name) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700328 if (name.size() < 5) return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600329
330 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
331 ConfigFile = name;
332 return true;
333 }
334
335 return false;
336}
337
338//
339// Parse either a .conf file provided by the user or the default string above.
340//
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600341void VkTestFramework::ProcessConfigFile(VkPhysicalDeviceLimits const *const device_limits) {
Karl Schultz6addd812016-02-02 17:17:23 -0700342 char **configStrings = 0;
343 char *config = 0;
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600344 bool config_file_specified = false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600345 if (ConfigFile.size() > 0) {
346 configStrings = ReadFileData(ConfigFile.c_str());
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600347 if (configStrings) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600348 config = *configStrings;
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600349 config_file_specified = true;
350 } else {
Dave Houlton6c72f352018-02-06 17:49:16 -0700351 printf("Error opening configuration file; will instead use the default configuration\n");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600352 }
353 }
354
355 if (config == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700356 config = (char *)alloca(strlen(DefaultConfig) + 1);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600357 strcpy(config, DefaultConfig);
358 }
359
Karl Schultz6addd812016-02-02 17:17:23 -0700360 const char *delims = " \t\n\r";
361 const char *token = strtok(config, delims);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600362 while (token) {
Karl Schultz6addd812016-02-02 17:17:23 -0700363 const char *valueStr = strtok(0, delims);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600364 if (valueStr == 0 || !(valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
Dave Houlton6c72f352018-02-06 17:49:16 -0700365 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600366 return;
367 }
368 int value = atoi(valueStr);
369
370 if (strcmp(token, "MaxLights") == 0)
371 Resources.maxLights = value;
372 else if (strcmp(token, "MaxClipPlanes") == 0)
373 Resources.maxClipPlanes = value;
374 else if (strcmp(token, "MaxTextureUnits") == 0)
375 Resources.maxTextureUnits = value;
376 else if (strcmp(token, "MaxTextureCoords") == 0)
377 Resources.maxTextureCoords = value;
378 else if (strcmp(token, "MaxVertexAttribs") == 0)
379 Resources.maxVertexAttribs = value;
380 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
381 Resources.maxVertexUniformComponents = value;
382 else if (strcmp(token, "MaxVaryingFloats") == 0)
383 Resources.maxVaryingFloats = value;
384 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
385 Resources.maxVertexTextureImageUnits = value;
386 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
387 Resources.maxCombinedTextureImageUnits = value;
388 else if (strcmp(token, "MaxTextureImageUnits") == 0)
389 Resources.maxTextureImageUnits = value;
390 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
391 Resources.maxFragmentUniformComponents = value;
392 else if (strcmp(token, "MaxDrawBuffers") == 0)
393 Resources.maxDrawBuffers = value;
394 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
395 Resources.maxVertexUniformVectors = value;
396 else if (strcmp(token, "MaxVaryingVectors") == 0)
397 Resources.maxVaryingVectors = value;
398 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
399 Resources.maxFragmentUniformVectors = value;
400 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
401 Resources.maxVertexOutputVectors = value;
402 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
403 Resources.maxFragmentInputVectors = value;
404 else if (strcmp(token, "MinProgramTexelOffset") == 0)
405 Resources.minProgramTexelOffset = value;
406 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
407 Resources.maxProgramTexelOffset = value;
408 else if (strcmp(token, "MaxClipDistances") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600409 Resources.maxClipDistances = (config_file_specified ? value : device_limits->maxClipDistances);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600410 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600411 Resources.maxComputeWorkGroupCountX = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[0]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600412 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600413 Resources.maxComputeWorkGroupCountY = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[1]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600414 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600415 Resources.maxComputeWorkGroupCountZ = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[2]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600416 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600417 Resources.maxComputeWorkGroupSizeX = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[0]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600418 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600419 Resources.maxComputeWorkGroupSizeY = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[1]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600420 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600421 Resources.maxComputeWorkGroupSizeZ = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[2]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600422 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
423 Resources.maxComputeUniformComponents = value;
424 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
425 Resources.maxComputeTextureImageUnits = value;
426 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
427 Resources.maxComputeImageUniforms = value;
428 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
429 Resources.maxComputeAtomicCounters = value;
430 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
431 Resources.maxComputeAtomicCounterBuffers = value;
432 else if (strcmp(token, "MaxVaryingComponents") == 0)
433 Resources.maxVaryingComponents = value;
434 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600435 Resources.maxVertexOutputComponents = (config_file_specified ? value : device_limits->maxVertexOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600436 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600437 Resources.maxGeometryInputComponents = (config_file_specified ? value : device_limits->maxGeometryInputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600438 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600439 Resources.maxGeometryOutputComponents = (config_file_specified ? value : device_limits->maxGeometryOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600440 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600441 Resources.maxFragmentInputComponents = (config_file_specified ? value : device_limits->maxFragmentInputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600442 else if (strcmp(token, "MaxImageUnits") == 0)
443 Resources.maxImageUnits = value;
444 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
445 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
446 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
447 Resources.maxCombinedShaderOutputResources = value;
448 else if (strcmp(token, "MaxImageSamples") == 0)
449 Resources.maxImageSamples = value;
450 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
451 Resources.maxVertexImageUniforms = value;
452 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
453 Resources.maxTessControlImageUniforms = value;
454 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
455 Resources.maxTessEvaluationImageUniforms = value;
456 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
457 Resources.maxGeometryImageUniforms = value;
458 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
459 Resources.maxFragmentImageUniforms = value;
460 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
461 Resources.maxCombinedImageUniforms = value;
462 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
463 Resources.maxGeometryTextureImageUnits = value;
464 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600465 Resources.maxGeometryOutputVertices = (config_file_specified ? value : device_limits->maxGeometryOutputVertices);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600466 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600467 Resources.maxGeometryTotalOutputComponents =
468 (config_file_specified ? value : device_limits->maxGeometryTotalOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600469 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
470 Resources.maxGeometryUniformComponents = value;
471 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
472 Resources.maxGeometryVaryingComponents = value;
473 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
474 Resources.maxTessControlInputComponents = value;
475 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
476 Resources.maxTessControlOutputComponents = value;
477 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
478 Resources.maxTessControlTextureImageUnits = value;
479 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
480 Resources.maxTessControlUniformComponents = value;
481 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
482 Resources.maxTessControlTotalOutputComponents = value;
483 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
484 Resources.maxTessEvaluationInputComponents = value;
485 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
486 Resources.maxTessEvaluationOutputComponents = value;
487 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
488 Resources.maxTessEvaluationTextureImageUnits = value;
489 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
490 Resources.maxTessEvaluationUniformComponents = value;
491 else if (strcmp(token, "MaxTessPatchComponents") == 0)
492 Resources.maxTessPatchComponents = value;
493 else if (strcmp(token, "MaxPatchVertices") == 0)
494 Resources.maxPatchVertices = value;
495 else if (strcmp(token, "MaxTessGenLevel") == 0)
496 Resources.maxTessGenLevel = value;
497 else if (strcmp(token, "MaxViewports") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600498 Resources.maxViewports = (config_file_specified ? value : device_limits->maxViewports);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600499 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
500 Resources.maxVertexAtomicCounters = value;
501 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
502 Resources.maxTessControlAtomicCounters = value;
503 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
504 Resources.maxTessEvaluationAtomicCounters = value;
505 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
506 Resources.maxGeometryAtomicCounters = value;
507 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
508 Resources.maxFragmentAtomicCounters = value;
509 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
510 Resources.maxCombinedAtomicCounters = value;
511 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
512 Resources.maxAtomicCounterBindings = value;
513 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
514 Resources.maxVertexAtomicCounterBuffers = value;
515 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
516 Resources.maxTessControlAtomicCounterBuffers = value;
517 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
518 Resources.maxTessEvaluationAtomicCounterBuffers = value;
519 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
520 Resources.maxGeometryAtomicCounterBuffers = value;
521 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
522 Resources.maxFragmentAtomicCounterBuffers = value;
523 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
524 Resources.maxCombinedAtomicCounterBuffers = value;
525 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
526 Resources.maxAtomicCounterBufferSize = value;
527 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
528 Resources.maxTransformFeedbackBuffers = value;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600529 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600530 Resources.maxTransformFeedbackInterleavedComponents = value;
531 else if (strcmp(token, "MaxCullDistances") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600532 Resources.maxCullDistances = (config_file_specified ? value : device_limits->maxCullDistances);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600533 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
534 Resources.maxCombinedClipAndCullDistances = value;
535 else if (strcmp(token, "MaxSamples") == 0)
536 Resources.maxSamples = value;
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500537 else if (strcmp(token, "MaxMeshOutputVerticesNV") == 0)
538 Resources.maxMeshOutputVerticesNV = value;
539 else if (strcmp(token, "MaxMeshOutputPrimitivesNV") == 0)
540 Resources.maxMeshOutputPrimitivesNV = value;
541 else if (strcmp(token, "MaxMeshWorkGroupSizeX_NV") == 0)
542 Resources.maxMeshWorkGroupSizeX_NV = value;
543 else if (strcmp(token, "MaxMeshWorkGroupSizeY_NV") == 0)
544 Resources.maxMeshWorkGroupSizeY_NV = value;
545 else if (strcmp(token, "MaxMeshWorkGroupSizeZ_NV") == 0)
546 Resources.maxMeshWorkGroupSizeZ_NV = value;
547 else if (strcmp(token, "MaxTaskWorkGroupSizeX_NV") == 0)
548 Resources.maxTaskWorkGroupSizeX_NV = value;
549 else if (strcmp(token, "MaxTaskWorkGroupSizeY_NV") == 0)
550 Resources.maxTaskWorkGroupSizeY_NV = value;
551 else if (strcmp(token, "MaxTaskWorkGroupSizeZ_NV") == 0)
552 Resources.maxTaskWorkGroupSizeZ_NV = value;
553 else if (strcmp(token, "MaxMeshViewCountNV") == 0)
554 Resources.maxMeshViewCountNV = value;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600555
556 else if (strcmp(token, "nonInductiveForLoops") == 0)
557 Resources.limits.nonInductiveForLoops = (value != 0);
558 else if (strcmp(token, "whileLoops") == 0)
559 Resources.limits.whileLoops = (value != 0);
560 else if (strcmp(token, "doWhileLoops") == 0)
561 Resources.limits.doWhileLoops = (value != 0);
562 else if (strcmp(token, "generalUniformIndexing") == 0)
563 Resources.limits.generalUniformIndexing = (value != 0);
564 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600565 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600566 else if (strcmp(token, "generalVaryingIndexing") == 0)
567 Resources.limits.generalVaryingIndexing = (value != 0);
568 else if (strcmp(token, "generalSamplerIndexing") == 0)
569 Resources.limits.generalSamplerIndexing = (value != 0);
570 else if (strcmp(token, "generalVariableIndexing") == 0)
571 Resources.limits.generalVariableIndexing = (value != 0);
572 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
573 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
574 else
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600575 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600576
577 token = strtok(0, delims);
578 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700579 if (configStrings) FreeFileData(configStrings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600580}
581
Karl Schultz6addd812016-02-02 17:17:23 -0700582void VkTestFramework::SetMessageOptions(EShMessages &messages) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700583 if (m_compile_options & EOptionRelaxedErrors) messages = (EShMessages)(messages | EShMsgRelaxedErrors);
584 if (m_compile_options & EOptionIntermediate) messages = (EShMessages)(messages | EShMsgAST);
585 if (m_compile_options & EOptionSuppressWarnings) messages = (EShMessages)(messages | EShMsgSuppressWarnings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600586}
587
588//
589// Malloc a string of sufficient size and read a string into it.
590//
Karl Schultz6addd812016-02-02 17:17:23 -0700591char **VkTestFramework::ReadFileData(const char *fileName) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600592 FILE *in;
Karl Schultz6addd812016-02-02 17:17:23 -0700593#if defined(_WIN32) && defined(__GNUC__)
594 in = fopen(fileName, "r");
595 int errorCode = in ? 0 : 1;
596#else
597 int errorCode = fopen_s(&in, fileName, "r");
598#endif
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600599
600 char *fdata;
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600601 size_t count = 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600602 const int maxSourceStrings = 5;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600603 char **return_data = (char **)malloc(sizeof(char *) * (maxSourceStrings + 1));
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600604
605 if (errorCode) {
606 printf("Error: unable to open input file: %s\n", fileName);
607 return 0;
608 }
609
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700610 while (fgetc(in) != EOF) count++;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600611
612 fseek(in, 0, SEEK_SET);
613
Karl Schultz6addd812016-02-02 17:17:23 -0700614 if (!(fdata = (char *)malloc(count + 2))) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600615 printf("Error allocating memory\n");
616 return 0;
617 }
Karl Schultz6addd812016-02-02 17:17:23 -0700618 if (fread(fdata, 1, count, in) != count) {
619 printf("Error reading input file: %s\n", fileName);
620 return 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600621 }
622 fdata[count] = '\0';
623 fclose(in);
624 if (count == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700625 return_data[0] = (char *)malloc(count + 2);
626 return_data[0][0] = '\0';
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600627 m_num_shader_strings = 0;
628 return return_data;
629 } else
630 m_num_shader_strings = 1;
631
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600632 size_t len = (int)(ceil)((float)count / (float)m_num_shader_strings);
633 size_t ptr_len = 0, i = 0;
Karl Schultz6addd812016-02-02 17:17:23 -0700634 while (count > 0) {
635 return_data[i] = (char *)malloc(len + 2);
636 memcpy(return_data[i], fdata + ptr_len, len);
637 return_data[i][len] = '\0';
638 count -= (len);
639 ptr_len += (len);
640 if (count < len) {
641 if (count == 0) {
642 m_num_shader_strings = (i + 1);
643 break;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600644 }
Karl Schultz6addd812016-02-02 17:17:23 -0700645 len = count;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600646 }
647 ++i;
648 }
649 return return_data;
650}
651
Karl Schultz6addd812016-02-02 17:17:23 -0700652void VkTestFramework::FreeFileData(char **data) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700653 for (int i = 0; i < m_num_shader_strings; i++) free(data[i]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600654}
655
656//
657// Deduce the language from the filename. Files must end in one of the
658// following extensions:
659//
660// .vert = vertex
661// .tesc = tessellation control
662// .tese = tessellation evaluation
663// .geom = geometry
664// .frag = fragment
665// .comp = compute
666//
Karl Schultz6addd812016-02-02 17:17:23 -0700667EShLanguage VkTestFramework::FindLanguage(const std::string &name) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600668 size_t ext = name.rfind('.');
669 if (ext == std::string::npos) {
670 return EShLangVertex;
671 }
672
673 std::string suffix = name.substr(ext + 1, std::string::npos);
674 if (suffix == "vert")
675 return EShLangVertex;
676 else if (suffix == "tesc")
677 return EShLangTessControl;
678 else if (suffix == "tese")
679 return EShLangTessEvaluation;
680 else if (suffix == "geom")
681 return EShLangGeometry;
682 else if (suffix == "frag")
683 return EShLangFragment;
684 else if (suffix == "comp")
685 return EShLangCompute;
686
687 return EShLangVertex;
688}
689
690//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600691// Convert VK shader type to compiler's
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600692//
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600693EShLanguage VkTestFramework::FindLanguage(const VkShaderStageFlagBits shader_type) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600694 switch (shader_type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700695 case VK_SHADER_STAGE_VERTEX_BIT:
696 return EShLangVertex;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600697
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700698 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
699 return EShLangTessControl;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600700
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700701 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
702 return EShLangTessEvaluation;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600703
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700704 case VK_SHADER_STAGE_GEOMETRY_BIT:
705 return EShLangGeometry;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600706
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700707 case VK_SHADER_STAGE_FRAGMENT_BIT:
708 return EShLangFragment;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600709
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700710 case VK_SHADER_STAGE_COMPUTE_BIT:
711 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600712
Jeff Bolzd3f98d22018-12-13 23:53:11 -0600713 case VK_SHADER_STAGE_RAYGEN_BIT_NV:
714 return EShLangRayGenNV;
715
716 case VK_SHADER_STAGE_ANY_HIT_BIT_NV:
717 return EShLangAnyHitNV;
718
719 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
720 return EShLangClosestHitNV;
721
722 case VK_SHADER_STAGE_MISS_BIT_NV:
723 return EShLangMissNV;
724
725 case VK_SHADER_STAGE_INTERSECTION_BIT_NV:
726 return EShLangIntersectNV;
727
728 case VK_SHADER_STAGE_CALLABLE_BIT_NV:
729 return EShLangCallableNV;
730
731 case VK_SHADER_STAGE_TASK_BIT_NV:
732 return EShLangTaskNV;
733
734 case VK_SHADER_STAGE_MESH_BIT_NV:
735 return EShLangMeshNV;
736
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700737 default:
738 return EShLangVertex;
Chia-I Wub4c2aa42014-12-15 23:50:11 +0800739 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600740}
741
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600742//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600743// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600744// Return value of false means an error was encountered.
745//
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600746bool VkTestFramework::GLSLtoSPV(VkPhysicalDeviceLimits const *const device_limits, const VkShaderStageFlagBits shader_type,
747 const char *pshader, std::vector<unsigned int> &spirv, bool debug, uint32_t spirv_minor_version) {
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600748 glslang::TProgram program;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600749 const char *shaderStrings[1];
750
751 // TODO: Do we want to load a special config file depending on the
752 // shader source? Optional name maybe?
753 // SetConfigFile(fileName);
754
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600755 ProcessConfigFile(device_limits);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600756
757 EShMessages messages = EShMsgDefault;
758 SetMessageOptions(messages);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600759 messages = static_cast<EShMessages>(messages | EShMsgSpvRules | EShMsgVulkanRules);
Karl Schultz9d09ee92018-10-19 14:31:49 -0600760 if (debug) {
761 messages = static_cast<EShMessages>(messages | EShMsgDebugInfo);
762 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600763
764 EShLanguage stage = FindLanguage(shader_type);
Karl Schultz6addd812016-02-02 17:17:23 -0700765 glslang::TShader *shader = new glslang::TShader(stage);
Jeff Bolz49d64982019-09-18 13:18:14 -0500766 switch (spirv_minor_version) {
767 default:
768 case 0:
769 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
770 break;
771 case 1:
772 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_1);
773 break;
774 case 2:
775 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_2);
776 break;
777 case 3:
778 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
779 break;
780 case 4:
781 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
782 break;
783 case 5:
784 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
785 break;
786 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600787
788 shaderStrings[0] = pshader;
789 shader->setStrings(shaderStrings, 1);
790
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600791 if (!shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700792 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700793 puts(shader->getInfoLog());
794 puts(shader->getInfoDebugLog());
795 }
796
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700797 return false; // something didn't work
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600798 }
799
800 program.addShader(shader);
801
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600802 //
803 // Program-level processing...
804 //
805
Karl Schultz6addd812016-02-02 17:17:23 -0700806 if (!program.link(messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700807 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700808 puts(shader->getInfoLog());
809 puts(shader->getInfoDebugLog());
810 }
811
812 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600813 }
814
815 if (m_compile_options & EOptionDumpReflection) {
816 program.buildReflection();
817 program.dumpReflection();
818 }
819
Karl Schultz9d09ee92018-10-19 14:31:49 -0600820 glslang::SpvOptions spv_options;
821 if (debug) {
822 spv_options.generateDebugInfo = true;
823 }
824 glslang::GlslangToSpv(*program.getIntermediate(stage), spirv, &spv_options);
Cody Northrop5a95b472015-06-03 13:01:54 -0600825
826 //
827 // Test the different modes of SPIR-V modification
828 //
829 if (this->m_canonicalize_spv) {
830 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
831 }
832
833 if (this->m_strip_spv) {
834 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
835 }
836
837 if (this->m_do_everything_spv) {
838 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
839 }
840
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600841 delete shader;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600842
843 return true;
844}
Karl Schultz23707622018-08-22 10:20:33 -0600845
846//
847// Compile a given string containing SPIR-V assembly into SPV for use by VK
848// Return value of false means an error was encountered.
849//
850bool VkTestFramework::ASMtoSPV(const spv_target_env target_env, const uint32_t options, const char *pasm,
851 std::vector<unsigned int> &spv) {
852 spv_binary binary;
853 spv_diagnostic diagnostic = nullptr;
854 spv_context context = spvContextCreate(target_env);
855 spv_result_t error = spvTextToBinaryWithOptions(context, pasm, strlen(pasm), options, &binary, &diagnostic);
856 spvContextDestroy(context);
857 if (error) {
858 spvDiagnosticPrint(diagnostic);
859 spvDiagnosticDestroy(diagnostic);
860 return false;
861 }
862 spv.insert(spv.end(), binary->code, binary->code + binary->wordCount);
863 spvBinaryDestroy(binary);
864
865 return true;
866}