SPIRV-Tools/source/spirv_target_env.cpp
Kévin Petit bec7e0393f Add all accepted target environments to the tools' help texts (#2687)
Several tools take a --target-env option to specify the SPIR-V
environment to use. They all use spvParseTargetEnv to parse
the user-specified string and select the appropriate spv_target_env
but all tools list only _some_ of the valid values in their help
text.

This change makes the help text construction automatic from the
full list of valid values, establishing a single source of truth
for the values printed in the help text. The new utility function
added allows its user to specify padding and wrapping constraints
so the produced strings fits well in the various help texts.

Signed-off-by: Kévin Petit <kpet@free.fr>
2019-06-20 09:41:28 -04:00

304 lines
9.1 KiB
C++

// Copyright (c) 2015-2016 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/spirv_target_env.h"
#include <cstring>
#include <map>
#include <string>
#include "source/spirv_constant.h"
#include "spirv-tools/libspirv.h"
const char* spvTargetEnvDescription(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
return "SPIR-V 1.0";
case SPV_ENV_VULKAN_1_0:
return "SPIR-V 1.0 (under Vulkan 1.0 semantics)";
case SPV_ENV_UNIVERSAL_1_1:
return "SPIR-V 1.1";
case SPV_ENV_OPENCL_1_2:
return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)";
case SPV_ENV_OPENCL_EMBEDDED_1_2:
return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)";
case SPV_ENV_OPENCL_2_0:
return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)";
case SPV_ENV_OPENCL_EMBEDDED_2_0:
return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)";
case SPV_ENV_OPENCL_2_1:
return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)";
case SPV_ENV_OPENCL_EMBEDDED_2_1:
return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)";
case SPV_ENV_OPENCL_2_2:
return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)";
case SPV_ENV_OPENCL_EMBEDDED_2_2:
return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
case SPV_ENV_OPENGL_4_0:
return "SPIR-V 1.0 (under OpenGL 4.0 semantics)";
case SPV_ENV_OPENGL_4_1:
return "SPIR-V 1.0 (under OpenGL 4.1 semantics)";
case SPV_ENV_OPENGL_4_2:
return "SPIR-V 1.0 (under OpenGL 4.2 semantics)";
case SPV_ENV_OPENGL_4_3:
return "SPIR-V 1.0 (under OpenGL 4.3 semantics)";
case SPV_ENV_OPENGL_4_5:
return "SPIR-V 1.0 (under OpenGL 4.5 semantics)";
case SPV_ENV_UNIVERSAL_1_2:
return "SPIR-V 1.2";
case SPV_ENV_UNIVERSAL_1_3:
return "SPIR-V 1.3";
case SPV_ENV_VULKAN_1_1:
return "SPIR-V 1.3 (under Vulkan 1.1 semantics)";
case SPV_ENV_WEBGPU_0:
return "SPIR-V 1.3 (under WIP WebGPU semantics)";
case SPV_ENV_UNIVERSAL_1_4:
return "SPIR-V 1.4";
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
}
return "";
}
uint32_t spvVersionForTargetEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
return SPV_SPIRV_VERSION_WORD(1, 0);
case SPV_ENV_UNIVERSAL_1_1:
return SPV_SPIRV_VERSION_WORD(1, 1);
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_OPENCL_2_2:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
return SPV_SPIRV_VERSION_WORD(1, 2);
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_WEBGPU_0:
return SPV_SPIRV_VERSION_WORD(1, 3);
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return SPV_SPIRV_VERSION_WORD(1, 4);
}
return SPV_SPIRV_VERSION_WORD(0, 0);
}
static const std::map<std::string, spv_target_env> spvTargetEnvNameMap = {
{"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4},
{"vulkan1.0", SPV_ENV_VULKAN_1_0},
{"vulkan1.1", SPV_ENV_VULKAN_1_1},
{"spv1.0", SPV_ENV_UNIVERSAL_1_0},
{"spv1.1", SPV_ENV_UNIVERSAL_1_1},
{"spv1.2", SPV_ENV_UNIVERSAL_1_2},
{"spv1.3", SPV_ENV_UNIVERSAL_1_3},
{"spv1.4", SPV_ENV_UNIVERSAL_1_4},
{"opencl1.2embedded", SPV_ENV_OPENCL_EMBEDDED_1_2},
{"opencl1.2", SPV_ENV_OPENCL_1_2},
{"opencl2.0embedded", SPV_ENV_OPENCL_EMBEDDED_2_0},
{"opencl2.0", SPV_ENV_OPENCL_2_0},
{"opencl2.1embedded", SPV_ENV_OPENCL_EMBEDDED_2_1},
{"opencl2.1", SPV_ENV_OPENCL_2_1},
{"opencl2.2embedded", SPV_ENV_OPENCL_EMBEDDED_2_2},
{"opencl2.2", SPV_ENV_OPENCL_2_2},
{"opengl4.0", SPV_ENV_OPENGL_4_0},
{"opengl4.1", SPV_ENV_OPENGL_4_1},
{"opengl4.2", SPV_ENV_OPENGL_4_2},
{"opengl4.3", SPV_ENV_OPENGL_4_3},
{"opengl4.5", SPV_ENV_OPENGL_4_5},
{"webgpu0", SPV_ENV_WEBGPU_0},
};
bool spvParseTargetEnv(const char* s, spv_target_env* env) {
std::string envstr;
if (s != nullptr) {
envstr = s;
}
if (spvTargetEnvNameMap.count(envstr) != 0) {
if (env) {
*env = spvTargetEnvNameMap.at(envstr);
}
return true;
}
if (env) *env = SPV_ENV_UNIVERSAL_1_0;
return false;
}
bool spvIsVulkanEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_OPENCL_2_2:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
return false;
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return true;
}
return false;
}
bool spvIsOpenCLEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_WEBGPU_0:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return false;
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_2_2:
return true;
}
return false;
}
bool spvIsWebGPUEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_2_2:
case SPV_ENV_UNIVERSAL_1_4:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
return false;
case SPV_ENV_WEBGPU_0:
return true;
}
return false;
}
bool spvIsVulkanOrWebGPUEnv(spv_target_env env) {
return spvIsVulkanEnv(env) || spvIsWebGPUEnv(env);
}
std::string spvLogStringForEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_2_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_2: {
return "OpenCL";
}
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5: {
return "OpenGL";
}
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_VULKAN_1_1_SPIRV_1_4: {
return "Vulkan";
}
case SPV_ENV_WEBGPU_0: {
return "WebGPU";
}
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_UNIVERSAL_1_4: {
return "Universal";
}
}
return "Unknown";
}
std::string spvTargetEnvList(const int pad, const int wrap) {
std::string ret;
size_t max_line_len = wrap - pad; // The first line isn't padded
std::string line;
std::string sep = "";
for (auto& env_name : spvTargetEnvNameMap) {
std::string word = sep + env_name.first;
if (line.length() + word.length() > max_line_len) {
// Adding one word wouldn't fit, commit the line in progress and
// start a new one.
ret += line + "\n";
line.assign(pad, ' ');
// The first line is done. The max length now comprises the
// padding.
max_line_len = wrap;
}
line += word;
sep = "|";
}
ret += line;
return ret;
}