https://github.com/shader-slang/slang
Tip revision: f7431f96e1cad2a68534bebc1f25cd6f65f87f82 authored by Yong He on 16 March 2023, 06:26:14 UTC
Fix `transcribeConstruct` for `makeStruct`. (#2703)
Fix `transcribeConstruct` for `makeStruct`. (#2703)
Tip revision: f7431f9
slang-type-text-util.cpp
#include "slang-type-text-util.h"
#include "slang-array-view.h"
#include "slang-string-util.h"
namespace Slang
{
#define SLANG_SCALAR_TYPES(x) \
x(None, none) \
x(Void, void) \
x(Bool, bool) \
x(Float16, half) \
x(UInt32, uint32_t) \
x(Int32, int32_t) \
x(Int64, int64_t) \
x(UInt64, uint64_t) \
x(Float32, float) \
x(Float64, double)
#define SLANG_PASS_THROUGH_TYPES(x) \
x(none, NONE) \
x(fxc, FXC) \
x(dxc, DXC) \
x(glslang, GLSLANG) \
x(visualstudio, VISUAL_STUDIO) \
x(clang, CLANG) \
x(gcc, GCC) \
x(genericcpp, GENERIC_C_CPP) \
x(nvrtc, NVRTC) \
x(llvm, LLVM)
#define SLANG_DEBUG_INFO_FORMATS(x) \
x(default-format, DEFAULT) \
x(c7, C7) \
x(pdb, PDB) \
x(stabs, STABS) \
x(coff, COFF) \
x(dwarf, DWARF)
namespace { // anonymous
struct ScalarTypeInfo
{
slang::TypeReflection::ScalarType type;
UnownedStringSlice text;
};
static const ScalarTypeInfo s_scalarTypeInfos[] =
{
#define SLANG_SCALAR_TYPE_INFO(value, text) \
{ slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text) },
SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)
};
struct CompileTargetInfo
{
SlangCompileTarget target; ///< The target
const char* extensions; ///< Comma delimited list of extensions associated with the target
const char* names; ///< Comma delimited list of names associated with the target. NOTE! First name is taken as the normal display name.
};
// Make sure to keep this table in sync with that in slang/slang-options.cpp getHelpText
static const CompileTargetInfo s_compileTargetInfos[] =
{
{ SLANG_TARGET_UNKNOWN, "", "unknown"},
{ SLANG_TARGET_NONE, "", "none"},
{ SLANG_HLSL, "hlsl,fx", "hlsl"},
{ SLANG_DXBC, "dxbc", "dxbc"},
{ SLANG_DXBC_ASM, "dxbc-asm", "dxbc-asm,dxbc-assembly" },
{ SLANG_DXIL, "dxil", "dxil" },
{ SLANG_DXIL_ASM, "dxil-asm", "dxil-asm,dxil-assembly" },
{ SLANG_GLSL, "glsl,vert,frag,geom,tesc,tese,comp", "glsl" },
{ SLANG_GLSL_VULKAN, "", "glsl-vulkan" },
{ SLANG_GLSL_VULKAN_ONE_DESC, "", "glsl-vulkan-one-desc" },
{ SLANG_SPIRV, "spv", "spirv"},
{ SLANG_SPIRV_ASM, "spv-asm", "spirv-asm,spirv-assembly" },
{ SLANG_C_SOURCE, "c", "c" },
{ SLANG_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx" },
{ SLANG_HOST_CPP_SOURCE, "cpp,c++,cxx", "host-cpp,host-c++,host-cxx"},
{ SLANG_HOST_EXECUTABLE,"exe", "exe,executable" },
{ SLANG_SHADER_SHARED_LIBRARY, "dll,so", "sharedlib,sharedlibrary,dll" },
{ SLANG_CUDA_SOURCE, "cu", "cuda,cu" },
{ SLANG_PTX, "ptx", "ptx" },
{ SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable" },
{ SLANG_OBJECT_CODE, "obj,o", "object-code" },
{ SLANG_HOST_HOST_CALLABLE, "", "host-host-callable" },
};
struct ArchiveTypeInfo
{
SlangArchiveType type;
UnownedStringSlice text;
};
static const ArchiveTypeInfo s_archiveTypeInfos[] =
{
{ SLANG_ARCHIVE_TYPE_RIFF_DEFLATE, UnownedStringSlice::fromLiteral("riff-deflate")},
{ SLANG_ARCHIVE_TYPE_RIFF_LZ4, UnownedStringSlice::fromLiteral("riff-lz4")},
{ SLANG_ARCHIVE_TYPE_ZIP, UnownedStringSlice::fromLiteral("zip")},
{ SLANG_ARCHIVE_TYPE_RIFF, UnownedStringSlice::fromLiteral("riff")},
};
} // anonymous
/* static */SlangArchiveType TypeTextUtil::findArchiveType(const UnownedStringSlice& slice)
{
for (const auto& entry : s_archiveTypeInfos)
{
if (slice == entry.text)
{
return entry.type;
}
}
return SLANG_ARCHIVE_TYPE_UNDEFINED;
}
struct DebugInfoFormatTable
{
UnownedStringSlice entries[SLANG_DEBUG_INFO_FORMAT_COUNT_OF];
static DebugInfoFormatTable _makeTable()
{
DebugInfoFormatTable dst;
#define SLANG_DEBUG_INFO_FORMAT_ENTRY(name, value) \
dst.entries[SLANG_DEBUG_INFO_FORMAT_##value] = toSlice(#name);
SLANG_DEBUG_INFO_FORMATS(SLANG_DEBUG_INFO_FORMAT_ENTRY)
return dst;
}
static Index findIndex(const UnownedStringSlice slice) { return makeConstArrayView(table.entries).indexOf(slice); }
static UnownedStringSlice getSlice(SlangDebugInfoFormat format) { return table.entries[Index(format)]; }
static const DebugInfoFormatTable table;
};
/* static */const DebugInfoFormatTable DebugInfoFormatTable::table = DebugInfoFormatTable::_makeTable();
/* static */SlangResult TypeTextUtil::findDebugInfoFormat(const Slang::UnownedStringSlice& text, SlangDebugInfoFormat& out)
{
const auto index = DebugInfoFormatTable::findIndex(text);
if (index >= 0)
{
out = SlangDebugInfoFormat(index);
return SLANG_OK;
}
return SLANG_FAIL;
}
/* static */UnownedStringSlice TypeTextUtil::getDebugInfoFormatName(SlangDebugInfoFormat format) { return DebugInfoFormatTable::getSlice(format); }
/* static */UnownedStringSlice TypeTextUtil::getScalarTypeName(slang::TypeReflection::ScalarType scalarType)
{
typedef slang::TypeReflection::ScalarType ScalarType;
switch (scalarType)
{
#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) case ScalarType::value: return UnownedStringSlice::fromLiteral(#text);
SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_TO_TEXT)
default: break;
}
return UnownedStringSlice();
}
/* static */slang::TypeReflection::ScalarType TypeTextUtil::findScalarType(const UnownedStringSlice& inText)
{
for (Index i = 0; i < SLANG_COUNT_OF(s_scalarTypeInfos); ++i)
{
const auto& info = s_scalarTypeInfos[i];
if (info.text == inText)
{
return info.type;
}
}
return slang::TypeReflection::ScalarType::None;
}
#define SLANG_PASS_THROUGH_HUMAN_TEXT(x) \
x(NONE, "Unknown") \
x(VISUAL_STUDIO, "Visual Studio") \
x(GCC, "GCC") \
x(CLANG, "Clang") \
x(NVRTC, "NVRTC") \
x(FXC, "fxc") \
x(DXC, "dxc") \
x(GLSLANG, "glslang") \
x(LLVM, "LLVM/Clang")
/* static */UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
{
#define SLANG_PASS_THROUGH_HUMAN_CASE(value, text) case SLANG_PASS_THROUGH_##value: return UnownedStringSlice::fromLiteral(text);
switch (type)
{
default: /* fall-through to none */
SLANG_PASS_THROUGH_HUMAN_TEXT(SLANG_PASS_THROUGH_HUMAN_CASE)
}
}
/* static */SlangResult TypeTextUtil::findPassThroughFromHumanText(const UnownedStringSlice& inText, SlangPassThrough& outPassThrough)
{
#define SLANG_PASS_THROUGH_HUMAN_IF(value, text) if (inText == UnownedStringSlice::fromLiteral(text)) { outPassThrough = SLANG_PASS_THROUGH_##value; return SLANG_OK; } else
SLANG_PASS_THROUGH_HUMAN_TEXT(SLANG_PASS_THROUGH_HUMAN_IF)
return SLANG_FAIL;
}
/* static */SlangSourceLanguage TypeTextUtil::findSourceLanguage(const UnownedStringSlice& text)
{
if (text == "c" || text == "C")
{
return SLANG_SOURCE_LANGUAGE_C;
}
else if (text == "cpp" || text == "c++" || text == "C++" || text == "cxx")
{
return SLANG_SOURCE_LANGUAGE_CPP;
}
else if (text == "slang")
{
return SLANG_SOURCE_LANGUAGE_SLANG;
}
else if (text == "glsl")
{
return SLANG_SOURCE_LANGUAGE_GLSL;
}
else if (text == "hlsl")
{
return SLANG_SOURCE_LANGUAGE_HLSL;
}
else if (text == "cu" || text == "cuda")
{
return SLANG_SOURCE_LANGUAGE_CUDA;
}
return SLANG_SOURCE_LANGUAGE_UNKNOWN;
}
/* static */SlangPassThrough TypeTextUtil::findPassThrough(const UnownedStringSlice& slice)
{
#define SLANG_PASS_THROUGH_NAME_TO_TYPE(x, y) \
if (slice == UnownedStringSlice::fromLiteral(#x)) return SLANG_PASS_THROUGH_##y;
SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_NAME_TO_TYPE)
// Other options
if (slice == "c" || slice == "cpp")
{
return SLANG_PASS_THROUGH_GENERIC_C_CPP;
}
else if (slice == "vs")
{
return SLANG_PASS_THROUGH_VISUAL_STUDIO;
}
return SLANG_PASS_THROUGH_NONE;
}
/* static */SlangResult TypeTextUtil::findPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough)
{
outPassThrough = findPassThrough(slice);
// It could be none on error - if it's not equal to "none" then it must be an error
if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none"))
{
return SLANG_FAIL;
}
return SLANG_OK;
}
/* static */UnownedStringSlice TypeTextUtil::getPassThroughName(SlangPassThrough passThru)
{
#define SLANG_PASS_THROUGH_TYPE_TO_NAME(x, y) \
case SLANG_PASS_THROUGH_##y: return UnownedStringSlice::fromLiteral(#x);
switch (passThru)
{
SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_TYPE_TO_NAME)
default: break;
}
return UnownedStringSlice::fromLiteral("unknown");
}
/* static */SlangCompileTarget TypeTextUtil::findCompileTargetFromExtension(const UnownedStringSlice& slice)
{
if (slice.getLength())
{
for (const auto& info : s_compileTargetInfos)
{
if (StringUtil::indexOfInSplit(UnownedStringSlice(info.extensions), ',', slice) >= 0)
{
return info.target;
}
}
}
return SLANG_TARGET_UNKNOWN;
}
/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromName(const UnownedStringSlice& slice)
{
if (slice.getLength())
{
for (const auto& info : s_compileTargetInfos)
{
if (StringUtil::indexOfInSplit(UnownedStringSlice(info.names), ',', slice) >= 0)
{
return info.target;
}
}
}
return SLANG_TARGET_UNKNOWN;
}
static Index _getTargetInfoIndex(SlangCompileTarget target)
{
for (Index i = 0; i < SLANG_COUNT_OF(s_compileTargetInfos); ++i)
{
if (s_compileTargetInfos[i].target == target)
{
return i;
}
}
return -1;
}
UnownedStringSlice TypeTextUtil::getCompileTargetName(SlangCompileTarget target)
{
const Index index = _getTargetInfoIndex(target);
// Return the first name
return index >= 0 ? StringUtil::getAtInSplit(UnownedStringSlice(s_compileTargetInfos[index].names), ',', 0) : UnownedStringSlice();
}
}