blob: ef5ae06750f0a786cb7c78b8bc3b0d4d368736f6 [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
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070063#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
64 { \
65 m_fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
66 if (m_fp##entrypoint == NULL) { \
67 ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, "vkGetInstanceProcAddr Failure"); \
68 } \
Karl Schultz6addd812016-02-02 17:17:23 -070069 }
Tony Barbour6a3faf02015-07-23 10:36:18 -060070
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070071#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
72 { \
73 m_fp##entrypoint = (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint); \
74 if (m_fp##entrypoint == NULL) { \
75 ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint, "vkGetDeviceProcAddr Failure"); \
76 } \
Karl Schultz6addd812016-02-02 17:17:23 -070077 }
Tony Barbour6a3faf02015-07-23 10:36:18 -060078
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060079// Command-line options
80enum TOptions {
Karl Schultz6addd812016-02-02 17:17:23 -070081 EOptionNone = 0x000,
82 EOptionIntermediate = 0x001,
83 EOptionSuppressInfolog = 0x002,
84 EOptionMemoryLeakMode = 0x004,
85 EOptionRelaxedErrors = 0x008,
86 EOptionGiveWarnings = 0x010,
87 EOptionLinkProgram = 0x020,
88 EOptionMultiThreaded = 0x040,
89 EOptionDumpConfig = 0x080,
90 EOptionDumpReflection = 0x100,
91 EOptionSuppressWarnings = 0x200,
92 EOptionDumpVersions = 0x400,
93 EOptionSpv = 0x800,
94 EOptionDefaultDesktop = 0x1000,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060095};
96
Mark Lobodzinskib5ccf3f2016-05-19 17:26:51 -060097struct SwapchainBuffers {
Tony Barbour6a3faf02015-07-23 10:36:18 -060098 VkImage image;
Chia-I Wu3432a0c2015-10-27 18:04:07 +080099 VkCommandBuffer cmd;
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -0600100 VkImageView view;
Mark Lobodzinskib5ccf3f2016-05-19 17:26:51 -0600101};
Tony Barbour6a3faf02015-07-23 10:36:18 -0600102
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600103#ifndef _WIN32
104
105#include <errno.h>
106
Karl Schultz6addd812016-02-02 17:17:23 -0700107int fopen_s(FILE **pFile, const char *filename, const char *mode) {
108 if (!pFile || !filename || !mode) {
109 return EINVAL;
110 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600111
Karl Schultz6addd812016-02-02 17:17:23 -0700112 FILE *f = fopen(filename, mode);
113 if (!f) {
114 if (errno != 0) {
115 return errno;
116 } else {
117 return ENOENT;
118 }
119 }
120 *pFile = f;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600121
Karl Schultz6addd812016-02-02 17:17:23 -0700122 return 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600123}
124
125#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600126
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600127// Set up environment for GLSL compiler
128// Must be done once per process
Karl Schultz6addd812016-02-02 17:17:23 -0700129void TestEnvironment::SetUp() {
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600130 // Initialize GLSL to SPV compiler utility
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600131 glslang::InitializeProcess();
Chia-I Wub76e0fa2014-12-28 14:27:28 +0800132
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600133 vk_testing::set_error_callback(test_error_callback);
Mark Lobodzinski91ee16c2019-09-27 11:44:52 -0600134
135 vk::InitDispatchTable();
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600136}
137
Karl Schultz6addd812016-02-02 17:17:23 -0700138void TestEnvironment::TearDown() { glslang::FinalizeProcess(); }
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600139
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600140VkTestFramework::VkTestFramework() : m_compile_options(0), m_num_shader_strings(0) {}
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600141
Karl Schultz6addd812016-02-02 17:17:23 -0700142VkTestFramework::~VkTestFramework() {}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600143
144// Define all the static elements
Karl Schultz6addd812016-02-02 17:17:23 -0700145bool VkTestFramework::m_canonicalize_spv = false;
146bool VkTestFramework::m_strip_spv = false;
Cody Northrop5a95b472015-06-03 13:01:54 -0600147bool VkTestFramework::m_do_everything_spv = false;
Tobin Ehlis72888642017-11-15 09:43:56 -0700148bool VkTestFramework::m_devsim_layer = false;
Tony Barbour6918cd52015-04-09 12:58:51 -0600149int VkTestFramework::m_width = 0;
150int VkTestFramework::m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600151
Karl Schultz6addd812016-02-02 17:17:23 -0700152bool VkTestFramework::optionMatch(const char *option, char *optionLine) {
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600153 if (strncmp(option, optionLine, strlen(option)) == 0)
154 return true;
155 else
156 return false;
157}
158
Karl Schultz6addd812016-02-02 17:17:23 -0700159void VkTestFramework::InitArgs(int *argc, char *argv[]) {
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600160 int i, n;
161
Karl Schultz6addd812016-02-02 17:17:23 -0700162 for (i = 1, n = 1; i < *argc; i++) {
Chris Forbesb5e22252017-04-04 15:51:36 -0700163 if (optionMatch("--strip-SPV", argv[i]))
Tony Barbour7b60e492016-02-02 14:43:55 -0700164 m_strip_spv = true;
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600165 else if (optionMatch("--canonicalize-SPV", argv[i]))
166 m_canonicalize_spv = true;
Tobin Ehlis72888642017-11-15 09:43:56 -0700167 else if (optionMatch("--devsim", argv[i]))
168 m_devsim_layer = true;
Karl Schultz6addd812016-02-02 17:17:23 -0700169 else if (optionMatch("--help", argv[i]) || optionMatch("-h", argv[i])) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700170 printf("\nOther options:\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700171 printf(
172 "\t--show-images\n"
173 "\t\tDisplay test images in viewer after tests complete.\n");
174 printf(
175 "\t--save-images\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700176 "\t\tSave tests images as ppm files in current working directory.\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700177 "\t\tUsed to generate golden images for compare-images.\n");
178 printf(
179 "\t--compare-images\n"
180 "\t\tCompare test images to 'golden' image in golden folder.\n"
181 "\t\tAlso saves the generated test image in current working\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700182 "\t\t\tdirectory but only if the image is different from the golden\n"
183 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700184 "\t\t\tdifferent directory for golden images\n"
185 "\t\tSignal test failure if different.\n");
186 printf(
187 "\t--no-SPV\n"
188 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
189 printf(
190 "\t--strip-SPV\n"
Dave Houlton6c72f352018-02-06 17:49:16 -0700191 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700192 printf(
193 "\t--canonicalize-SPV\n"
194 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600195 exit(0);
196 } else {
197 printf("\nUnrecognized option: %s\n", argv[i]);
198 printf("\nUse --help or -h for option list.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700199 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700200 }
201
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600202 /*
203 * Since the above "consume" inputs, update argv
204 * so that it contains the trimmed list of args for glutInit
205 */
206
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600207 argv[n] = argv[i];
208 n++;
209 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600210}
211
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600212VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device) {
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700213 VkFormatProperties format_props;
Tony Barbour7b60e492016-02-02 14:43:55 -0700214
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600215 vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
216 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
217 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700218 return VK_FORMAT_B8G8R8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700219 }
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600220 vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
221 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
222 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
Tony Barbour7b60e492016-02-02 14:43:55 -0700223 return VK_FORMAT_R8G8B8A8_UNORM;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700224 }
Dave Houlton6c72f352018-02-06 17:49:16 -0700225 printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
Tobin Ehlise37e9732016-07-11 12:57:29 -0600226 exit(1);
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700227}
228
Karl Schultz6addd812016-02-02 17:17:23 -0700229void VkTestFramework::Finish() {}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600230
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600231//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600232// These are the default resources for TBuiltInResources, used for both
233// - parsing this string for the case where the user didn't supply one
234// - dumping out a template for user construction of a config file
235//
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700236static const char *DefaultConfig =
237 "MaxLights 32\n"
238 "MaxClipPlanes 6\n"
239 "MaxTextureUnits 32\n"
240 "MaxTextureCoords 32\n"
241 "MaxVertexAttribs 64\n"
242 "MaxVertexUniformComponents 4096\n"
243 "MaxVaryingFloats 64\n"
244 "MaxVertexTextureImageUnits 32\n"
245 "MaxCombinedTextureImageUnits 80\n"
246 "MaxTextureImageUnits 32\n"
247 "MaxFragmentUniformComponents 4096\n"
248 "MaxDrawBuffers 32\n"
249 "MaxVertexUniformVectors 128\n"
250 "MaxVaryingVectors 8\n"
251 "MaxFragmentUniformVectors 16\n"
252 "MaxVertexOutputVectors 16\n"
253 "MaxFragmentInputVectors 15\n"
254 "MinProgramTexelOffset -8\n"
255 "MaxProgramTexelOffset 7\n"
256 "MaxClipDistances 8\n"
257 "MaxComputeWorkGroupCountX 65535\n"
258 "MaxComputeWorkGroupCountY 65535\n"
259 "MaxComputeWorkGroupCountZ 65535\n"
260 "MaxComputeWorkGroupSizeX 1024\n"
261 "MaxComputeWorkGroupSizeY 1024\n"
262 "MaxComputeWorkGroupSizeZ 64\n"
263 "MaxComputeUniformComponents 1024\n"
264 "MaxComputeTextureImageUnits 16\n"
265 "MaxComputeImageUniforms 8\n"
266 "MaxComputeAtomicCounters 8\n"
267 "MaxComputeAtomicCounterBuffers 1\n"
268 "MaxVaryingComponents 60\n"
269 "MaxVertexOutputComponents 64\n"
270 "MaxGeometryInputComponents 64\n"
271 "MaxGeometryOutputComponents 128\n"
272 "MaxFragmentInputComponents 128\n"
273 "MaxImageUnits 8\n"
274 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
275 "MaxCombinedShaderOutputResources 8\n"
276 "MaxImageSamples 0\n"
277 "MaxVertexImageUniforms 0\n"
278 "MaxTessControlImageUniforms 0\n"
279 "MaxTessEvaluationImageUniforms 0\n"
280 "MaxGeometryImageUniforms 0\n"
281 "MaxFragmentImageUniforms 8\n"
282 "MaxCombinedImageUniforms 8\n"
283 "MaxGeometryTextureImageUnits 16\n"
284 "MaxGeometryOutputVertices 256\n"
285 "MaxGeometryTotalOutputComponents 1024\n"
286 "MaxGeometryUniformComponents 1024\n"
287 "MaxGeometryVaryingComponents 64\n"
288 "MaxTessControlInputComponents 128\n"
289 "MaxTessControlOutputComponents 128\n"
290 "MaxTessControlTextureImageUnits 16\n"
291 "MaxTessControlUniformComponents 1024\n"
292 "MaxTessControlTotalOutputComponents 4096\n"
293 "MaxTessEvaluationInputComponents 128\n"
294 "MaxTessEvaluationOutputComponents 128\n"
295 "MaxTessEvaluationTextureImageUnits 16\n"
296 "MaxTessEvaluationUniformComponents 1024\n"
297 "MaxTessPatchComponents 120\n"
298 "MaxPatchVertices 32\n"
299 "MaxTessGenLevel 64\n"
300 "MaxViewports 16\n"
301 "MaxVertexAtomicCounters 0\n"
302 "MaxTessControlAtomicCounters 0\n"
303 "MaxTessEvaluationAtomicCounters 0\n"
304 "MaxGeometryAtomicCounters 0\n"
305 "MaxFragmentAtomicCounters 8\n"
306 "MaxCombinedAtomicCounters 8\n"
307 "MaxAtomicCounterBindings 1\n"
308 "MaxVertexAtomicCounterBuffers 0\n"
309 "MaxTessControlAtomicCounterBuffers 0\n"
310 "MaxTessEvaluationAtomicCounterBuffers 0\n"
311 "MaxGeometryAtomicCounterBuffers 0\n"
312 "MaxFragmentAtomicCounterBuffers 1\n"
313 "MaxCombinedAtomicCounterBuffers 1\n"
314 "MaxAtomicCounterBufferSize 16384\n"
315 "MaxTransformFeedbackBuffers 4\n"
316 "MaxTransformFeedbackInterleavedComponents 64\n"
317 "MaxCullDistances 8\n"
318 "MaxCombinedClipAndCullDistances 8\n"
319 "MaxSamples 4\n"
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500320 "MaxMeshOutputVerticesNV 256\n"
321 "MaxMeshOutputPrimitivesNV 512\n"
322 "MaxMeshWorkGroupSizeX_NV 32\n"
323 "MaxMeshWorkGroupSizeY_NV 1\n"
324 "MaxMeshWorkGroupSizeZ_NV 1\n"
325 "MaxTaskWorkGroupSizeX_NV 32\n"
326 "MaxTaskWorkGroupSizeY_NV 1\n"
327 "MaxTaskWorkGroupSizeZ_NV 1\n"
328 "MaxMeshViewCountNV 4\n"
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600329
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700330 "nonInductiveForLoops 1\n"
331 "whileLoops 1\n"
332 "doWhileLoops 1\n"
333 "generalUniformIndexing 1\n"
334 "generalAttributeMatrixVectorIndexing 1\n"
335 "generalVaryingIndexing 1\n"
336 "generalSamplerIndexing 1\n"
337 "generalVariableIndexing 1\n"
338 "generalConstantMatrixVectorIndexing 1\n";
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600339
340//
341// *.conf => this is a config file that can set limits/resources
342//
Karl Schultz6addd812016-02-02 17:17:23 -0700343bool VkTestFramework::SetConfigFile(const std::string &name) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700344 if (name.size() < 5) return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600345
346 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
347 ConfigFile = name;
348 return true;
349 }
350
351 return false;
352}
353
354//
355// Parse either a .conf file provided by the user or the default string above.
356//
Karl Schultz6addd812016-02-02 17:17:23 -0700357void VkTestFramework::ProcessConfigFile() {
358 char **configStrings = 0;
359 char *config = 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600360 if (ConfigFile.size() > 0) {
361 configStrings = ReadFileData(ConfigFile.c_str());
362 if (configStrings)
363 config = *configStrings;
364 else {
Dave Houlton6c72f352018-02-06 17:49:16 -0700365 printf("Error opening configuration file; will instead use the default configuration\n");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600366 }
367 }
368
369 if (config == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700370 config = (char *)alloca(strlen(DefaultConfig) + 1);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600371 strcpy(config, DefaultConfig);
372 }
373
Karl Schultz6addd812016-02-02 17:17:23 -0700374 const char *delims = " \t\n\r";
375 const char *token = strtok(config, delims);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600376 while (token) {
Karl Schultz6addd812016-02-02 17:17:23 -0700377 const char *valueStr = strtok(0, delims);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600378 if (valueStr == 0 || !(valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
Dave Houlton6c72f352018-02-06 17:49:16 -0700379 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600380 return;
381 }
382 int value = atoi(valueStr);
383
384 if (strcmp(token, "MaxLights") == 0)
385 Resources.maxLights = value;
386 else if (strcmp(token, "MaxClipPlanes") == 0)
387 Resources.maxClipPlanes = value;
388 else if (strcmp(token, "MaxTextureUnits") == 0)
389 Resources.maxTextureUnits = value;
390 else if (strcmp(token, "MaxTextureCoords") == 0)
391 Resources.maxTextureCoords = value;
392 else if (strcmp(token, "MaxVertexAttribs") == 0)
393 Resources.maxVertexAttribs = value;
394 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
395 Resources.maxVertexUniformComponents = value;
396 else if (strcmp(token, "MaxVaryingFloats") == 0)
397 Resources.maxVaryingFloats = value;
398 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
399 Resources.maxVertexTextureImageUnits = value;
400 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
401 Resources.maxCombinedTextureImageUnits = value;
402 else if (strcmp(token, "MaxTextureImageUnits") == 0)
403 Resources.maxTextureImageUnits = value;
404 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
405 Resources.maxFragmentUniformComponents = value;
406 else if (strcmp(token, "MaxDrawBuffers") == 0)
407 Resources.maxDrawBuffers = value;
408 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
409 Resources.maxVertexUniformVectors = value;
410 else if (strcmp(token, "MaxVaryingVectors") == 0)
411 Resources.maxVaryingVectors = value;
412 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
413 Resources.maxFragmentUniformVectors = value;
414 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
415 Resources.maxVertexOutputVectors = value;
416 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
417 Resources.maxFragmentInputVectors = value;
418 else if (strcmp(token, "MinProgramTexelOffset") == 0)
419 Resources.minProgramTexelOffset = value;
420 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
421 Resources.maxProgramTexelOffset = value;
422 else if (strcmp(token, "MaxClipDistances") == 0)
423 Resources.maxClipDistances = value;
424 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
425 Resources.maxComputeWorkGroupCountX = value;
426 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
427 Resources.maxComputeWorkGroupCountY = value;
428 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
429 Resources.maxComputeWorkGroupCountZ = value;
430 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
431 Resources.maxComputeWorkGroupSizeX = value;
432 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
433 Resources.maxComputeWorkGroupSizeY = value;
434 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
435 Resources.maxComputeWorkGroupSizeZ = value;
436 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
437 Resources.maxComputeUniformComponents = value;
438 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
439 Resources.maxComputeTextureImageUnits = value;
440 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
441 Resources.maxComputeImageUniforms = value;
442 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
443 Resources.maxComputeAtomicCounters = value;
444 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
445 Resources.maxComputeAtomicCounterBuffers = value;
446 else if (strcmp(token, "MaxVaryingComponents") == 0)
447 Resources.maxVaryingComponents = value;
448 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
449 Resources.maxVertexOutputComponents = value;
450 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
451 Resources.maxGeometryInputComponents = value;
452 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
453 Resources.maxGeometryOutputComponents = value;
454 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
455 Resources.maxFragmentInputComponents = value;
456 else if (strcmp(token, "MaxImageUnits") == 0)
457 Resources.maxImageUnits = value;
458 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
459 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
460 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
461 Resources.maxCombinedShaderOutputResources = value;
462 else if (strcmp(token, "MaxImageSamples") == 0)
463 Resources.maxImageSamples = value;
464 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
465 Resources.maxVertexImageUniforms = value;
466 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
467 Resources.maxTessControlImageUniforms = value;
468 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
469 Resources.maxTessEvaluationImageUniforms = value;
470 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
471 Resources.maxGeometryImageUniforms = value;
472 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
473 Resources.maxFragmentImageUniforms = value;
474 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
475 Resources.maxCombinedImageUniforms = value;
476 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
477 Resources.maxGeometryTextureImageUnits = value;
478 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
479 Resources.maxGeometryOutputVertices = value;
480 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
481 Resources.maxGeometryTotalOutputComponents = value;
482 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
483 Resources.maxGeometryUniformComponents = value;
484 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
485 Resources.maxGeometryVaryingComponents = value;
486 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
487 Resources.maxTessControlInputComponents = value;
488 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
489 Resources.maxTessControlOutputComponents = value;
490 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
491 Resources.maxTessControlTextureImageUnits = value;
492 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
493 Resources.maxTessControlUniformComponents = value;
494 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
495 Resources.maxTessControlTotalOutputComponents = value;
496 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
497 Resources.maxTessEvaluationInputComponents = value;
498 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
499 Resources.maxTessEvaluationOutputComponents = value;
500 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
501 Resources.maxTessEvaluationTextureImageUnits = value;
502 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
503 Resources.maxTessEvaluationUniformComponents = value;
504 else if (strcmp(token, "MaxTessPatchComponents") == 0)
505 Resources.maxTessPatchComponents = value;
506 else if (strcmp(token, "MaxPatchVertices") == 0)
507 Resources.maxPatchVertices = value;
508 else if (strcmp(token, "MaxTessGenLevel") == 0)
509 Resources.maxTessGenLevel = value;
510 else if (strcmp(token, "MaxViewports") == 0)
511 Resources.maxViewports = value;
512 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
513 Resources.maxVertexAtomicCounters = value;
514 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
515 Resources.maxTessControlAtomicCounters = value;
516 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
517 Resources.maxTessEvaluationAtomicCounters = value;
518 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
519 Resources.maxGeometryAtomicCounters = value;
520 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
521 Resources.maxFragmentAtomicCounters = value;
522 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
523 Resources.maxCombinedAtomicCounters = value;
524 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
525 Resources.maxAtomicCounterBindings = value;
526 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
527 Resources.maxVertexAtomicCounterBuffers = value;
528 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
529 Resources.maxTessControlAtomicCounterBuffers = value;
530 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
531 Resources.maxTessEvaluationAtomicCounterBuffers = value;
532 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
533 Resources.maxGeometryAtomicCounterBuffers = value;
534 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
535 Resources.maxFragmentAtomicCounterBuffers = value;
536 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
537 Resources.maxCombinedAtomicCounterBuffers = value;
538 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
539 Resources.maxAtomicCounterBufferSize = value;
540 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
541 Resources.maxTransformFeedbackBuffers = value;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600542 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600543 Resources.maxTransformFeedbackInterleavedComponents = value;
544 else if (strcmp(token, "MaxCullDistances") == 0)
545 Resources.maxCullDistances = value;
546 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
547 Resources.maxCombinedClipAndCullDistances = value;
548 else if (strcmp(token, "MaxSamples") == 0)
549 Resources.maxSamples = value;
Jeff Bolzc5d1c012018-09-21 09:02:15 -0500550 else if (strcmp(token, "MaxMeshOutputVerticesNV") == 0)
551 Resources.maxMeshOutputVerticesNV = value;
552 else if (strcmp(token, "MaxMeshOutputPrimitivesNV") == 0)
553 Resources.maxMeshOutputPrimitivesNV = value;
554 else if (strcmp(token, "MaxMeshWorkGroupSizeX_NV") == 0)
555 Resources.maxMeshWorkGroupSizeX_NV = value;
556 else if (strcmp(token, "MaxMeshWorkGroupSizeY_NV") == 0)
557 Resources.maxMeshWorkGroupSizeY_NV = value;
558 else if (strcmp(token, "MaxMeshWorkGroupSizeZ_NV") == 0)
559 Resources.maxMeshWorkGroupSizeZ_NV = value;
560 else if (strcmp(token, "MaxTaskWorkGroupSizeX_NV") == 0)
561 Resources.maxTaskWorkGroupSizeX_NV = value;
562 else if (strcmp(token, "MaxTaskWorkGroupSizeY_NV") == 0)
563 Resources.maxTaskWorkGroupSizeY_NV = value;
564 else if (strcmp(token, "MaxTaskWorkGroupSizeZ_NV") == 0)
565 Resources.maxTaskWorkGroupSizeZ_NV = value;
566 else if (strcmp(token, "MaxMeshViewCountNV") == 0)
567 Resources.maxMeshViewCountNV = value;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600568
569 else if (strcmp(token, "nonInductiveForLoops") == 0)
570 Resources.limits.nonInductiveForLoops = (value != 0);
571 else if (strcmp(token, "whileLoops") == 0)
572 Resources.limits.whileLoops = (value != 0);
573 else if (strcmp(token, "doWhileLoops") == 0)
574 Resources.limits.doWhileLoops = (value != 0);
575 else if (strcmp(token, "generalUniformIndexing") == 0)
576 Resources.limits.generalUniformIndexing = (value != 0);
577 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600578 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600579 else if (strcmp(token, "generalVaryingIndexing") == 0)
580 Resources.limits.generalVaryingIndexing = (value != 0);
581 else if (strcmp(token, "generalSamplerIndexing") == 0)
582 Resources.limits.generalSamplerIndexing = (value != 0);
583 else if (strcmp(token, "generalVariableIndexing") == 0)
584 Resources.limits.generalVariableIndexing = (value != 0);
585 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
586 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
587 else
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600588 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600589
590 token = strtok(0, delims);
591 }
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700592 if (configStrings) FreeFileData(configStrings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600593}
594
Karl Schultz6addd812016-02-02 17:17:23 -0700595void VkTestFramework::SetMessageOptions(EShMessages &messages) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700596 if (m_compile_options & EOptionRelaxedErrors) messages = (EShMessages)(messages | EShMsgRelaxedErrors);
597 if (m_compile_options & EOptionIntermediate) messages = (EShMessages)(messages | EShMsgAST);
598 if (m_compile_options & EOptionSuppressWarnings) messages = (EShMessages)(messages | EShMsgSuppressWarnings);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600599}
600
601//
602// Malloc a string of sufficient size and read a string into it.
603//
Karl Schultz6addd812016-02-02 17:17:23 -0700604char **VkTestFramework::ReadFileData(const char *fileName) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600605 FILE *in;
Karl Schultz6addd812016-02-02 17:17:23 -0700606#if defined(_WIN32) && defined(__GNUC__)
607 in = fopen(fileName, "r");
608 int errorCode = in ? 0 : 1;
609#else
610 int errorCode = fopen_s(&in, fileName, "r");
611#endif
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600612
613 char *fdata;
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600614 size_t count = 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600615 const int maxSourceStrings = 5;
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600616 char **return_data = (char **)malloc(sizeof(char *) * (maxSourceStrings + 1));
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600617
618 if (errorCode) {
619 printf("Error: unable to open input file: %s\n", fileName);
620 return 0;
621 }
622
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700623 while (fgetc(in) != EOF) count++;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600624
625 fseek(in, 0, SEEK_SET);
626
Karl Schultz6addd812016-02-02 17:17:23 -0700627 if (!(fdata = (char *)malloc(count + 2))) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600628 printf("Error allocating memory\n");
629 return 0;
630 }
Karl Schultz6addd812016-02-02 17:17:23 -0700631 if (fread(fdata, 1, count, in) != count) {
632 printf("Error reading input file: %s\n", fileName);
633 return 0;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600634 }
635 fdata[count] = '\0';
636 fclose(in);
637 if (count == 0) {
Karl Schultz6addd812016-02-02 17:17:23 -0700638 return_data[0] = (char *)malloc(count + 2);
639 return_data[0][0] = '\0';
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600640 m_num_shader_strings = 0;
641 return return_data;
642 } else
643 m_num_shader_strings = 1;
644
Jeremy Hayes3b2a3a32016-06-21 11:05:08 -0600645 size_t len = (int)(ceil)((float)count / (float)m_num_shader_strings);
646 size_t ptr_len = 0, i = 0;
Karl Schultz6addd812016-02-02 17:17:23 -0700647 while (count > 0) {
648 return_data[i] = (char *)malloc(len + 2);
649 memcpy(return_data[i], fdata + ptr_len, len);
650 return_data[i][len] = '\0';
651 count -= (len);
652 ptr_len += (len);
653 if (count < len) {
654 if (count == 0) {
655 m_num_shader_strings = (i + 1);
656 break;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600657 }
Karl Schultz6addd812016-02-02 17:17:23 -0700658 len = count;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600659 }
660 ++i;
661 }
662 return return_data;
663}
664
Karl Schultz6addd812016-02-02 17:17:23 -0700665void VkTestFramework::FreeFileData(char **data) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700666 for (int i = 0; i < m_num_shader_strings; i++) free(data[i]);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600667}
668
669//
670// Deduce the language from the filename. Files must end in one of the
671// following extensions:
672//
673// .vert = vertex
674// .tesc = tessellation control
675// .tese = tessellation evaluation
676// .geom = geometry
677// .frag = fragment
678// .comp = compute
679//
Karl Schultz6addd812016-02-02 17:17:23 -0700680EShLanguage VkTestFramework::FindLanguage(const std::string &name) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600681 size_t ext = name.rfind('.');
682 if (ext == std::string::npos) {
683 return EShLangVertex;
684 }
685
686 std::string suffix = name.substr(ext + 1, std::string::npos);
687 if (suffix == "vert")
688 return EShLangVertex;
689 else if (suffix == "tesc")
690 return EShLangTessControl;
691 else if (suffix == "tese")
692 return EShLangTessEvaluation;
693 else if (suffix == "geom")
694 return EShLangGeometry;
695 else if (suffix == "frag")
696 return EShLangFragment;
697 else if (suffix == "comp")
698 return EShLangCompute;
699
700 return EShLangVertex;
701}
702
703//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600704// Convert VK shader type to compiler's
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600705//
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600706EShLanguage VkTestFramework::FindLanguage(const VkShaderStageFlagBits shader_type) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600707 switch (shader_type) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700708 case VK_SHADER_STAGE_VERTEX_BIT:
709 return EShLangVertex;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600710
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700711 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
712 return EShLangTessControl;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600713
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700714 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
715 return EShLangTessEvaluation;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600716
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700717 case VK_SHADER_STAGE_GEOMETRY_BIT:
718 return EShLangGeometry;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600719
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700720 case VK_SHADER_STAGE_FRAGMENT_BIT:
721 return EShLangFragment;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600722
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700723 case VK_SHADER_STAGE_COMPUTE_BIT:
724 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600725
Jeff Bolzd3f98d22018-12-13 23:53:11 -0600726 case VK_SHADER_STAGE_RAYGEN_BIT_NV:
727 return EShLangRayGenNV;
728
729 case VK_SHADER_STAGE_ANY_HIT_BIT_NV:
730 return EShLangAnyHitNV;
731
732 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
733 return EShLangClosestHitNV;
734
735 case VK_SHADER_STAGE_MISS_BIT_NV:
736 return EShLangMissNV;
737
738 case VK_SHADER_STAGE_INTERSECTION_BIT_NV:
739 return EShLangIntersectNV;
740
741 case VK_SHADER_STAGE_CALLABLE_BIT_NV:
742 return EShLangCallableNV;
743
744 case VK_SHADER_STAGE_TASK_BIT_NV:
745 return EShLangTaskNV;
746
747 case VK_SHADER_STAGE_MESH_BIT_NV:
748 return EShLangMeshNV;
749
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700750 default:
751 return EShLangVertex;
Chia-I Wub4c2aa42014-12-15 23:50:11 +0800752 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600753}
754
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600755//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600756// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600757// Return value of false means an error was encountered.
758//
Karl Schultz9d09ee92018-10-19 14:31:49 -0600759bool VkTestFramework::GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<unsigned int> &spirv,
Jeff Bolz49d64982019-09-18 13:18:14 -0500760 bool debug, uint32_t spirv_minor_version) {
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600761 glslang::TProgram program;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600762 const char *shaderStrings[1];
763
764 // TODO: Do we want to load a special config file depending on the
765 // shader source? Optional name maybe?
766 // SetConfigFile(fileName);
767
768 ProcessConfigFile();
769
770 EShMessages messages = EShMsgDefault;
771 SetMessageOptions(messages);
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600772 messages = static_cast<EShMessages>(messages | EShMsgSpvRules | EShMsgVulkanRules);
Karl Schultz9d09ee92018-10-19 14:31:49 -0600773 if (debug) {
774 messages = static_cast<EShMessages>(messages | EShMsgDebugInfo);
775 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600776
777 EShLanguage stage = FindLanguage(shader_type);
Karl Schultz6addd812016-02-02 17:17:23 -0700778 glslang::TShader *shader = new glslang::TShader(stage);
Jeff Bolz49d64982019-09-18 13:18:14 -0500779 switch (spirv_minor_version) {
780 default:
781 case 0:
782 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
783 break;
784 case 1:
785 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_1);
786 break;
787 case 2:
788 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_2);
789 break;
790 case 3:
791 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
792 break;
793 case 4:
794 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_4);
795 break;
796 case 5:
797 shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
798 break;
799 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600800
801 shaderStrings[0] = pshader;
802 shader->setStrings(shaderStrings, 1);
803
Mark Lobodzinskic6a62142016-09-07 16:35:55 -0600804 if (!shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700805 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700806 puts(shader->getInfoLog());
807 puts(shader->getInfoDebugLog());
808 }
809
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700810 return false; // something didn't work
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600811 }
812
813 program.addShader(shader);
814
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600815 //
816 // Program-level processing...
817 //
818
Karl Schultz6addd812016-02-02 17:17:23 -0700819 if (!program.link(messages)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700820 if (!(m_compile_options & EOptionSuppressInfolog)) {
Cody Northrop195d6622014-11-03 12:54:37 -0700821 puts(shader->getInfoLog());
822 puts(shader->getInfoDebugLog());
823 }
824
825 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600826 }
827
828 if (m_compile_options & EOptionDumpReflection) {
829 program.buildReflection();
830 program.dumpReflection();
831 }
832
Karl Schultz9d09ee92018-10-19 14:31:49 -0600833 glslang::SpvOptions spv_options;
834 if (debug) {
835 spv_options.generateDebugInfo = true;
836 }
837 glslang::GlslangToSpv(*program.getIntermediate(stage), spirv, &spv_options);
Cody Northrop5a95b472015-06-03 13:01:54 -0600838
839 //
840 // Test the different modes of SPIR-V modification
841 //
842 if (this->m_canonicalize_spv) {
843 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
844 }
845
846 if (this->m_strip_spv) {
847 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
848 }
849
850 if (this->m_do_everything_spv) {
851 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
852 }
853
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -0600854 delete shader;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600855
856 return true;
857}
Karl Schultz23707622018-08-22 10:20:33 -0600858
859//
860// Compile a given string containing SPIR-V assembly into SPV for use by VK
861// Return value of false means an error was encountered.
862//
863bool VkTestFramework::ASMtoSPV(const spv_target_env target_env, const uint32_t options, const char *pasm,
864 std::vector<unsigned int> &spv) {
865 spv_binary binary;
866 spv_diagnostic diagnostic = nullptr;
867 spv_context context = spvContextCreate(target_env);
868 spv_result_t error = spvTextToBinaryWithOptions(context, pasm, strlen(pasm), options, &binary, &diagnostic);
869 spvContextDestroy(context);
870 if (error) {
871 spvDiagnosticPrint(diagnostic);
872 spvDiagnosticDestroy(diagnostic);
873 return false;
874 }
875 spv.insert(spv.end(), binary->code, binary->code + binary->wordCount);
876 spvBinaryDestroy(binary);
877
878 return true;
879}