blob: 94940dbd722ea4ac6ac477ba4314a74d356a753b [file] [log] [blame]
Karl Schultz6addd812016-02-02 17:17:23 -07001/*
Nathaniel Cesario022e7b22021-04-06 00:06:17 -06002 * Copyright (c) 2015-2021 The Khronos Group Inc.
3 * Copyright (c) 2015-2021 Valve Corporation
4 * Copyright (c) 2015-2021 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;
Nathaniel Cesario022e7b22021-04-06 00:06:17 -0600135int VkTestFramework::m_phys_device_index = -1;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600136
Karl Schultz6addd812016-02-02 17:17:23 -0700137bool VkTestFramework::optionMatch(const char *option, char *optionLine) {
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600138 if (strncmp(option, optionLine, strlen(option)) == 0)
139 return true;
140 else
141 return false;
142}
143
Karl Schultz6addd812016-02-02 17:17:23 -0700144void VkTestFramework::InitArgs(int *argc, char *argv[]) {
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600145 int i, n;
146
Karl Schultz6addd812016-02-02 17:17:23 -0700147 for (i = 1, n = 1; i < *argc; i++) {
Chris Forbesb5e22252017-04-04 15:51:36 -0700148 if (optionMatch("--strip-SPV", argv[i]))
Tony Barbour7b60e492016-02-02 14:43:55 -0700149 m_strip_spv = true;
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600150 else if (optionMatch("--canonicalize-SPV", argv[i]))
151 m_canonicalize_spv = true;
Tobin Ehlis72888642017-11-15 09:43:56 -0700152 else if (optionMatch("--devsim", argv[i]))
153 m_devsim_layer = true;
Nathaniel Cesario022e7b22021-04-06 00:06:17 -0600154 else if (optionMatch("--device-index", argv[i]) && ((i + 1) < *argc)) {
155 m_phys_device_index = std::atoi(argv[++i]);
156 } else if (optionMatch("--help", argv[i]) || optionMatch("-h", argv[i])) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700157 printf("\nOther options:\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700158 printf(
159 "\t--show-images\n"
160 "\t\tDisplay test images in viewer after tests complete.\n");
161 printf(
162 "\t--save-images\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700163 "\t\tSave tests images as ppm files in current working directory.\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700164 "\t\tUsed to generate golden images for compare-images.\n");
165 printf(
166 "\t--compare-images\n"
167 "\t\tCompare test images to 'golden' image in golden folder.\n"
168 "\t\tAlso saves the generated test image in current working\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700169 "\t\t\tdirectory but only if the image is different from the golden\n"
170 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700171 "\t\t\tdifferent directory for golden images\n"
172 "\t\tSignal test failure if different.\n");
173 printf(
174 "\t--no-SPV\n"
175 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
176 printf(
177 "\t--strip-SPV\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700178 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700179 printf(
180 "\t--canonicalize-SPV\n"
181 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
Nathaniel Cesario022e7b22021-04-06 00:06:17 -0600182 printf(
183 "\t--device-index <physical device index>\n"
184 "\t\tIndex into VkPhysicalDevice array returned from vkEnumeratePhysicalDevices.\n"
185 "\t\tThe default behavior is to automatically choose \"the most reasonable device.\"\n"
186 "\t\tAn invalid index (i.e., outside the range [0, *pPhysicalDeviceCount)) will result in the default behavior\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600187 exit(0);
188 } else {
189 printf("\nUnrecognized option: %s\n", argv[i]);
190 printf("\nUse --help or -h for option list.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700191 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700192 }
193
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600194 /*
195 * Since the above "consume" inputs, update argv
196 * so that it contains the trimmed list of args for glutInit
197 */
198
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600199 argv[n] = argv[i];
200 n++;
201 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600202}
203
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600204VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device) {
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700205 VkFormatProperties format_props;
Tony Barbour7b60e492016-02-02 14:43:55 -0700206
Mark Lobodzinski1ad400e2019-09-27 13:53:29 -0600207 vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600208 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
209 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700210 return VK_FORMAT_B8G8R8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700211 }
Mark Lobodzinski1ad400e2019-09-27 13:53:29 -0600212 vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600213 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
214 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700215 return VK_FORMAT_R8G8B8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700216 }
Dave Houlton6c72f352018-02-06 17:49:16 -0700217 printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
Tobin Ehlise37e9732016-07-11 12:57:29 -0600218 exit(1);
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700219}
220
Karl Schultz6addd812016-02-02 17:17:23 -0700221void VkTestFramework::Finish() {}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600222
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600223//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600224// These are the default resources for TBuiltInResources, used for both
225// - parsing this string for the case where the user didn't supply one
226// - dumping out a template for user construction of a config file
227//
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700228static const char *DefaultConfig =
229 "MaxLights 32\n"
230 "MaxClipPlanes 6\n"
231 "MaxTextureUnits 32\n"
232 "MaxTextureCoords 32\n"
233 "MaxVertexAttribs 64\n"
234 "MaxVertexUniformComponents 4096\n"
235 "MaxVaryingFloats 64\n"
236 "MaxVertexTextureImageUnits 32\n"
237 "MaxCombinedTextureImageUnits 80\n"
238 "MaxTextureImageUnits 32\n"
239 "MaxFragmentUniformComponents 4096\n"
240 "MaxDrawBuffers 32\n"
241 "MaxVertexUniformVectors 128\n"
242 "MaxVaryingVectors 8\n"
243 "MaxFragmentUniformVectors 16\n"
244 "MaxVertexOutputVectors 16\n"
245 "MaxFragmentInputVectors 15\n"
246 "MinProgramTexelOffset -8\n"
247 "MaxProgramTexelOffset 7\n"
248 "MaxClipDistances 8\n"
249 "MaxComputeWorkGroupCountX 65535\n"
250 "MaxComputeWorkGroupCountY 65535\n"
251 "MaxComputeWorkGroupCountZ 65535\n"
252 "MaxComputeWorkGroupSizeX 1024\n"
253 "MaxComputeWorkGroupSizeY 1024\n"
254 "MaxComputeWorkGroupSizeZ 64\n"
255 "MaxComputeUniformComponents 1024\n"
256 "MaxComputeTextureImageUnits 16\n"
257 "MaxComputeImageUniforms 8\n"
258 "MaxComputeAtomicCounters 8\n"
259 "MaxComputeAtomicCounterBuffers 1\n"
260 "MaxVaryingComponents 60\n"
261 "MaxVertexOutputComponents 64\n"
262 "MaxGeometryInputComponents 64\n"
263 "MaxGeometryOutputComponents 128\n"
264 "MaxFragmentInputComponents 128\n"
265 "MaxImageUnits 8\n"
266 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
267 "MaxCombinedShaderOutputResources 8\n"
268 "MaxImageSamples 0\n"
269 "MaxVertexImageUniforms 0\n"
270 "MaxTessControlImageUniforms 0\n"
271 "MaxTessEvaluationImageUniforms 0\n"
272 "MaxGeometryImageUniforms 0\n"
273 "MaxFragmentImageUniforms 8\n"
274 "MaxCombinedImageUniforms 8\n"
275 "MaxGeometryTextureImageUnits 16\n"
276 "MaxGeometryOutputVertices 256\n"
277 "MaxGeometryTotalOutputComponents 1024\n"
278 "MaxGeometryUniformComponents 1024\n"
279 "MaxGeometryVaryingComponents 64\n"
280 "MaxTessControlInputComponents 128\n"
281 "MaxTessControlOutputComponents 128\n"
282 "MaxTessControlTextureImageUnits 16\n"
283 "MaxTessControlUniformComponents 1024\n"
284 "MaxTessControlTotalOutputComponents 4096\n"
285 "MaxTessEvaluationInputComponents 128\n"
286 "MaxTessEvaluationOutputComponents 128\n"
287 "MaxTessEvaluationTextureImageUnits 16\n"
288 "MaxTessEvaluationUniformComponents 1024\n"
289 "MaxTessPatchComponents 120\n"
290 "MaxPatchVertices 32\n"
291 "MaxTessGenLevel 64\n"
292 "MaxViewports 16\n"
293 "MaxVertexAtomicCounters 0\n"
294 "MaxTessControlAtomicCounters 0\n"
295 "MaxTessEvaluationAtomicCounters 0\n"
296 "MaxGeometryAtomicCounters 0\n"
297 "MaxFragmentAtomicCounters 8\n"
298 "MaxCombinedAtomicCounters 8\n"
299 "MaxAtomicCounterBindings 1\n"
300 "MaxVertexAtomicCounterBuffers 0\n"
301 "MaxTessControlAtomicCounterBuffers 0\n"
302 "MaxTessEvaluationAtomicCounterBuffers 0\n"
303 "MaxGeometryAtomicCounterBuffers 0\n"
304 "MaxFragmentAtomicCounterBuffers 1\n"
305 "MaxCombinedAtomicCounterBuffers 1\n"
306 "MaxAtomicCounterBufferSize 16384\n"
307 "MaxTransformFeedbackBuffers 4\n"
308 "MaxTransformFeedbackInterleavedComponents 64\n"
309 "MaxCullDistances 8\n"
310 "MaxCombinedClipAndCullDistances 8\n"
311 "MaxSamples 4\n"
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500312 "MaxMeshOutputVerticesNV 256\n"
313 "MaxMeshOutputPrimitivesNV 512\n"
314 "MaxMeshWorkGroupSizeX_NV 32\n"
315 "MaxMeshWorkGroupSizeY_NV 1\n"
316 "MaxMeshWorkGroupSizeZ_NV 1\n"
317 "MaxTaskWorkGroupSizeX_NV 32\n"
318 "MaxTaskWorkGroupSizeY_NV 1\n"
319 "MaxTaskWorkGroupSizeZ_NV 1\n"
320 "MaxMeshViewCountNV 4\n"
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600321
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700322 "nonInductiveForLoops 1\n"
323 "whileLoops 1\n"
324 "doWhileLoops 1\n"
325 "generalUniformIndexing 1\n"
326 "generalAttributeMatrixVectorIndexing 1\n"
327 "generalVaryingIndexing 1\n"
328 "generalSamplerIndexing 1\n"
329 "generalVariableIndexing 1\n"
330 "generalConstantMatrixVectorIndexing 1\n";
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600331
332//
333// *.conf => this is a config file that can set limits/resources
334//
Karl Schultz6addd812016-02-02 17:17:23 -0700335bool VkTestFramework::SetConfigFile(const std::string &name) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700336 if (name.size() < 5) return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600337
338 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
339 ConfigFile = name;
340 return true;
341 }
342
343 return false;
344}
345
346//
347// Parse either a .conf file provided by the user or the default string above.
348//
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600349void VkTestFramework::ProcessConfigFile(VkPhysicalDeviceLimits const *const device_limits) {
Karl Schultz6addd812016-02-02 17:17:23 -0700350 char **configStrings = 0;
351 char *config = 0;
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600352 bool config_file_specified = false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600353 if (ConfigFile.size() > 0) {
354 configStrings = ReadFileData(ConfigFile.c_str());
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600355 if (configStrings) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600356 config = *configStrings;
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600357 config_file_specified = true;
358 } else {
Dave Houlton6c72f352018-02-06 17:49:16 -0700359 printf("Error opening configuration file; will instead use the default configuration\n");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600360 }
361 }
362
363 if (config == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700364 config = (char *)alloca(strlen(DefaultConfig) + 1);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600365 strcpy(config, DefaultConfig);
366 }
367
Karl Schultz6addd812016-02-02 17:17:23 -0700368 const char *delims = " \t\n\r";
369 const char *token = strtok(config, delims);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600370 while (token) {
Karl Schultz6addd812016-02-02 17:17:23 -0700371 const char *valueStr = strtok(0, delims);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600372 if (valueStr == 0 || !(valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
Dave Houlton6c72f352018-02-06 17:49:16 -0700373 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600374 return;
375 }
376 int value = atoi(valueStr);
377
378 if (strcmp(token, "MaxLights") == 0)
379 Resources.maxLights = value;
380 else if (strcmp(token, "MaxClipPlanes") == 0)
381 Resources.maxClipPlanes = value;
382 else if (strcmp(token, "MaxTextureUnits") == 0)
383 Resources.maxTextureUnits = value;
384 else if (strcmp(token, "MaxTextureCoords") == 0)
385 Resources.maxTextureCoords = value;
386 else if (strcmp(token, "MaxVertexAttribs") == 0)
387 Resources.maxVertexAttribs = value;
388 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
389 Resources.maxVertexUniformComponents = value;
390 else if (strcmp(token, "MaxVaryingFloats") == 0)
391 Resources.maxVaryingFloats = value;
392 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
393 Resources.maxVertexTextureImageUnits = value;
394 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
395 Resources.maxCombinedTextureImageUnits = value;
396 else if (strcmp(token, "MaxTextureImageUnits") == 0)
397 Resources.maxTextureImageUnits = value;
398 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
399 Resources.maxFragmentUniformComponents = value;
400 else if (strcmp(token, "MaxDrawBuffers") == 0)
401 Resources.maxDrawBuffers = value;
402 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
403 Resources.maxVertexUniformVectors = value;
404 else if (strcmp(token, "MaxVaryingVectors") == 0)
405 Resources.maxVaryingVectors = value;
406 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
407 Resources.maxFragmentUniformVectors = value;
408 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
409 Resources.maxVertexOutputVectors = value;
410 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
411 Resources.maxFragmentInputVectors = value;
412 else if (strcmp(token, "MinProgramTexelOffset") == 0)
413 Resources.minProgramTexelOffset = value;
414 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
415 Resources.maxProgramTexelOffset = value;
416 else if (strcmp(token, "MaxClipDistances") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600417 Resources.maxClipDistances = (config_file_specified ? value : device_limits->maxClipDistances);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600418 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600419 Resources.maxComputeWorkGroupCountX = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[0]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600420 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600421 Resources.maxComputeWorkGroupCountY = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[1]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600422 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600423 Resources.maxComputeWorkGroupCountZ = (config_file_specified ? value : device_limits->maxComputeWorkGroupCount[2]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600424 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600425 Resources.maxComputeWorkGroupSizeX = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[0]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600426 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600427 Resources.maxComputeWorkGroupSizeY = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[1]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600428 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600429 Resources.maxComputeWorkGroupSizeZ = (config_file_specified ? value : device_limits->maxComputeWorkGroupSize[2]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600430 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
431 Resources.maxComputeUniformComponents = value;
432 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
433 Resources.maxComputeTextureImageUnits = value;
434 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
435 Resources.maxComputeImageUniforms = value;
436 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
437 Resources.maxComputeAtomicCounters = value;
438 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
439 Resources.maxComputeAtomicCounterBuffers = value;
440 else if (strcmp(token, "MaxVaryingComponents") == 0)
441 Resources.maxVaryingComponents = value;
442 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600443 Resources.maxVertexOutputComponents = (config_file_specified ? value : device_limits->maxVertexOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600444 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600445 Resources.maxGeometryInputComponents = (config_file_specified ? value : device_limits->maxGeometryInputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600446 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600447 Resources.maxGeometryOutputComponents = (config_file_specified ? value : device_limits->maxGeometryOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600448 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600449 Resources.maxFragmentInputComponents = (config_file_specified ? value : device_limits->maxFragmentInputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600450 else if (strcmp(token, "MaxImageUnits") == 0)
451 Resources.maxImageUnits = value;
452 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
453 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
454 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
455 Resources.maxCombinedShaderOutputResources = value;
456 else if (strcmp(token, "MaxImageSamples") == 0)
457 Resources.maxImageSamples = value;
458 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
459 Resources.maxVertexImageUniforms = value;
460 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
461 Resources.maxTessControlImageUniforms = value;
462 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
463 Resources.maxTessEvaluationImageUniforms = value;
464 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
465 Resources.maxGeometryImageUniforms = value;
466 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
467 Resources.maxFragmentImageUniforms = value;
468 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
469 Resources.maxCombinedImageUniforms = value;
470 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
471 Resources.maxGeometryTextureImageUnits = value;
472 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600473 Resources.maxGeometryOutputVertices = (config_file_specified ? value : device_limits->maxGeometryOutputVertices);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600474 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600475 Resources.maxGeometryTotalOutputComponents =
476 (config_file_specified ? value : device_limits->maxGeometryTotalOutputComponents);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600477 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
478 Resources.maxGeometryUniformComponents = value;
479 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
480 Resources.maxGeometryVaryingComponents = value;
481 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
482 Resources.maxTessControlInputComponents = value;
483 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
484 Resources.maxTessControlOutputComponents = value;
485 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
486 Resources.maxTessControlTextureImageUnits = value;
487 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
488 Resources.maxTessControlUniformComponents = value;
489 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
490 Resources.maxTessControlTotalOutputComponents = value;
491 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
492 Resources.maxTessEvaluationInputComponents = value;
493 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
494 Resources.maxTessEvaluationOutputComponents = value;
495 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
496 Resources.maxTessEvaluationTextureImageUnits = value;
497 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
498 Resources.maxTessEvaluationUniformComponents = value;
499 else if (strcmp(token, "MaxTessPatchComponents") == 0)
500 Resources.maxTessPatchComponents = value;
501 else if (strcmp(token, "MaxPatchVertices") == 0)
502 Resources.maxPatchVertices = value;
503 else if (strcmp(token, "MaxTessGenLevel") == 0)
504 Resources.maxTessGenLevel = value;
505 else if (strcmp(token, "MaxViewports") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600506 Resources.maxViewports = (config_file_specified ? value : device_limits->maxViewports);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600507 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
508 Resources.maxVertexAtomicCounters = value;
509 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
510 Resources.maxTessControlAtomicCounters = value;
511 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
512 Resources.maxTessEvaluationAtomicCounters = value;
513 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
514 Resources.maxGeometryAtomicCounters = value;
515 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
516 Resources.maxFragmentAtomicCounters = value;
517 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
518 Resources.maxCombinedAtomicCounters = value;
519 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
520 Resources.maxAtomicCounterBindings = value;
521 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
522 Resources.maxVertexAtomicCounterBuffers = value;
523 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
524 Resources.maxTessControlAtomicCounterBuffers = value;
525 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
526 Resources.maxTessEvaluationAtomicCounterBuffers = value;
527 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
528 Resources.maxGeometryAtomicCounterBuffers = value;
529 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
530 Resources.maxFragmentAtomicCounterBuffers = value;
531 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
532 Resources.maxCombinedAtomicCounterBuffers = value;
533 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
534 Resources.maxAtomicCounterBufferSize = value;
535 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
536 Resources.maxTransformFeedbackBuffers = value;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600537 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600538 Resources.maxTransformFeedbackInterleavedComponents = value;
539 else if (strcmp(token, "MaxCullDistances") == 0)
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600540 Resources.maxCullDistances = (config_file_specified ? value : device_limits->maxCullDistances);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600541 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
542 Resources.maxCombinedClipAndCullDistances = value;
543 else if (strcmp(token, "MaxSamples") == 0)
544 Resources.maxSamples = value;
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500545 else if (strcmp(token, "MaxMeshOutputVerticesNV") == 0)
546 Resources.maxMeshOutputVerticesNV = value;
547 else if (strcmp(token, "MaxMeshOutputPrimitivesNV") == 0)
548 Resources.maxMeshOutputPrimitivesNV = value;
549 else if (strcmp(token, "MaxMeshWorkGroupSizeX_NV") == 0)
550 Resources.maxMeshWorkGroupSizeX_NV = value;
551 else if (strcmp(token, "MaxMeshWorkGroupSizeY_NV") == 0)
552 Resources.maxMeshWorkGroupSizeY_NV = value;
553 else if (strcmp(token, "MaxMeshWorkGroupSizeZ_NV") == 0)
554 Resources.maxMeshWorkGroupSizeZ_NV = value;
555 else if (strcmp(token, "MaxTaskWorkGroupSizeX_NV") == 0)
556 Resources.maxTaskWorkGroupSizeX_NV = value;
557 else if (strcmp(token, "MaxTaskWorkGroupSizeY_NV") == 0)
558 Resources.maxTaskWorkGroupSizeY_NV = value;
559 else if (strcmp(token, "MaxTaskWorkGroupSizeZ_NV") == 0)
560 Resources.maxTaskWorkGroupSizeZ_NV = value;
561 else if (strcmp(token, "MaxMeshViewCountNV") == 0)
562 Resources.maxMeshViewCountNV = value;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600563
564 else if (strcmp(token, "nonInductiveForLoops") == 0)
565 Resources.limits.nonInductiveForLoops = (value != 0);
566 else if (strcmp(token, "whileLoops") == 0)
567 Resources.limits.whileLoops = (value != 0);
568 else if (strcmp(token, "doWhileLoops") == 0)
569 Resources.limits.doWhileLoops = (value != 0);
570 else if (strcmp(token, "generalUniformIndexing") == 0)
571 Resources.limits.generalUniformIndexing = (value != 0);
572 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600573 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600574 else if (strcmp(token, "generalVaryingIndexing") == 0)
575 Resources.limits.generalVaryingIndexing = (value != 0);
576 else if (strcmp(token, "generalSamplerIndexing") == 0)
577 Resources.limits.generalSamplerIndexing = (value != 0);
578 else if (strcmp(token, "generalVariableIndexing") == 0)
579 Resources.limits.generalVariableIndexing = (value != 0);
580 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
581 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
582 else
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600583 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600584
585 token = strtok(0, delims);
586 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700587 if (configStrings) FreeFileData(configStrings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600588}
589
Karl Schultz6addd812016-02-02 17:17:23 -0700590void VkTestFramework::SetMessageOptions(EShMessages &messages) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700591 if (m_compile_options & EOptionRelaxedErrors) messages = (EShMessages)(messages | EShMsgRelaxedErrors);
592 if (m_compile_options & EOptionIntermediate) messages = (EShMessages)(messages | EShMsgAST);
593 if (m_compile_options & EOptionSuppressWarnings) messages = (EShMessages)(messages | EShMsgSuppressWarnings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600594}
595
596//
597// Malloc a string of sufficient size and read a string into it.
598//
Karl Schultz6addd812016-02-02 17:17:23 -0700599char **VkTestFramework::ReadFileData(const char *fileName) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600600 FILE *in;
Karl Schultz6addd812016-02-02 17:17:23 -0700601#if defined(_WIN32) && defined(__GNUC__)
602 in = fopen(fileName, "r");
603 int errorCode = in ? 0 : 1;
604#else
605 int errorCode = fopen_s(&in, fileName, "r");
606#endif
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600607
608 char *fdata;
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600609 size_t count = 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600610 const int maxSourceStrings = 5;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600611 char **return_data = (char **)malloc(sizeof(char *) * (maxSourceStrings + 1));
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600612
613 if (errorCode) {
614 printf("Error: unable to open input file: %s\n", fileName);
615 return 0;
616 }
617
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700618 while (fgetc(in) != EOF) count++;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600619
620 fseek(in, 0, SEEK_SET);
621
Karl Schultz6addd812016-02-02 17:17:23 -0700622 if (!(fdata = (char *)malloc(count + 2))) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600623 printf("Error allocating memory\n");
624 return 0;
625 }
Karl Schultz6addd812016-02-02 17:17:23 -0700626 if (fread(fdata, 1, count, in) != count) {
627 printf("Error reading input file: %s\n", fileName);
628 return 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600629 }
630 fdata[count] = '\0';
631 fclose(in);
632 if (count == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700633 return_data[0] = (char *)malloc(count + 2);
634 return_data[0][0] = '\0';
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600635 m_num_shader_strings = 0;
636 return return_data;
637 } else
638 m_num_shader_strings = 1;
639
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600640 size_t len = (int)(ceil)((float)count / (float)m_num_shader_strings);
641 size_t ptr_len = 0, i = 0;
Karl Schultz6addd812016-02-02 17:17:23 -0700642 while (count > 0) {
643 return_data[i] = (char *)malloc(len + 2);
644 memcpy(return_data[i], fdata + ptr_len, len);
645 return_data[i][len] = '\0';
646 count -= (len);
647 ptr_len += (len);
648 if (count < len) {
649 if (count == 0) {
650 m_num_shader_strings = (i + 1);
651 break;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600652 }
Karl Schultz6addd812016-02-02 17:17:23 -0700653 len = count;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600654 }
655 ++i;
656 }
657 return return_data;
658}
659
Karl Schultz6addd812016-02-02 17:17:23 -0700660void VkTestFramework::FreeFileData(char **data) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700661 for (int i = 0; i < m_num_shader_strings; i++) free(data[i]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600662}
663
664//
665// Deduce the language from the filename. Files must end in one of the
666// following extensions:
667//
668// .vert = vertex
669// .tesc = tessellation control
670// .tese = tessellation evaluation
671// .geom = geometry
672// .frag = fragment
673// .comp = compute
674//
Karl Schultz6addd812016-02-02 17:17:23 -0700675EShLanguage VkTestFramework::FindLanguage(const std::string &name) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600676 size_t ext = name.rfind('.');
677 if (ext == std::string::npos) {
678 return EShLangVertex;
679 }
680
681 std::string suffix = name.substr(ext + 1, std::string::npos);
682 if (suffix == "vert")
683 return EShLangVertex;
684 else if (suffix == "tesc")
685 return EShLangTessControl;
686 else if (suffix == "tese")
687 return EShLangTessEvaluation;
688 else if (suffix == "geom")
689 return EShLangGeometry;
690 else if (suffix == "frag")
691 return EShLangFragment;
692 else if (suffix == "comp")
693 return EShLangCompute;
694
695 return EShLangVertex;
696}
697
698//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600699// Convert VK shader type to compiler's
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600700//
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600701EShLanguage VkTestFramework::FindLanguage(const VkShaderStageFlagBits shader_type) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600702 switch (shader_type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700703 case VK_SHADER_STAGE_VERTEX_BIT:
704 return EShLangVertex;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600705
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700706 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
707 return EShLangTessControl;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600708
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700709 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
710 return EShLangTessEvaluation;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600711
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700712 case VK_SHADER_STAGE_GEOMETRY_BIT:
713 return EShLangGeometry;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600714
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700715 case VK_SHADER_STAGE_FRAGMENT_BIT:
716 return EShLangFragment;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600717
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700718 case VK_SHADER_STAGE_COMPUTE_BIT:
719 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600720
Jeff Bolzd3f98d22018-12-13 23:53:11 -0600721 case VK_SHADER_STAGE_RAYGEN_BIT_NV:
722 return EShLangRayGenNV;
723
724 case VK_SHADER_STAGE_ANY_HIT_BIT_NV:
725 return EShLangAnyHitNV;
726
727 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
728 return EShLangClosestHitNV;
729
730 case VK_SHADER_STAGE_MISS_BIT_NV:
731 return EShLangMissNV;
732
733 case VK_SHADER_STAGE_INTERSECTION_BIT_NV:
734 return EShLangIntersectNV;
735
736 case VK_SHADER_STAGE_CALLABLE_BIT_NV:
737 return EShLangCallableNV;
738
739 case VK_SHADER_STAGE_TASK_BIT_NV:
740 return EShLangTaskNV;
741
742 case VK_SHADER_STAGE_MESH_BIT_NV:
743 return EShLangMeshNV;
744
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700745 default:
746 return EShLangVertex;
Chia-I Wub4c2aa42014-12-15 23:50:11 +0800747 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600748}
749
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600750//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600751// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600752// Return value of false means an error was encountered.
753//
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600754bool VkTestFramework::GLSLtoSPV(VkPhysicalDeviceLimits const *const device_limits, const VkShaderStageFlagBits shader_type,
755 const char *pshader, std::vector<unsigned int> &spirv, bool debug, uint32_t spirv_minor_version) {
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600756 glslang::TProgram program;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600757 const char *shaderStrings[1];
758
759 // TODO: Do we want to load a special config file depending on the
760 // shader source? Optional name maybe?
761 // SetConfigFile(fileName);
762
Mark Lobodzinskif0003442019-10-28 16:05:32 -0600763 ProcessConfigFile(device_limits);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600764
765 EShMessages messages = EShMsgDefault;
766 SetMessageOptions(messages);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600767 messages = static_cast<EShMessages>(messages | EShMsgSpvRules | EShMsgVulkanRules);
Karl Schultz9d09ee92018-10-19 14:31:49 -0600768 if (debug) {
769 messages = static_cast<EShMessages>(messages | EShMsgDebugInfo);
770 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600771
772 EShLanguage stage = FindLanguage(shader_type);
Karl Schultz6addd812016-02-02 17:17:23 -0700773 glslang::TShader *shader = new glslang::TShader(stage);
Jeff Bolz49d64982019-09-18 13:18:14 -0500774 switch (spirv_minor_version) {
775 default:
776 case 0:
777 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
778 break;
779 case 1:
780 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_1);
781 break;
782 case 2:
783 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_2);
784 break;
785 case 3:
786 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
787 break;
788 case 4:
789 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
790 break;
791 case 5:
792 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
793 break;
794 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600795
796 shaderStrings[0] = pshader;
797 shader->setStrings(shaderStrings, 1);
798
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600799 if (!shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700800 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700801 puts(shader->getInfoLog());
802 puts(shader->getInfoDebugLog());
803 }
804
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700805 return false; // something didn't work
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600806 }
807
808 program.addShader(shader);
809
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600810 //
811 // Program-level processing...
812 //
813
Karl Schultz6addd812016-02-02 17:17:23 -0700814 if (!program.link(messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700815 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700816 puts(shader->getInfoLog());
817 puts(shader->getInfoDebugLog());
818 }
819
820 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600821 }
822
823 if (m_compile_options & EOptionDumpReflection) {
824 program.buildReflection();
825 program.dumpReflection();
826 }
827
Karl Schultz9d09ee92018-10-19 14:31:49 -0600828 glslang::SpvOptions spv_options;
829 if (debug) {
830 spv_options.generateDebugInfo = true;
831 }
832 glslang::GlslangToSpv(*program.getIntermediate(stage), spirv, &spv_options);
Cody Northrop5a95b472015-06-03 13:01:54 -0600833
834 //
835 // Test the different modes of SPIR-V modification
836 //
837 if (this->m_canonicalize_spv) {
838 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
839 }
840
841 if (this->m_strip_spv) {
842 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
843 }
844
845 if (this->m_do_everything_spv) {
846 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
847 }
848
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600849 delete shader;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600850
851 return true;
852}
Karl Schultz23707622018-08-22 10:20:33 -0600853
854//
855// Compile a given string containing SPIR-V assembly into SPV for use by VK
856// Return value of false means an error was encountered.
857//
858bool VkTestFramework::ASMtoSPV(const spv_target_env target_env, const uint32_t options, const char *pasm,
859 std::vector<unsigned int> &spv) {
860 spv_binary binary;
861 spv_diagnostic diagnostic = nullptr;
862 spv_context context = spvContextCreate(target_env);
863 spv_result_t error = spvTextToBinaryWithOptions(context, pasm, strlen(pasm), options, &binary, &diagnostic);
864 spvContextDestroy(context);
865 if (error) {
866 spvDiagnosticPrint(diagnostic);
867 spvDiagnosticDestroy(diagnostic);
868 return false;
869 }
870 spv.insert(spv.end(), binary->code, binary->code + binary->wordCount);
871 spvBinaryDestroy(binary);
872
873 return true;
874}