mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-22 11:40:05 +00:00
Add spvParseVulkanEnv (#3142)
This new API lets clients request a minimal spv_target_env value that supports a given Vulkan and SPIR-V version, by a generic numbering scheme (as already defined by Vulkan and SPIR-V specs). This breaks a formal source dependency from Glslang to SPIRV-Tools. When a new API is rolled out, such as Vulkan 1.2, Glslang currently needs to reference a specific SPIRV-Tools enum by name.
This commit is contained in:
parent
dd37d73c5e
commit
bb236c326d
@ -473,6 +473,19 @@ SPIRV_TOOLS_EXPORT const char* spvTargetEnvDescription(spv_target_env env);
|
||||
// false and sets *env to SPV_ENV_UNIVERSAL_1_0.
|
||||
SPIRV_TOOLS_EXPORT bool spvParseTargetEnv(const char* s, spv_target_env* env);
|
||||
|
||||
// Determines the target env value with the least features but which enables
|
||||
// the given Vulkan and SPIR-V versions. If such a target is supported, returns
|
||||
// true and writes the value to |env|, otherwise returns false.
|
||||
//
|
||||
// The Vulkan version is given as an unsigned 32-bit number as specified in
|
||||
// Vulkan section "29.2.1 Version Numbers": the major version number appears
|
||||
// in bits 22 to 21, and the minor version is in bits 12 to 21. The SPIR-V
|
||||
// version is given in the SPIR-V version header word: major version in bits
|
||||
// 16 to 23, and minor version in bits 8 to 15.
|
||||
SPIRV_TOOLS_EXPORT bool spvParseVulkanEnv(uint32_t vulkan_ver,
|
||||
uint32_t spirv_ver,
|
||||
spv_target_env* env);
|
||||
|
||||
// Creates a context object. Returns null if env is invalid.
|
||||
SPIRV_TOOLS_EXPORT spv_context spvContextCreate(spv_target_env env);
|
||||
|
||||
|
@ -153,6 +153,34 @@ bool spvParseTargetEnv(const char* s, spv_target_env* env) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define VULKAN_VER(MAJOR, MINOR) ((MAJOR << 22) | (MINOR << 12))
|
||||
#define SPIRV_VER(MAJOR, MINOR) ((MAJOR << 16) | (MINOR << 8))
|
||||
|
||||
struct VulkanEnv {
|
||||
spv_target_env vulkan_env;
|
||||
uint32_t vulkan_ver;
|
||||
uint32_t spirv_ver;
|
||||
};
|
||||
// Maps each Vulkan target environment enum to the Vulkan version, and the
|
||||
// maximum supported SPIR-V version for that Vulkan environment.
|
||||
// Keep this ordered from least capable to most capable.
|
||||
static const VulkanEnv ordered_vulkan_envs[] = {
|
||||
{SPV_ENV_VULKAN_1_0, VULKAN_VER(1, 0), SPIRV_VER(1, 0)},
|
||||
{SPV_ENV_VULKAN_1_1, VULKAN_VER(1, 1), SPIRV_VER(1, 3)},
|
||||
{SPV_ENV_VULKAN_1_1_SPIRV_1_4, VULKAN_VER(1, 1), SPIRV_VER(1, 4)},
|
||||
{SPV_ENV_VULKAN_1_2, VULKAN_VER(1, 2), SPIRV_VER(1, 5)}};
|
||||
|
||||
bool spvParseVulkanEnv(uint32_t vulkan_ver, uint32_t spirv_ver,
|
||||
spv_target_env* env) {
|
||||
for (auto triple : ordered_vulkan_envs) {
|
||||
if (triple.vulkan_ver >= vulkan_ver && triple.spirv_ver >= spirv_ver) {
|
||||
*env = triple.vulkan_env;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool spvIsVulkanEnv(spv_target_env env) {
|
||||
switch (env) {
|
||||
case SPV_ENV_UNIVERSAL_1_0:
|
||||
|
@ -63,11 +63,13 @@ struct ParseCase {
|
||||
|
||||
using TargetParseTest = ::testing::TestWithParam<ParseCase>;
|
||||
|
||||
TEST_P(TargetParseTest, InvalidTargetEnvProducesNull) {
|
||||
TEST_P(TargetParseTest, Samples) {
|
||||
spv_target_env env;
|
||||
bool parsed = spvParseTargetEnv(GetParam().input, &env);
|
||||
EXPECT_THAT(parsed, Eq(GetParam().success));
|
||||
if (parsed) {
|
||||
EXPECT_THAT(env, Eq(GetParam().env));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
@ -103,5 +105,61 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
{"abc", false, SPV_ENV_UNIVERSAL_1_0},
|
||||
}));
|
||||
|
||||
// A test case for parsing an environment string.
|
||||
struct ParseVulkanCase {
|
||||
uint32_t vulkan;
|
||||
uint32_t spirv;
|
||||
bool success; // Expect to successfully parse?
|
||||
spv_target_env env; // The parsed environment, if successful.
|
||||
};
|
||||
|
||||
using TargetParseVulkanTest = ::testing::TestWithParam<ParseVulkanCase>;
|
||||
|
||||
TEST_P(TargetParseVulkanTest, Samples) {
|
||||
spv_target_env env;
|
||||
bool parsed = spvParseVulkanEnv(GetParam().vulkan, GetParam().spirv, &env);
|
||||
EXPECT_THAT(parsed, Eq(GetParam().success));
|
||||
if (parsed) {
|
||||
EXPECT_THAT(env, Eq(GetParam().env));
|
||||
}
|
||||
}
|
||||
|
||||
#define VK(MAJ, MIN) ((MAJ << 22) | (MIN << 12))
|
||||
#define SPV(MAJ, MIN) ((MAJ << 16) | (MIN << 8))
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
TargetVulkanParsing, TargetParseVulkanTest,
|
||||
ValuesIn(std::vector<ParseVulkanCase>{
|
||||
// Vulkan 1.0 cases
|
||||
{VK(1, 0), SPV(1, 0), true, SPV_ENV_VULKAN_1_0},
|
||||
{VK(1, 0), SPV(1, 1), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 0), SPV(1, 2), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 0), SPV(1, 3), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 0), SPV(1, 4), true, SPV_ENV_VULKAN_1_1_SPIRV_1_4},
|
||||
{VK(1, 0), SPV(1, 5), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 0), SPV(1, 6), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
// Vulkan 1.1 cases
|
||||
{VK(1, 1), SPV(1, 0), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 1), SPV(1, 1), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 1), SPV(1, 2), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 1), SPV(1, 3), true, SPV_ENV_VULKAN_1_1},
|
||||
{VK(1, 1), SPV(1, 4), true, SPV_ENV_VULKAN_1_1_SPIRV_1_4},
|
||||
{VK(1, 1), SPV(1, 5), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 1), SPV(1, 6), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
// Vulkan 1.2 cases
|
||||
{VK(1, 2), SPV(1, 0), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 1), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 2), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 3), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 4), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 5), true, SPV_ENV_VULKAN_1_2},
|
||||
{VK(1, 2), SPV(1, 6), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
// Vulkan 1.3 cases
|
||||
{VK(1, 3), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
// Vulkan 2.0 cases
|
||||
{VK(2, 0), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
// Vulkan 99.0 cases
|
||||
{VK(99, 0), SPV(1, 0), false, SPV_ENV_UNIVERSAL_1_0},
|
||||
}));
|
||||
|
||||
} // namespace
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user