xref: /aosp_15_r20/external/vulkan-validation-layers/tests/vktestframework.cpp (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1*b7893ccfSSadaf Ebrahimi /*
2*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 The Khronos Group Inc.
3*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 Valve Corporation
4*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 LunarG, Inc.
5*b7893ccfSSadaf Ebrahimi  *
6*b7893ccfSSadaf Ebrahimi  * Licensed under the Apache License, Version 2.0 (the "License");
7*b7893ccfSSadaf Ebrahimi  * you may not use this file except in compliance with the License.
8*b7893ccfSSadaf Ebrahimi  * You may obtain a copy of the License at
9*b7893ccfSSadaf Ebrahimi  *
10*b7893ccfSSadaf Ebrahimi  *     http://www.apache.org/licenses/LICENSE-2.0
11*b7893ccfSSadaf Ebrahimi  *
12*b7893ccfSSadaf Ebrahimi  * Unless required by applicable law or agreed to in writing, software
13*b7893ccfSSadaf Ebrahimi  * distributed under the License is distributed on an "AS IS" BASIS,
14*b7893ccfSSadaf Ebrahimi  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*b7893ccfSSadaf Ebrahimi  * See the License for the specific language governing permissions and
16*b7893ccfSSadaf Ebrahimi  * limitations under the License.
17*b7893ccfSSadaf Ebrahimi  *
18*b7893ccfSSadaf Ebrahimi  * Author: Chia-I Wu <[email protected]>
19*b7893ccfSSadaf Ebrahimi  * Author: Courtney Goeltzenleuchter <[email protected]>
20*b7893ccfSSadaf Ebrahimi  * Author: Tony Barbour <[email protected]>
21*b7893ccfSSadaf Ebrahimi  */
22*b7893ccfSSadaf Ebrahimi 
23*b7893ccfSSadaf Ebrahimi #include "vktestframework.h"
24*b7893ccfSSadaf Ebrahimi #include "vkrenderframework.h"
25*b7893ccfSSadaf Ebrahimi 
26*b7893ccfSSadaf Ebrahimi // For versions prior to VS 2015, suppress the warning
27*b7893ccfSSadaf Ebrahimi // caused by the inconsistent redefinition of snprintf
28*b7893ccfSSadaf Ebrahimi // between a vulkan header and a glslang header.
29*b7893ccfSSadaf Ebrahimi #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
30*b7893ccfSSadaf Ebrahimi #pragma warning(push)
31*b7893ccfSSadaf Ebrahimi #pragma warning(disable : 4005)
32*b7893ccfSSadaf Ebrahimi #endif
33*b7893ccfSSadaf Ebrahimi // TODO FIXME remove this once glslang doesn't define this
34*b7893ccfSSadaf Ebrahimi #undef BadValue
35*b7893ccfSSadaf Ebrahimi #include "SPIRV/GlslangToSpv.h"
36*b7893ccfSSadaf Ebrahimi #include "SPIRV/SPVRemapper.h"
37*b7893ccfSSadaf Ebrahimi #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
38*b7893ccfSSadaf Ebrahimi #pragma warning(pop)
39*b7893ccfSSadaf Ebrahimi #endif
40*b7893ccfSSadaf Ebrahimi #include <limits.h>
41*b7893ccfSSadaf Ebrahimi #include <math.h>
42*b7893ccfSSadaf Ebrahimi 
43*b7893ccfSSadaf Ebrahimi #if defined(PATH_MAX) && !defined(MAX_PATH)
44*b7893ccfSSadaf Ebrahimi #define MAX_PATH PATH_MAX
45*b7893ccfSSadaf Ebrahimi #endif
46*b7893ccfSSadaf Ebrahimi 
47*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
48*b7893ccfSSadaf Ebrahimi #define ERR_EXIT(err_msg, err_class)                 \
49*b7893ccfSSadaf Ebrahimi     do {                                             \
50*b7893ccfSSadaf Ebrahimi         MessageBox(NULL, err_msg, err_class, MB_OK); \
51*b7893ccfSSadaf Ebrahimi         exit(1);                                     \
52*b7893ccfSSadaf Ebrahimi     } while (0)
53*b7893ccfSSadaf Ebrahimi #else  // _WIN32
54*b7893ccfSSadaf Ebrahimi 
55*b7893ccfSSadaf Ebrahimi #define ERR_EXIT(err_msg, err_class) \
56*b7893ccfSSadaf Ebrahimi     do {                             \
57*b7893ccfSSadaf Ebrahimi         printf(err_msg);             \
58*b7893ccfSSadaf Ebrahimi         fflush(stdout);              \
59*b7893ccfSSadaf Ebrahimi         exit(1);                     \
60*b7893ccfSSadaf Ebrahimi     } while (0)
61*b7893ccfSSadaf Ebrahimi #endif  // _WIN32
62*b7893ccfSSadaf Ebrahimi 
63*b7893ccfSSadaf Ebrahimi #define GET_INSTANCE_PROC_ADDR(inst, entrypoint)                                                              \
64*b7893ccfSSadaf Ebrahimi     {                                                                                                         \
65*b7893ccfSSadaf Ebrahimi         m_fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint);                 \
66*b7893ccfSSadaf Ebrahimi         if (m_fp##entrypoint == NULL) {                                                                       \
67*b7893ccfSSadaf Ebrahimi             ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, "vkGetInstanceProcAddr Failure"); \
68*b7893ccfSSadaf Ebrahimi         }                                                                                                     \
69*b7893ccfSSadaf Ebrahimi     }
70*b7893ccfSSadaf Ebrahimi 
71*b7893ccfSSadaf Ebrahimi #define GET_DEVICE_PROC_ADDR(dev, entrypoint)                                                             \
72*b7893ccfSSadaf Ebrahimi     {                                                                                                     \
73*b7893ccfSSadaf Ebrahimi         m_fp##entrypoint = (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint);                \
74*b7893ccfSSadaf Ebrahimi         if (m_fp##entrypoint == NULL) {                                                                   \
75*b7893ccfSSadaf Ebrahimi             ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint, "vkGetDeviceProcAddr Failure"); \
76*b7893ccfSSadaf Ebrahimi         }                                                                                                 \
77*b7893ccfSSadaf Ebrahimi     }
78*b7893ccfSSadaf Ebrahimi 
79*b7893ccfSSadaf Ebrahimi // Command-line options
80*b7893ccfSSadaf Ebrahimi enum TOptions {
81*b7893ccfSSadaf Ebrahimi     EOptionNone = 0x000,
82*b7893ccfSSadaf Ebrahimi     EOptionIntermediate = 0x001,
83*b7893ccfSSadaf Ebrahimi     EOptionSuppressInfolog = 0x002,
84*b7893ccfSSadaf Ebrahimi     EOptionMemoryLeakMode = 0x004,
85*b7893ccfSSadaf Ebrahimi     EOptionRelaxedErrors = 0x008,
86*b7893ccfSSadaf Ebrahimi     EOptionGiveWarnings = 0x010,
87*b7893ccfSSadaf Ebrahimi     EOptionLinkProgram = 0x020,
88*b7893ccfSSadaf Ebrahimi     EOptionMultiThreaded = 0x040,
89*b7893ccfSSadaf Ebrahimi     EOptionDumpConfig = 0x080,
90*b7893ccfSSadaf Ebrahimi     EOptionDumpReflection = 0x100,
91*b7893ccfSSadaf Ebrahimi     EOptionSuppressWarnings = 0x200,
92*b7893ccfSSadaf Ebrahimi     EOptionDumpVersions = 0x400,
93*b7893ccfSSadaf Ebrahimi     EOptionSpv = 0x800,
94*b7893ccfSSadaf Ebrahimi     EOptionDefaultDesktop = 0x1000,
95*b7893ccfSSadaf Ebrahimi };
96*b7893ccfSSadaf Ebrahimi 
97*b7893ccfSSadaf Ebrahimi struct SwapchainBuffers {
98*b7893ccfSSadaf Ebrahimi     VkImage image;
99*b7893ccfSSadaf Ebrahimi     VkCommandBuffer cmd;
100*b7893ccfSSadaf Ebrahimi     VkImageView view;
101*b7893ccfSSadaf Ebrahimi };
102*b7893ccfSSadaf Ebrahimi 
103*b7893ccfSSadaf Ebrahimi #ifndef _WIN32
104*b7893ccfSSadaf Ebrahimi 
105*b7893ccfSSadaf Ebrahimi #include <errno.h>
106*b7893ccfSSadaf Ebrahimi 
fopen_s(FILE ** pFile,const char * filename,const char * mode)107*b7893ccfSSadaf Ebrahimi int fopen_s(FILE **pFile, const char *filename, const char *mode) {
108*b7893ccfSSadaf Ebrahimi     if (!pFile || !filename || !mode) {
109*b7893ccfSSadaf Ebrahimi         return EINVAL;
110*b7893ccfSSadaf Ebrahimi     }
111*b7893ccfSSadaf Ebrahimi 
112*b7893ccfSSadaf Ebrahimi     FILE *f = fopen(filename, mode);
113*b7893ccfSSadaf Ebrahimi     if (!f) {
114*b7893ccfSSadaf Ebrahimi         if (errno != 0) {
115*b7893ccfSSadaf Ebrahimi             return errno;
116*b7893ccfSSadaf Ebrahimi         } else {
117*b7893ccfSSadaf Ebrahimi             return ENOENT;
118*b7893ccfSSadaf Ebrahimi         }
119*b7893ccfSSadaf Ebrahimi     }
120*b7893ccfSSadaf Ebrahimi     *pFile = f;
121*b7893ccfSSadaf Ebrahimi 
122*b7893ccfSSadaf Ebrahimi     return 0;
123*b7893ccfSSadaf Ebrahimi }
124*b7893ccfSSadaf Ebrahimi 
125*b7893ccfSSadaf Ebrahimi #endif
126*b7893ccfSSadaf Ebrahimi 
127*b7893ccfSSadaf Ebrahimi // Set up environment for GLSL compiler
128*b7893ccfSSadaf Ebrahimi // Must be done once per process
SetUp()129*b7893ccfSSadaf Ebrahimi void TestEnvironment::SetUp() {
130*b7893ccfSSadaf Ebrahimi     // Initialize GLSL to SPV compiler utility
131*b7893ccfSSadaf Ebrahimi     glslang::InitializeProcess();
132*b7893ccfSSadaf Ebrahimi 
133*b7893ccfSSadaf Ebrahimi     vk_testing::set_error_callback(test_error_callback);
134*b7893ccfSSadaf Ebrahimi }
135*b7893ccfSSadaf Ebrahimi 
TearDown()136*b7893ccfSSadaf Ebrahimi void TestEnvironment::TearDown() { glslang::FinalizeProcess(); }
137*b7893ccfSSadaf Ebrahimi 
VkTestFramework()138*b7893ccfSSadaf Ebrahimi VkTestFramework::VkTestFramework() : m_compile_options(0), m_num_shader_strings(0) {}
139*b7893ccfSSadaf Ebrahimi 
~VkTestFramework()140*b7893ccfSSadaf Ebrahimi VkTestFramework::~VkTestFramework() {}
141*b7893ccfSSadaf Ebrahimi 
142*b7893ccfSSadaf Ebrahimi // Define all the static elements
143*b7893ccfSSadaf Ebrahimi bool VkTestFramework::m_canonicalize_spv = false;
144*b7893ccfSSadaf Ebrahimi bool VkTestFramework::m_strip_spv = false;
145*b7893ccfSSadaf Ebrahimi bool VkTestFramework::m_do_everything_spv = false;
146*b7893ccfSSadaf Ebrahimi bool VkTestFramework::m_devsim_layer = false;
147*b7893ccfSSadaf Ebrahimi bool VkTestFramework::m_khronos_layer_disable = false;
148*b7893ccfSSadaf Ebrahimi int VkTestFramework::m_width = 0;
149*b7893ccfSSadaf Ebrahimi int VkTestFramework::m_height = 0;
150*b7893ccfSSadaf Ebrahimi 
optionMatch(const char * option,char * optionLine)151*b7893ccfSSadaf Ebrahimi bool VkTestFramework::optionMatch(const char *option, char *optionLine) {
152*b7893ccfSSadaf Ebrahimi     if (strncmp(option, optionLine, strlen(option)) == 0)
153*b7893ccfSSadaf Ebrahimi         return true;
154*b7893ccfSSadaf Ebrahimi     else
155*b7893ccfSSadaf Ebrahimi         return false;
156*b7893ccfSSadaf Ebrahimi }
157*b7893ccfSSadaf Ebrahimi 
InitArgs(int * argc,char * argv[])158*b7893ccfSSadaf Ebrahimi void VkTestFramework::InitArgs(int *argc, char *argv[]) {
159*b7893ccfSSadaf Ebrahimi     int i, n;
160*b7893ccfSSadaf Ebrahimi 
161*b7893ccfSSadaf Ebrahimi     for (i = 1, n = 1; i < *argc; i++) {
162*b7893ccfSSadaf Ebrahimi         if (optionMatch("--strip-SPV", argv[i]))
163*b7893ccfSSadaf Ebrahimi             m_strip_spv = true;
164*b7893ccfSSadaf Ebrahimi         else if (optionMatch("--canonicalize-SPV", argv[i]))
165*b7893ccfSSadaf Ebrahimi             m_canonicalize_spv = true;
166*b7893ccfSSadaf Ebrahimi         else if (optionMatch("--devsim", argv[i]))
167*b7893ccfSSadaf Ebrahimi             m_devsim_layer = true;
168*b7893ccfSSadaf Ebrahimi         else if (optionMatch("--disable_uberlayer", argv[i]))
169*b7893ccfSSadaf Ebrahimi             m_khronos_layer_disable = true;
170*b7893ccfSSadaf Ebrahimi         else if (optionMatch("--help", argv[i]) || optionMatch("-h", argv[i])) {
171*b7893ccfSSadaf Ebrahimi             printf("\nOther options:\n");
172*b7893ccfSSadaf Ebrahimi             printf(
173*b7893ccfSSadaf Ebrahimi                 "\t--show-images\n"
174*b7893ccfSSadaf Ebrahimi                 "\t\tDisplay test images in viewer after tests complete.\n");
175*b7893ccfSSadaf Ebrahimi             printf(
176*b7893ccfSSadaf Ebrahimi                 "\t--save-images\n"
177*b7893ccfSSadaf Ebrahimi                 "\t\tSave tests images as ppm files in current working directory.\n"
178*b7893ccfSSadaf Ebrahimi                 "\t\tUsed to generate golden images for compare-images.\n");
179*b7893ccfSSadaf Ebrahimi             printf(
180*b7893ccfSSadaf Ebrahimi                 "\t--compare-images\n"
181*b7893ccfSSadaf Ebrahimi                 "\t\tCompare test images to 'golden' image in golden folder.\n"
182*b7893ccfSSadaf Ebrahimi                 "\t\tAlso saves the generated test image in current working\n"
183*b7893ccfSSadaf Ebrahimi                 "\t\t\tdirectory but only if the image is different from the golden\n"
184*b7893ccfSSadaf Ebrahimi                 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
185*b7893ccfSSadaf Ebrahimi                 "\t\t\tdifferent directory for golden images\n"
186*b7893ccfSSadaf Ebrahimi                 "\t\tSignal test failure if different.\n");
187*b7893ccfSSadaf Ebrahimi             printf(
188*b7893ccfSSadaf Ebrahimi                 "\t--no-SPV\n"
189*b7893ccfSSadaf Ebrahimi                 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
190*b7893ccfSSadaf Ebrahimi             printf(
191*b7893ccfSSadaf Ebrahimi                 "\t--strip-SPV\n"
192*b7893ccfSSadaf Ebrahimi                 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
193*b7893ccfSSadaf Ebrahimi             printf(
194*b7893ccfSSadaf Ebrahimi                 "\t--canonicalize-SPV\n"
195*b7893ccfSSadaf Ebrahimi                 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
196*b7893ccfSSadaf Ebrahimi             exit(0);
197*b7893ccfSSadaf Ebrahimi         } else {
198*b7893ccfSSadaf Ebrahimi             printf("\nUnrecognized option: %s\n", argv[i]);
199*b7893ccfSSadaf Ebrahimi             printf("\nUse --help or -h for option list.\n");
200*b7893ccfSSadaf Ebrahimi             exit(0);
201*b7893ccfSSadaf Ebrahimi         }
202*b7893ccfSSadaf Ebrahimi 
203*b7893ccfSSadaf Ebrahimi         /*
204*b7893ccfSSadaf Ebrahimi          * Since the above "consume" inputs, update argv
205*b7893ccfSSadaf Ebrahimi          * so that it contains the trimmed list of args for glutInit
206*b7893ccfSSadaf Ebrahimi          */
207*b7893ccfSSadaf Ebrahimi 
208*b7893ccfSSadaf Ebrahimi         argv[n] = argv[i];
209*b7893ccfSSadaf Ebrahimi         n++;
210*b7893ccfSSadaf Ebrahimi     }
211*b7893ccfSSadaf Ebrahimi }
212*b7893ccfSSadaf Ebrahimi 
GetFormat(VkInstance instance,vk_testing::Device * device)213*b7893ccfSSadaf Ebrahimi VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device) {
214*b7893ccfSSadaf Ebrahimi     VkFormatProperties format_props;
215*b7893ccfSSadaf Ebrahimi 
216*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
217*b7893ccfSSadaf Ebrahimi     if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
218*b7893ccfSSadaf Ebrahimi         format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
219*b7893ccfSSadaf Ebrahimi         return VK_FORMAT_B8G8R8A8_UNORM;
220*b7893ccfSSadaf Ebrahimi     }
221*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
222*b7893ccfSSadaf Ebrahimi     if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
223*b7893ccfSSadaf Ebrahimi         format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
224*b7893ccfSSadaf Ebrahimi         return VK_FORMAT_R8G8B8A8_UNORM;
225*b7893ccfSSadaf Ebrahimi     }
226*b7893ccfSSadaf Ebrahimi     printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
227*b7893ccfSSadaf Ebrahimi     exit(1);
228*b7893ccfSSadaf Ebrahimi }
229*b7893ccfSSadaf Ebrahimi 
Finish()230*b7893ccfSSadaf Ebrahimi void VkTestFramework::Finish() {}
231*b7893ccfSSadaf Ebrahimi 
232*b7893ccfSSadaf Ebrahimi //
233*b7893ccfSSadaf Ebrahimi // These are the default resources for TBuiltInResources, used for both
234*b7893ccfSSadaf Ebrahimi //  - parsing this string for the case where the user didn't supply one
235*b7893ccfSSadaf Ebrahimi //  - dumping out a template for user construction of a config file
236*b7893ccfSSadaf Ebrahimi //
237*b7893ccfSSadaf Ebrahimi static const char *DefaultConfig =
238*b7893ccfSSadaf Ebrahimi     "MaxLights 32\n"
239*b7893ccfSSadaf Ebrahimi     "MaxClipPlanes 6\n"
240*b7893ccfSSadaf Ebrahimi     "MaxTextureUnits 32\n"
241*b7893ccfSSadaf Ebrahimi     "MaxTextureCoords 32\n"
242*b7893ccfSSadaf Ebrahimi     "MaxVertexAttribs 64\n"
243*b7893ccfSSadaf Ebrahimi     "MaxVertexUniformComponents 4096\n"
244*b7893ccfSSadaf Ebrahimi     "MaxVaryingFloats 64\n"
245*b7893ccfSSadaf Ebrahimi     "MaxVertexTextureImageUnits 32\n"
246*b7893ccfSSadaf Ebrahimi     "MaxCombinedTextureImageUnits 80\n"
247*b7893ccfSSadaf Ebrahimi     "MaxTextureImageUnits 32\n"
248*b7893ccfSSadaf Ebrahimi     "MaxFragmentUniformComponents 4096\n"
249*b7893ccfSSadaf Ebrahimi     "MaxDrawBuffers 32\n"
250*b7893ccfSSadaf Ebrahimi     "MaxVertexUniformVectors 128\n"
251*b7893ccfSSadaf Ebrahimi     "MaxVaryingVectors 8\n"
252*b7893ccfSSadaf Ebrahimi     "MaxFragmentUniformVectors 16\n"
253*b7893ccfSSadaf Ebrahimi     "MaxVertexOutputVectors 16\n"
254*b7893ccfSSadaf Ebrahimi     "MaxFragmentInputVectors 15\n"
255*b7893ccfSSadaf Ebrahimi     "MinProgramTexelOffset -8\n"
256*b7893ccfSSadaf Ebrahimi     "MaxProgramTexelOffset 7\n"
257*b7893ccfSSadaf Ebrahimi     "MaxClipDistances 8\n"
258*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupCountX 65535\n"
259*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupCountY 65535\n"
260*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupCountZ 65535\n"
261*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupSizeX 1024\n"
262*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupSizeY 1024\n"
263*b7893ccfSSadaf Ebrahimi     "MaxComputeWorkGroupSizeZ 64\n"
264*b7893ccfSSadaf Ebrahimi     "MaxComputeUniformComponents 1024\n"
265*b7893ccfSSadaf Ebrahimi     "MaxComputeTextureImageUnits 16\n"
266*b7893ccfSSadaf Ebrahimi     "MaxComputeImageUniforms 8\n"
267*b7893ccfSSadaf Ebrahimi     "MaxComputeAtomicCounters 8\n"
268*b7893ccfSSadaf Ebrahimi     "MaxComputeAtomicCounterBuffers 1\n"
269*b7893ccfSSadaf Ebrahimi     "MaxVaryingComponents 60\n"
270*b7893ccfSSadaf Ebrahimi     "MaxVertexOutputComponents 64\n"
271*b7893ccfSSadaf Ebrahimi     "MaxGeometryInputComponents 64\n"
272*b7893ccfSSadaf Ebrahimi     "MaxGeometryOutputComponents 128\n"
273*b7893ccfSSadaf Ebrahimi     "MaxFragmentInputComponents 128\n"
274*b7893ccfSSadaf Ebrahimi     "MaxImageUnits 8\n"
275*b7893ccfSSadaf Ebrahimi     "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
276*b7893ccfSSadaf Ebrahimi     "MaxCombinedShaderOutputResources 8\n"
277*b7893ccfSSadaf Ebrahimi     "MaxImageSamples 0\n"
278*b7893ccfSSadaf Ebrahimi     "MaxVertexImageUniforms 0\n"
279*b7893ccfSSadaf Ebrahimi     "MaxTessControlImageUniforms 0\n"
280*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationImageUniforms 0\n"
281*b7893ccfSSadaf Ebrahimi     "MaxGeometryImageUniforms 0\n"
282*b7893ccfSSadaf Ebrahimi     "MaxFragmentImageUniforms 8\n"
283*b7893ccfSSadaf Ebrahimi     "MaxCombinedImageUniforms 8\n"
284*b7893ccfSSadaf Ebrahimi     "MaxGeometryTextureImageUnits 16\n"
285*b7893ccfSSadaf Ebrahimi     "MaxGeometryOutputVertices 256\n"
286*b7893ccfSSadaf Ebrahimi     "MaxGeometryTotalOutputComponents 1024\n"
287*b7893ccfSSadaf Ebrahimi     "MaxGeometryUniformComponents 1024\n"
288*b7893ccfSSadaf Ebrahimi     "MaxGeometryVaryingComponents 64\n"
289*b7893ccfSSadaf Ebrahimi     "MaxTessControlInputComponents 128\n"
290*b7893ccfSSadaf Ebrahimi     "MaxTessControlOutputComponents 128\n"
291*b7893ccfSSadaf Ebrahimi     "MaxTessControlTextureImageUnits 16\n"
292*b7893ccfSSadaf Ebrahimi     "MaxTessControlUniformComponents 1024\n"
293*b7893ccfSSadaf Ebrahimi     "MaxTessControlTotalOutputComponents 4096\n"
294*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationInputComponents 128\n"
295*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationOutputComponents 128\n"
296*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationTextureImageUnits 16\n"
297*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationUniformComponents 1024\n"
298*b7893ccfSSadaf Ebrahimi     "MaxTessPatchComponents 120\n"
299*b7893ccfSSadaf Ebrahimi     "MaxPatchVertices 32\n"
300*b7893ccfSSadaf Ebrahimi     "MaxTessGenLevel 64\n"
301*b7893ccfSSadaf Ebrahimi     "MaxViewports 16\n"
302*b7893ccfSSadaf Ebrahimi     "MaxVertexAtomicCounters 0\n"
303*b7893ccfSSadaf Ebrahimi     "MaxTessControlAtomicCounters 0\n"
304*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationAtomicCounters 0\n"
305*b7893ccfSSadaf Ebrahimi     "MaxGeometryAtomicCounters 0\n"
306*b7893ccfSSadaf Ebrahimi     "MaxFragmentAtomicCounters 8\n"
307*b7893ccfSSadaf Ebrahimi     "MaxCombinedAtomicCounters 8\n"
308*b7893ccfSSadaf Ebrahimi     "MaxAtomicCounterBindings 1\n"
309*b7893ccfSSadaf Ebrahimi     "MaxVertexAtomicCounterBuffers 0\n"
310*b7893ccfSSadaf Ebrahimi     "MaxTessControlAtomicCounterBuffers 0\n"
311*b7893ccfSSadaf Ebrahimi     "MaxTessEvaluationAtomicCounterBuffers 0\n"
312*b7893ccfSSadaf Ebrahimi     "MaxGeometryAtomicCounterBuffers 0\n"
313*b7893ccfSSadaf Ebrahimi     "MaxFragmentAtomicCounterBuffers 1\n"
314*b7893ccfSSadaf Ebrahimi     "MaxCombinedAtomicCounterBuffers 1\n"
315*b7893ccfSSadaf Ebrahimi     "MaxAtomicCounterBufferSize 16384\n"
316*b7893ccfSSadaf Ebrahimi     "MaxTransformFeedbackBuffers 4\n"
317*b7893ccfSSadaf Ebrahimi     "MaxTransformFeedbackInterleavedComponents 64\n"
318*b7893ccfSSadaf Ebrahimi     "MaxCullDistances 8\n"
319*b7893ccfSSadaf Ebrahimi     "MaxCombinedClipAndCullDistances 8\n"
320*b7893ccfSSadaf Ebrahimi     "MaxSamples 4\n"
321*b7893ccfSSadaf Ebrahimi     "MaxMeshOutputVerticesNV 256\n"
322*b7893ccfSSadaf Ebrahimi     "MaxMeshOutputPrimitivesNV 512\n"
323*b7893ccfSSadaf Ebrahimi     "MaxMeshWorkGroupSizeX_NV 32\n"
324*b7893ccfSSadaf Ebrahimi     "MaxMeshWorkGroupSizeY_NV 1\n"
325*b7893ccfSSadaf Ebrahimi     "MaxMeshWorkGroupSizeZ_NV 1\n"
326*b7893ccfSSadaf Ebrahimi     "MaxTaskWorkGroupSizeX_NV 32\n"
327*b7893ccfSSadaf Ebrahimi     "MaxTaskWorkGroupSizeY_NV 1\n"
328*b7893ccfSSadaf Ebrahimi     "MaxTaskWorkGroupSizeZ_NV 1\n"
329*b7893ccfSSadaf Ebrahimi     "MaxMeshViewCountNV 4\n"
330*b7893ccfSSadaf Ebrahimi 
331*b7893ccfSSadaf Ebrahimi     "nonInductiveForLoops 1\n"
332*b7893ccfSSadaf Ebrahimi     "whileLoops 1\n"
333*b7893ccfSSadaf Ebrahimi     "doWhileLoops 1\n"
334*b7893ccfSSadaf Ebrahimi     "generalUniformIndexing 1\n"
335*b7893ccfSSadaf Ebrahimi     "generalAttributeMatrixVectorIndexing 1\n"
336*b7893ccfSSadaf Ebrahimi     "generalVaryingIndexing 1\n"
337*b7893ccfSSadaf Ebrahimi     "generalSamplerIndexing 1\n"
338*b7893ccfSSadaf Ebrahimi     "generalVariableIndexing 1\n"
339*b7893ccfSSadaf Ebrahimi     "generalConstantMatrixVectorIndexing 1\n";
340*b7893ccfSSadaf Ebrahimi 
341*b7893ccfSSadaf Ebrahimi //
342*b7893ccfSSadaf Ebrahimi // *.conf => this is a config file that can set limits/resources
343*b7893ccfSSadaf Ebrahimi //
SetConfigFile(const std::string & name)344*b7893ccfSSadaf Ebrahimi bool VkTestFramework::SetConfigFile(const std::string &name) {
345*b7893ccfSSadaf Ebrahimi     if (name.size() < 5) return false;
346*b7893ccfSSadaf Ebrahimi 
347*b7893ccfSSadaf Ebrahimi     if (name.compare(name.size() - 5, 5, ".conf") == 0) {
348*b7893ccfSSadaf Ebrahimi         ConfigFile = name;
349*b7893ccfSSadaf Ebrahimi         return true;
350*b7893ccfSSadaf Ebrahimi     }
351*b7893ccfSSadaf Ebrahimi 
352*b7893ccfSSadaf Ebrahimi     return false;
353*b7893ccfSSadaf Ebrahimi }
354*b7893ccfSSadaf Ebrahimi 
355*b7893ccfSSadaf Ebrahimi //
356*b7893ccfSSadaf Ebrahimi // Parse either a .conf file provided by the user or the default string above.
357*b7893ccfSSadaf Ebrahimi //
ProcessConfigFile()358*b7893ccfSSadaf Ebrahimi void VkTestFramework::ProcessConfigFile() {
359*b7893ccfSSadaf Ebrahimi     char **configStrings = 0;
360*b7893ccfSSadaf Ebrahimi     char *config = 0;
361*b7893ccfSSadaf Ebrahimi     if (ConfigFile.size() > 0) {
362*b7893ccfSSadaf Ebrahimi         configStrings = ReadFileData(ConfigFile.c_str());
363*b7893ccfSSadaf Ebrahimi         if (configStrings)
364*b7893ccfSSadaf Ebrahimi             config = *configStrings;
365*b7893ccfSSadaf Ebrahimi         else {
366*b7893ccfSSadaf Ebrahimi             printf("Error opening configuration file; will instead use the default configuration\n");
367*b7893ccfSSadaf Ebrahimi         }
368*b7893ccfSSadaf Ebrahimi     }
369*b7893ccfSSadaf Ebrahimi 
370*b7893ccfSSadaf Ebrahimi     if (config == 0) {
371*b7893ccfSSadaf Ebrahimi         config = (char *)alloca(strlen(DefaultConfig) + 1);
372*b7893ccfSSadaf Ebrahimi         strcpy(config, DefaultConfig);
373*b7893ccfSSadaf Ebrahimi     }
374*b7893ccfSSadaf Ebrahimi 
375*b7893ccfSSadaf Ebrahimi     const char *delims = " \t\n\r";
376*b7893ccfSSadaf Ebrahimi     const char *token = strtok(config, delims);
377*b7893ccfSSadaf Ebrahimi     while (token) {
378*b7893ccfSSadaf Ebrahimi         const char *valueStr = strtok(0, delims);
379*b7893ccfSSadaf Ebrahimi         if (valueStr == 0 || !(valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
380*b7893ccfSSadaf Ebrahimi             printf("Error: '%s' bad .conf file.  Each name must be followed by one number.\n", valueStr ? valueStr : "");
381*b7893ccfSSadaf Ebrahimi             return;
382*b7893ccfSSadaf Ebrahimi         }
383*b7893ccfSSadaf Ebrahimi         int value = atoi(valueStr);
384*b7893ccfSSadaf Ebrahimi 
385*b7893ccfSSadaf Ebrahimi         if (strcmp(token, "MaxLights") == 0)
386*b7893ccfSSadaf Ebrahimi             Resources.maxLights = value;
387*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxClipPlanes") == 0)
388*b7893ccfSSadaf Ebrahimi             Resources.maxClipPlanes = value;
389*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTextureUnits") == 0)
390*b7893ccfSSadaf Ebrahimi             Resources.maxTextureUnits = value;
391*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTextureCoords") == 0)
392*b7893ccfSSadaf Ebrahimi             Resources.maxTextureCoords = value;
393*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexAttribs") == 0)
394*b7893ccfSSadaf Ebrahimi             Resources.maxVertexAttribs = value;
395*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexUniformComponents") == 0)
396*b7893ccfSSadaf Ebrahimi             Resources.maxVertexUniformComponents = value;
397*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVaryingFloats") == 0)
398*b7893ccfSSadaf Ebrahimi             Resources.maxVaryingFloats = value;
399*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
400*b7893ccfSSadaf Ebrahimi             Resources.maxVertexTextureImageUnits = value;
401*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
402*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedTextureImageUnits = value;
403*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTextureImageUnits") == 0)
404*b7893ccfSSadaf Ebrahimi             Resources.maxTextureImageUnits = value;
405*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
406*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentUniformComponents = value;
407*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxDrawBuffers") == 0)
408*b7893ccfSSadaf Ebrahimi             Resources.maxDrawBuffers = value;
409*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexUniformVectors") == 0)
410*b7893ccfSSadaf Ebrahimi             Resources.maxVertexUniformVectors = value;
411*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVaryingVectors") == 0)
412*b7893ccfSSadaf Ebrahimi             Resources.maxVaryingVectors = value;
413*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
414*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentUniformVectors = value;
415*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexOutputVectors") == 0)
416*b7893ccfSSadaf Ebrahimi             Resources.maxVertexOutputVectors = value;
417*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentInputVectors") == 0)
418*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentInputVectors = value;
419*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MinProgramTexelOffset") == 0)
420*b7893ccfSSadaf Ebrahimi             Resources.minProgramTexelOffset = value;
421*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxProgramTexelOffset") == 0)
422*b7893ccfSSadaf Ebrahimi             Resources.maxProgramTexelOffset = value;
423*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxClipDistances") == 0)
424*b7893ccfSSadaf Ebrahimi             Resources.maxClipDistances = value;
425*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
426*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupCountX = value;
427*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
428*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupCountY = value;
429*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
430*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupCountZ = value;
431*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
432*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupSizeX = value;
433*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
434*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupSizeY = value;
435*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
436*b7893ccfSSadaf Ebrahimi             Resources.maxComputeWorkGroupSizeZ = value;
437*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeUniformComponents") == 0)
438*b7893ccfSSadaf Ebrahimi             Resources.maxComputeUniformComponents = value;
439*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
440*b7893ccfSSadaf Ebrahimi             Resources.maxComputeTextureImageUnits = value;
441*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeImageUniforms") == 0)
442*b7893ccfSSadaf Ebrahimi             Resources.maxComputeImageUniforms = value;
443*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
444*b7893ccfSSadaf Ebrahimi             Resources.maxComputeAtomicCounters = value;
445*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
446*b7893ccfSSadaf Ebrahimi             Resources.maxComputeAtomicCounterBuffers = value;
447*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVaryingComponents") == 0)
448*b7893ccfSSadaf Ebrahimi             Resources.maxVaryingComponents = value;
449*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexOutputComponents") == 0)
450*b7893ccfSSadaf Ebrahimi             Resources.maxVertexOutputComponents = value;
451*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryInputComponents") == 0)
452*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryInputComponents = value;
453*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
454*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryOutputComponents = value;
455*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentInputComponents") == 0)
456*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentInputComponents = value;
457*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxImageUnits") == 0)
458*b7893ccfSSadaf Ebrahimi             Resources.maxImageUnits = value;
459*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
460*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
461*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
462*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedShaderOutputResources = value;
463*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxImageSamples") == 0)
464*b7893ccfSSadaf Ebrahimi             Resources.maxImageSamples = value;
465*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexImageUniforms") == 0)
466*b7893ccfSSadaf Ebrahimi             Resources.maxVertexImageUniforms = value;
467*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
468*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlImageUniforms = value;
469*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
470*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationImageUniforms = value;
471*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
472*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryImageUniforms = value;
473*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
474*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentImageUniforms = value;
475*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
476*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedImageUniforms = value;
477*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
478*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryTextureImageUnits = value;
479*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
480*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryOutputVertices = value;
481*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
482*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryTotalOutputComponents = value;
483*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
484*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryUniformComponents = value;
485*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
486*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryVaryingComponents = value;
487*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlInputComponents") == 0)
488*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlInputComponents = value;
489*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
490*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlOutputComponents = value;
491*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
492*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlTextureImageUnits = value;
493*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
494*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlUniformComponents = value;
495*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
496*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlTotalOutputComponents = value;
497*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
498*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationInputComponents = value;
499*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
500*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationOutputComponents = value;
501*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
502*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationTextureImageUnits = value;
503*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
504*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationUniformComponents = value;
505*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessPatchComponents") == 0)
506*b7893ccfSSadaf Ebrahimi             Resources.maxTessPatchComponents = value;
507*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxPatchVertices") == 0)
508*b7893ccfSSadaf Ebrahimi             Resources.maxPatchVertices = value;
509*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessGenLevel") == 0)
510*b7893ccfSSadaf Ebrahimi             Resources.maxTessGenLevel = value;
511*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxViewports") == 0)
512*b7893ccfSSadaf Ebrahimi             Resources.maxViewports = value;
513*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
514*b7893ccfSSadaf Ebrahimi             Resources.maxVertexAtomicCounters = value;
515*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
516*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlAtomicCounters = value;
517*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
518*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationAtomicCounters = value;
519*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
520*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryAtomicCounters = value;
521*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
522*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentAtomicCounters = value;
523*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
524*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedAtomicCounters = value;
525*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
526*b7893ccfSSadaf Ebrahimi             Resources.maxAtomicCounterBindings = value;
527*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
528*b7893ccfSSadaf Ebrahimi             Resources.maxVertexAtomicCounterBuffers = value;
529*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
530*b7893ccfSSadaf Ebrahimi             Resources.maxTessControlAtomicCounterBuffers = value;
531*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
532*b7893ccfSSadaf Ebrahimi             Resources.maxTessEvaluationAtomicCounterBuffers = value;
533*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
534*b7893ccfSSadaf Ebrahimi             Resources.maxGeometryAtomicCounterBuffers = value;
535*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
536*b7893ccfSSadaf Ebrahimi             Resources.maxFragmentAtomicCounterBuffers = value;
537*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
538*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedAtomicCounterBuffers = value;
539*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
540*b7893ccfSSadaf Ebrahimi             Resources.maxAtomicCounterBufferSize = value;
541*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
542*b7893ccfSSadaf Ebrahimi             Resources.maxTransformFeedbackBuffers = value;
543*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
544*b7893ccfSSadaf Ebrahimi             Resources.maxTransformFeedbackInterleavedComponents = value;
545*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCullDistances") == 0)
546*b7893ccfSSadaf Ebrahimi             Resources.maxCullDistances = value;
547*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
548*b7893ccfSSadaf Ebrahimi             Resources.maxCombinedClipAndCullDistances = value;
549*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxSamples") == 0)
550*b7893ccfSSadaf Ebrahimi             Resources.maxSamples = value;
551*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshOutputVerticesNV") == 0)
552*b7893ccfSSadaf Ebrahimi             Resources.maxMeshOutputVerticesNV = value;
553*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshOutputPrimitivesNV") == 0)
554*b7893ccfSSadaf Ebrahimi             Resources.maxMeshOutputPrimitivesNV = value;
555*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshWorkGroupSizeX_NV") == 0)
556*b7893ccfSSadaf Ebrahimi             Resources.maxMeshWorkGroupSizeX_NV = value;
557*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshWorkGroupSizeY_NV") == 0)
558*b7893ccfSSadaf Ebrahimi             Resources.maxMeshWorkGroupSizeY_NV = value;
559*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshWorkGroupSizeZ_NV") == 0)
560*b7893ccfSSadaf Ebrahimi             Resources.maxMeshWorkGroupSizeZ_NV = value;
561*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTaskWorkGroupSizeX_NV") == 0)
562*b7893ccfSSadaf Ebrahimi             Resources.maxTaskWorkGroupSizeX_NV = value;
563*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTaskWorkGroupSizeY_NV") == 0)
564*b7893ccfSSadaf Ebrahimi             Resources.maxTaskWorkGroupSizeY_NV = value;
565*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxTaskWorkGroupSizeZ_NV") == 0)
566*b7893ccfSSadaf Ebrahimi             Resources.maxTaskWorkGroupSizeZ_NV = value;
567*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "MaxMeshViewCountNV") == 0)
568*b7893ccfSSadaf Ebrahimi             Resources.maxMeshViewCountNV = value;
569*b7893ccfSSadaf Ebrahimi 
570*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "nonInductiveForLoops") == 0)
571*b7893ccfSSadaf Ebrahimi             Resources.limits.nonInductiveForLoops = (value != 0);
572*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "whileLoops") == 0)
573*b7893ccfSSadaf Ebrahimi             Resources.limits.whileLoops = (value != 0);
574*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "doWhileLoops") == 0)
575*b7893ccfSSadaf Ebrahimi             Resources.limits.doWhileLoops = (value != 0);
576*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalUniformIndexing") == 0)
577*b7893ccfSSadaf Ebrahimi             Resources.limits.generalUniformIndexing = (value != 0);
578*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
579*b7893ccfSSadaf Ebrahimi             Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
580*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalVaryingIndexing") == 0)
581*b7893ccfSSadaf Ebrahimi             Resources.limits.generalVaryingIndexing = (value != 0);
582*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalSamplerIndexing") == 0)
583*b7893ccfSSadaf Ebrahimi             Resources.limits.generalSamplerIndexing = (value != 0);
584*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalVariableIndexing") == 0)
585*b7893ccfSSadaf Ebrahimi             Resources.limits.generalVariableIndexing = (value != 0);
586*b7893ccfSSadaf Ebrahimi         else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
587*b7893ccfSSadaf Ebrahimi             Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
588*b7893ccfSSadaf Ebrahimi         else
589*b7893ccfSSadaf Ebrahimi             printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
590*b7893ccfSSadaf Ebrahimi 
591*b7893ccfSSadaf Ebrahimi         token = strtok(0, delims);
592*b7893ccfSSadaf Ebrahimi     }
593*b7893ccfSSadaf Ebrahimi     if (configStrings) FreeFileData(configStrings);
594*b7893ccfSSadaf Ebrahimi }
595*b7893ccfSSadaf Ebrahimi 
SetMessageOptions(EShMessages & messages)596*b7893ccfSSadaf Ebrahimi void VkTestFramework::SetMessageOptions(EShMessages &messages) {
597*b7893ccfSSadaf Ebrahimi     if (m_compile_options & EOptionRelaxedErrors) messages = (EShMessages)(messages | EShMsgRelaxedErrors);
598*b7893ccfSSadaf Ebrahimi     if (m_compile_options & EOptionIntermediate) messages = (EShMessages)(messages | EShMsgAST);
599*b7893ccfSSadaf Ebrahimi     if (m_compile_options & EOptionSuppressWarnings) messages = (EShMessages)(messages | EShMsgSuppressWarnings);
600*b7893ccfSSadaf Ebrahimi }
601*b7893ccfSSadaf Ebrahimi 
602*b7893ccfSSadaf Ebrahimi //
603*b7893ccfSSadaf Ebrahimi //   Malloc a string of sufficient size and read a string into it.
604*b7893ccfSSadaf Ebrahimi //
ReadFileData(const char * fileName)605*b7893ccfSSadaf Ebrahimi char **VkTestFramework::ReadFileData(const char *fileName) {
606*b7893ccfSSadaf Ebrahimi     FILE *in;
607*b7893ccfSSadaf Ebrahimi #if defined(_WIN32) && defined(__GNUC__)
608*b7893ccfSSadaf Ebrahimi     in = fopen(fileName, "r");
609*b7893ccfSSadaf Ebrahimi     int errorCode = in ? 0 : 1;
610*b7893ccfSSadaf Ebrahimi #else
611*b7893ccfSSadaf Ebrahimi     int errorCode = fopen_s(&in, fileName, "r");
612*b7893ccfSSadaf Ebrahimi #endif
613*b7893ccfSSadaf Ebrahimi 
614*b7893ccfSSadaf Ebrahimi     char *fdata;
615*b7893ccfSSadaf Ebrahimi     size_t count = 0;
616*b7893ccfSSadaf Ebrahimi     const int maxSourceStrings = 5;
617*b7893ccfSSadaf Ebrahimi     char **return_data = (char **)malloc(sizeof(char *) * (maxSourceStrings + 1));
618*b7893ccfSSadaf Ebrahimi 
619*b7893ccfSSadaf Ebrahimi     if (errorCode) {
620*b7893ccfSSadaf Ebrahimi         printf("Error: unable to open input file: %s\n", fileName);
621*b7893ccfSSadaf Ebrahimi         return 0;
622*b7893ccfSSadaf Ebrahimi     }
623*b7893ccfSSadaf Ebrahimi 
624*b7893ccfSSadaf Ebrahimi     while (fgetc(in) != EOF) count++;
625*b7893ccfSSadaf Ebrahimi 
626*b7893ccfSSadaf Ebrahimi     fseek(in, 0, SEEK_SET);
627*b7893ccfSSadaf Ebrahimi 
628*b7893ccfSSadaf Ebrahimi     if (!(fdata = (char *)malloc(count + 2))) {
629*b7893ccfSSadaf Ebrahimi         printf("Error allocating memory\n");
630*b7893ccfSSadaf Ebrahimi         return 0;
631*b7893ccfSSadaf Ebrahimi     }
632*b7893ccfSSadaf Ebrahimi     if (fread(fdata, 1, count, in) != count) {
633*b7893ccfSSadaf Ebrahimi         printf("Error reading input file: %s\n", fileName);
634*b7893ccfSSadaf Ebrahimi         return 0;
635*b7893ccfSSadaf Ebrahimi     }
636*b7893ccfSSadaf Ebrahimi     fdata[count] = '\0';
637*b7893ccfSSadaf Ebrahimi     fclose(in);
638*b7893ccfSSadaf Ebrahimi     if (count == 0) {
639*b7893ccfSSadaf Ebrahimi         return_data[0] = (char *)malloc(count + 2);
640*b7893ccfSSadaf Ebrahimi         return_data[0][0] = '\0';
641*b7893ccfSSadaf Ebrahimi         m_num_shader_strings = 0;
642*b7893ccfSSadaf Ebrahimi         return return_data;
643*b7893ccfSSadaf Ebrahimi     } else
644*b7893ccfSSadaf Ebrahimi         m_num_shader_strings = 1;
645*b7893ccfSSadaf Ebrahimi 
646*b7893ccfSSadaf Ebrahimi     size_t len = (int)(ceil)((float)count / (float)m_num_shader_strings);
647*b7893ccfSSadaf Ebrahimi     size_t ptr_len = 0, i = 0;
648*b7893ccfSSadaf Ebrahimi     while (count > 0) {
649*b7893ccfSSadaf Ebrahimi         return_data[i] = (char *)malloc(len + 2);
650*b7893ccfSSadaf Ebrahimi         memcpy(return_data[i], fdata + ptr_len, len);
651*b7893ccfSSadaf Ebrahimi         return_data[i][len] = '\0';
652*b7893ccfSSadaf Ebrahimi         count -= (len);
653*b7893ccfSSadaf Ebrahimi         ptr_len += (len);
654*b7893ccfSSadaf Ebrahimi         if (count < len) {
655*b7893ccfSSadaf Ebrahimi             if (count == 0) {
656*b7893ccfSSadaf Ebrahimi                 m_num_shader_strings = (i + 1);
657*b7893ccfSSadaf Ebrahimi                 break;
658*b7893ccfSSadaf Ebrahimi             }
659*b7893ccfSSadaf Ebrahimi             len = count;
660*b7893ccfSSadaf Ebrahimi         }
661*b7893ccfSSadaf Ebrahimi         ++i;
662*b7893ccfSSadaf Ebrahimi     }
663*b7893ccfSSadaf Ebrahimi     return return_data;
664*b7893ccfSSadaf Ebrahimi }
665*b7893ccfSSadaf Ebrahimi 
FreeFileData(char ** data)666*b7893ccfSSadaf Ebrahimi void VkTestFramework::FreeFileData(char **data) {
667*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < m_num_shader_strings; i++) free(data[i]);
668*b7893ccfSSadaf Ebrahimi }
669*b7893ccfSSadaf Ebrahimi 
670*b7893ccfSSadaf Ebrahimi //
671*b7893ccfSSadaf Ebrahimi //   Deduce the language from the filename.  Files must end in one of the
672*b7893ccfSSadaf Ebrahimi //   following extensions:
673*b7893ccfSSadaf Ebrahimi //
674*b7893ccfSSadaf Ebrahimi //   .vert = vertex
675*b7893ccfSSadaf Ebrahimi //   .tesc = tessellation control
676*b7893ccfSSadaf Ebrahimi //   .tese = tessellation evaluation
677*b7893ccfSSadaf Ebrahimi //   .geom = geometry
678*b7893ccfSSadaf Ebrahimi //   .frag = fragment
679*b7893ccfSSadaf Ebrahimi //   .comp = compute
680*b7893ccfSSadaf Ebrahimi //
FindLanguage(const std::string & name)681*b7893ccfSSadaf Ebrahimi EShLanguage VkTestFramework::FindLanguage(const std::string &name) {
682*b7893ccfSSadaf Ebrahimi     size_t ext = name.rfind('.');
683*b7893ccfSSadaf Ebrahimi     if (ext == std::string::npos) {
684*b7893ccfSSadaf Ebrahimi         return EShLangVertex;
685*b7893ccfSSadaf Ebrahimi     }
686*b7893ccfSSadaf Ebrahimi 
687*b7893ccfSSadaf Ebrahimi     std::string suffix = name.substr(ext + 1, std::string::npos);
688*b7893ccfSSadaf Ebrahimi     if (suffix == "vert")
689*b7893ccfSSadaf Ebrahimi         return EShLangVertex;
690*b7893ccfSSadaf Ebrahimi     else if (suffix == "tesc")
691*b7893ccfSSadaf Ebrahimi         return EShLangTessControl;
692*b7893ccfSSadaf Ebrahimi     else if (suffix == "tese")
693*b7893ccfSSadaf Ebrahimi         return EShLangTessEvaluation;
694*b7893ccfSSadaf Ebrahimi     else if (suffix == "geom")
695*b7893ccfSSadaf Ebrahimi         return EShLangGeometry;
696*b7893ccfSSadaf Ebrahimi     else if (suffix == "frag")
697*b7893ccfSSadaf Ebrahimi         return EShLangFragment;
698*b7893ccfSSadaf Ebrahimi     else if (suffix == "comp")
699*b7893ccfSSadaf Ebrahimi         return EShLangCompute;
700*b7893ccfSSadaf Ebrahimi 
701*b7893ccfSSadaf Ebrahimi     return EShLangVertex;
702*b7893ccfSSadaf Ebrahimi }
703*b7893ccfSSadaf Ebrahimi 
704*b7893ccfSSadaf Ebrahimi //
705*b7893ccfSSadaf Ebrahimi // Convert VK shader type to compiler's
706*b7893ccfSSadaf Ebrahimi //
FindLanguage(const VkShaderStageFlagBits shader_type)707*b7893ccfSSadaf Ebrahimi EShLanguage VkTestFramework::FindLanguage(const VkShaderStageFlagBits shader_type) {
708*b7893ccfSSadaf Ebrahimi     switch (shader_type) {
709*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_VERTEX_BIT:
710*b7893ccfSSadaf Ebrahimi             return EShLangVertex;
711*b7893ccfSSadaf Ebrahimi 
712*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
713*b7893ccfSSadaf Ebrahimi             return EShLangTessControl;
714*b7893ccfSSadaf Ebrahimi 
715*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
716*b7893ccfSSadaf Ebrahimi             return EShLangTessEvaluation;
717*b7893ccfSSadaf Ebrahimi 
718*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_GEOMETRY_BIT:
719*b7893ccfSSadaf Ebrahimi             return EShLangGeometry;
720*b7893ccfSSadaf Ebrahimi 
721*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_FRAGMENT_BIT:
722*b7893ccfSSadaf Ebrahimi             return EShLangFragment;
723*b7893ccfSSadaf Ebrahimi 
724*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_COMPUTE_BIT:
725*b7893ccfSSadaf Ebrahimi             return EShLangCompute;
726*b7893ccfSSadaf Ebrahimi 
727*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_RAYGEN_BIT_NV:
728*b7893ccfSSadaf Ebrahimi             return EShLangRayGenNV;
729*b7893ccfSSadaf Ebrahimi 
730*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_ANY_HIT_BIT_NV:
731*b7893ccfSSadaf Ebrahimi             return EShLangAnyHitNV;
732*b7893ccfSSadaf Ebrahimi 
733*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV:
734*b7893ccfSSadaf Ebrahimi             return EShLangClosestHitNV;
735*b7893ccfSSadaf Ebrahimi 
736*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_MISS_BIT_NV:
737*b7893ccfSSadaf Ebrahimi             return EShLangMissNV;
738*b7893ccfSSadaf Ebrahimi 
739*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_INTERSECTION_BIT_NV:
740*b7893ccfSSadaf Ebrahimi             return EShLangIntersectNV;
741*b7893ccfSSadaf Ebrahimi 
742*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_CALLABLE_BIT_NV:
743*b7893ccfSSadaf Ebrahimi             return EShLangCallableNV;
744*b7893ccfSSadaf Ebrahimi 
745*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_TASK_BIT_NV:
746*b7893ccfSSadaf Ebrahimi             return EShLangTaskNV;
747*b7893ccfSSadaf Ebrahimi 
748*b7893ccfSSadaf Ebrahimi         case VK_SHADER_STAGE_MESH_BIT_NV:
749*b7893ccfSSadaf Ebrahimi             return EShLangMeshNV;
750*b7893ccfSSadaf Ebrahimi 
751*b7893ccfSSadaf Ebrahimi         default:
752*b7893ccfSSadaf Ebrahimi             return EShLangVertex;
753*b7893ccfSSadaf Ebrahimi     }
754*b7893ccfSSadaf Ebrahimi }
755*b7893ccfSSadaf Ebrahimi 
756*b7893ccfSSadaf Ebrahimi //
757*b7893ccfSSadaf Ebrahimi // Compile a given string containing GLSL into SPV for use by VK
758*b7893ccfSSadaf Ebrahimi // Return value of false means an error was encountered.
759*b7893ccfSSadaf Ebrahimi //
GLSLtoSPV(const VkShaderStageFlagBits shader_type,const char * pshader,std::vector<unsigned int> & spirv,bool debug)760*b7893ccfSSadaf Ebrahimi bool VkTestFramework::GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<unsigned int> &spirv,
761*b7893ccfSSadaf Ebrahimi                                 bool debug) {
762*b7893ccfSSadaf Ebrahimi     glslang::TProgram program;
763*b7893ccfSSadaf Ebrahimi     const char *shaderStrings[1];
764*b7893ccfSSadaf Ebrahimi 
765*b7893ccfSSadaf Ebrahimi     // TODO: Do we want to load a special config file depending on the
766*b7893ccfSSadaf Ebrahimi     // shader source? Optional name maybe?
767*b7893ccfSSadaf Ebrahimi     //    SetConfigFile(fileName);
768*b7893ccfSSadaf Ebrahimi 
769*b7893ccfSSadaf Ebrahimi     ProcessConfigFile();
770*b7893ccfSSadaf Ebrahimi 
771*b7893ccfSSadaf Ebrahimi     EShMessages messages = EShMsgDefault;
772*b7893ccfSSadaf Ebrahimi     SetMessageOptions(messages);
773*b7893ccfSSadaf Ebrahimi     messages = static_cast<EShMessages>(messages | EShMsgSpvRules | EShMsgVulkanRules);
774*b7893ccfSSadaf Ebrahimi     if (debug) {
775*b7893ccfSSadaf Ebrahimi         messages = static_cast<EShMessages>(messages | EShMsgDebugInfo);
776*b7893ccfSSadaf Ebrahimi     }
777*b7893ccfSSadaf Ebrahimi 
778*b7893ccfSSadaf Ebrahimi     EShLanguage stage = FindLanguage(shader_type);
779*b7893ccfSSadaf Ebrahimi     glslang::TShader *shader = new glslang::TShader(stage);
780*b7893ccfSSadaf Ebrahimi 
781*b7893ccfSSadaf Ebrahimi     shaderStrings[0] = pshader;
782*b7893ccfSSadaf Ebrahimi     shader->setStrings(shaderStrings, 1);
783*b7893ccfSSadaf Ebrahimi 
784*b7893ccfSSadaf Ebrahimi     if (!shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
785*b7893ccfSSadaf Ebrahimi         if (!(m_compile_options & EOptionSuppressInfolog)) {
786*b7893ccfSSadaf Ebrahimi             puts(shader->getInfoLog());
787*b7893ccfSSadaf Ebrahimi             puts(shader->getInfoDebugLog());
788*b7893ccfSSadaf Ebrahimi         }
789*b7893ccfSSadaf Ebrahimi 
790*b7893ccfSSadaf Ebrahimi         return false;  // something didn't work
791*b7893ccfSSadaf Ebrahimi     }
792*b7893ccfSSadaf Ebrahimi 
793*b7893ccfSSadaf Ebrahimi     program.addShader(shader);
794*b7893ccfSSadaf Ebrahimi 
795*b7893ccfSSadaf Ebrahimi     //
796*b7893ccfSSadaf Ebrahimi     // Program-level processing...
797*b7893ccfSSadaf Ebrahimi     //
798*b7893ccfSSadaf Ebrahimi 
799*b7893ccfSSadaf Ebrahimi     if (!program.link(messages)) {
800*b7893ccfSSadaf Ebrahimi         if (!(m_compile_options & EOptionSuppressInfolog)) {
801*b7893ccfSSadaf Ebrahimi             puts(shader->getInfoLog());
802*b7893ccfSSadaf Ebrahimi             puts(shader->getInfoDebugLog());
803*b7893ccfSSadaf Ebrahimi         }
804*b7893ccfSSadaf Ebrahimi 
805*b7893ccfSSadaf Ebrahimi         return false;
806*b7893ccfSSadaf Ebrahimi     }
807*b7893ccfSSadaf Ebrahimi 
808*b7893ccfSSadaf Ebrahimi     if (m_compile_options & EOptionDumpReflection) {
809*b7893ccfSSadaf Ebrahimi         program.buildReflection();
810*b7893ccfSSadaf Ebrahimi         program.dumpReflection();
811*b7893ccfSSadaf Ebrahimi     }
812*b7893ccfSSadaf Ebrahimi 
813*b7893ccfSSadaf Ebrahimi     glslang::SpvOptions spv_options;
814*b7893ccfSSadaf Ebrahimi     if (debug) {
815*b7893ccfSSadaf Ebrahimi         spv_options.generateDebugInfo = true;
816*b7893ccfSSadaf Ebrahimi     }
817*b7893ccfSSadaf Ebrahimi     glslang::GlslangToSpv(*program.getIntermediate(stage), spirv, &spv_options);
818*b7893ccfSSadaf Ebrahimi 
819*b7893ccfSSadaf Ebrahimi     //
820*b7893ccfSSadaf Ebrahimi     // Test the different modes of SPIR-V modification
821*b7893ccfSSadaf Ebrahimi     //
822*b7893ccfSSadaf Ebrahimi     if (this->m_canonicalize_spv) {
823*b7893ccfSSadaf Ebrahimi         spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
824*b7893ccfSSadaf Ebrahimi     }
825*b7893ccfSSadaf Ebrahimi 
826*b7893ccfSSadaf Ebrahimi     if (this->m_strip_spv) {
827*b7893ccfSSadaf Ebrahimi         spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
828*b7893ccfSSadaf Ebrahimi     }
829*b7893ccfSSadaf Ebrahimi 
830*b7893ccfSSadaf Ebrahimi     if (this->m_do_everything_spv) {
831*b7893ccfSSadaf Ebrahimi         spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
832*b7893ccfSSadaf Ebrahimi     }
833*b7893ccfSSadaf Ebrahimi 
834*b7893ccfSSadaf Ebrahimi     delete shader;
835*b7893ccfSSadaf Ebrahimi 
836*b7893ccfSSadaf Ebrahimi     return true;
837*b7893ccfSSadaf Ebrahimi }
838*b7893ccfSSadaf Ebrahimi 
839*b7893ccfSSadaf Ebrahimi //
840*b7893ccfSSadaf Ebrahimi // Compile a given string containing SPIR-V assembly into SPV for use by VK
841*b7893ccfSSadaf Ebrahimi // Return value of false means an error was encountered.
842*b7893ccfSSadaf Ebrahimi //
ASMtoSPV(const spv_target_env target_env,const uint32_t options,const char * pasm,std::vector<unsigned int> & spv)843*b7893ccfSSadaf Ebrahimi bool VkTestFramework::ASMtoSPV(const spv_target_env target_env, const uint32_t options, const char *pasm,
844*b7893ccfSSadaf Ebrahimi                                std::vector<unsigned int> &spv) {
845*b7893ccfSSadaf Ebrahimi     spv_binary binary;
846*b7893ccfSSadaf Ebrahimi     spv_diagnostic diagnostic = nullptr;
847*b7893ccfSSadaf Ebrahimi     spv_context context = spvContextCreate(target_env);
848*b7893ccfSSadaf Ebrahimi     spv_result_t error = spvTextToBinaryWithOptions(context, pasm, strlen(pasm), options, &binary, &diagnostic);
849*b7893ccfSSadaf Ebrahimi     spvContextDestroy(context);
850*b7893ccfSSadaf Ebrahimi     if (error) {
851*b7893ccfSSadaf Ebrahimi         spvDiagnosticPrint(diagnostic);
852*b7893ccfSSadaf Ebrahimi         spvDiagnosticDestroy(diagnostic);
853*b7893ccfSSadaf Ebrahimi         return false;
854*b7893ccfSSadaf Ebrahimi     }
855*b7893ccfSSadaf Ebrahimi     spv.insert(spv.end(), binary->code, binary->code + binary->wordCount);
856*b7893ccfSSadaf Ebrahimi     spvBinaryDestroy(binary);
857*b7893ccfSSadaf Ebrahimi 
858*b7893ccfSSadaf Ebrahimi     return true;
859*b7893ccfSSadaf Ebrahimi }
860