| #include <libspirv/libspirv.h> |
| |
| #include <string.h> |
| |
| /// Generate a spv_ext_inst_desc_t literal for a GLSL std450 extended |
| /// instruction with one/two/three <id> parameter(s). |
| #define GLSL450Inst1(name) \ |
| #name, GLSLstd450::GLSLstd450##name, { SPV_OPERAND_TYPE_ID } |
| #define GLSL450Inst2(name) \ |
| #name, GLSLstd450::GLSLstd450##name, { \ |
| SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID \ |
| } |
| #define GLSL450Inst3(name) \ |
| #name, GLSLstd450::GLSLstd450##name, { \ |
| SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID \ |
| } |
| |
| static const spv_ext_inst_desc_t glslStd450Entries[] = { |
| {GLSL450Inst1(Round)}, |
| {GLSL450Inst1(RoundEven)}, |
| {GLSL450Inst1(Trunc)}, |
| {GLSL450Inst1(FAbs)}, |
| {GLSL450Inst1(SAbs)}, |
| {GLSL450Inst1(FSign)}, |
| {GLSL450Inst1(SSign)}, |
| {GLSL450Inst1(Floor)}, |
| {GLSL450Inst1(Ceil)}, |
| {GLSL450Inst1(Fract)}, |
| {GLSL450Inst1(Radians)}, |
| {GLSL450Inst1(Degrees)}, |
| {GLSL450Inst1(Sin)}, |
| {GLSL450Inst1(Cos)}, |
| {GLSL450Inst1(Tan)}, |
| {GLSL450Inst1(Asin)}, |
| {GLSL450Inst1(Acos)}, |
| {GLSL450Inst1(Atan)}, |
| {GLSL450Inst1(Sinh)}, |
| {GLSL450Inst1(Cosh)}, |
| {GLSL450Inst1(Tanh)}, |
| {GLSL450Inst1(Asinh)}, |
| {GLSL450Inst1(Acosh)}, |
| {GLSL450Inst1(Atanh)}, |
| {GLSL450Inst2(Atan2)}, |
| {GLSL450Inst2(Pow)}, |
| {GLSL450Inst1(Exp)}, |
| {GLSL450Inst1(Log)}, |
| {GLSL450Inst1(Exp2)}, |
| {GLSL450Inst1(Log2)}, |
| {GLSL450Inst1(Sqrt)}, |
| {GLSL450Inst1(InverseSqrt)}, |
| {GLSL450Inst1(Determinant)}, |
| {GLSL450Inst1(MatrixInverse)}, |
| {GLSL450Inst2(Modf)}, |
| {GLSL450Inst1(ModfStruct)}, |
| {GLSL450Inst2(FMin)}, |
| {GLSL450Inst2(UMin)}, |
| {GLSL450Inst2(SMin)}, |
| {GLSL450Inst2(FMax)}, |
| {GLSL450Inst2(UMax)}, |
| {GLSL450Inst2(SMax)}, |
| {GLSL450Inst3(FClamp)}, |
| {GLSL450Inst3(UClamp)}, |
| {GLSL450Inst3(SClamp)}, |
| {GLSL450Inst3(FMix)}, |
| {GLSL450Inst3(IMix)}, |
| {GLSL450Inst2(Step)}, |
| {GLSL450Inst3(SmoothStep)}, |
| {GLSL450Inst3(Fma)}, |
| {GLSL450Inst2(Frexp)}, |
| {GLSL450Inst1(FrexpStruct)}, |
| {GLSL450Inst2(Ldexp)}, |
| {GLSL450Inst1(PackSnorm4x8)}, |
| {GLSL450Inst1(PackUnorm4x8)}, |
| {GLSL450Inst1(PackSnorm2x16)}, |
| {GLSL450Inst1(PackUnorm2x16)}, |
| {GLSL450Inst1(PackHalf2x16)}, |
| {GLSL450Inst1(PackDouble2x32)}, |
| {GLSL450Inst1(UnpackSnorm2x16)}, |
| {GLSL450Inst1(UnpackUnorm2x16)}, |
| {GLSL450Inst1(UnpackHalf2x16)}, |
| {GLSL450Inst1(UnpackSnorm4x8)}, |
| {GLSL450Inst1(UnpackUnorm4x8)}, |
| {GLSL450Inst1(UnpackDouble2x32)}, |
| {GLSL450Inst1(Length)}, |
| {GLSL450Inst2(Distance)}, |
| {GLSL450Inst2(Cross)}, |
| {GLSL450Inst1(Normalize)}, |
| {GLSL450Inst3(FaceForward)}, |
| {GLSL450Inst2(Reflect)}, |
| {GLSL450Inst3(Refract)}, |
| {GLSL450Inst1(FindILsb)}, |
| {GLSL450Inst1(FindSMsb)}, |
| {GLSL450Inst1(FindUMsb)}, |
| {GLSL450Inst1(InterpolateAtCentroid)}, |
| {GLSL450Inst2(InterpolateAtSample)}, |
| {GLSL450Inst2(InterpolateAtOffset)}, |
| }; |
| |
| static const spv_ext_inst_desc_t openclStd12Entries[] = { |
| {"placeholder", 0, {}}, |
| // TODO: Add remaining OpenCL.std.12 instructions |
| }; |
| |
| static const spv_ext_inst_desc_t openclStd20Entries[] = { |
| {"placeholder", 0, {}}, |
| // TODO: Add remaining OpenCL.std.20 instructions |
| }; |
| |
| static const spv_ext_inst_desc_t openclStd21Entries[] = { |
| {"placeholder", 0, {}}, |
| // TODO: Add remaining OpenCL.std.21 instructions |
| }; |
| |
| spv_result_t spvExtInstTableGet(spv_ext_inst_table *pExtInstTable) { |
| if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER; |
| |
| static const spv_ext_inst_group_t groups[] = { |
| {SPV_EXT_INST_TYPE_GLSL_STD_450, |
| sizeof(glslStd450Entries) / sizeof(spv_ext_inst_desc_t), |
| glslStd450Entries}, |
| {SPV_EXT_INST_TYPE_OPENCL_STD_12, |
| sizeof(openclStd12Entries) / sizeof(spv_ext_inst_desc_t), |
| openclStd12Entries}, |
| {SPV_EXT_INST_TYPE_OPENCL_STD_20, |
| sizeof(openclStd20Entries) / sizeof(spv_ext_inst_desc_t), |
| openclStd20Entries}, |
| {SPV_EXT_INST_TYPE_OPENCL_STD_21, |
| sizeof(openclStd21Entries) / sizeof(spv_ext_inst_desc_t), |
| openclStd21Entries}, |
| }; |
| |
| static const spv_ext_inst_table_t table = { |
| sizeof(groups) / sizeof(spv_ext_inst_group_t), groups}; |
| |
| *pExtInstTable = &table; |
| |
| return SPV_SUCCESS; |
| } |
| |
| spv_ext_inst_type_t spvExtInstImportTypeGet(const char *name) { |
| if (!strcmp("GLSL.std.450", name)) { |
| return SPV_EXT_INST_TYPE_GLSL_STD_450; |
| } |
| if (!strcmp("OpenCL.std.12", name)) { |
| return SPV_EXT_INST_TYPE_OPENCL_STD_12; |
| } |
| if (!strcmp("OpenCL.std.20", name)) { |
| return SPV_EXT_INST_TYPE_OPENCL_STD_20; |
| } |
| if (!strcmp("OpenCL.std.21", name)) { |
| return SPV_EXT_INST_TYPE_OPENCL_STD_21; |
| } |
| return SPV_EXT_INST_TYPE_NONE; |
| } |
| |
| spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table, |
| const spv_ext_inst_type_t type, |
| const char *name, |
| spv_ext_inst_desc *pEntry) { |
| if (!table) return SPV_ERROR_INVALID_TABLE; |
| if (!pEntry) return SPV_ERROR_INVALID_POINTER; |
| |
| for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { |
| auto &group = table->groups[groupIndex]; |
| if (type == group.type) { |
| for (uint32_t index = 0; index < group.count; index++) { |
| auto &entry = group.entries[index]; |
| if (!strcmp(name, entry.name)) { |
| *pEntry = &table->groups[groupIndex].entries[index]; |
| return SPV_SUCCESS; |
| } |
| } |
| } |
| } |
| |
| return SPV_ERROR_INVALID_LOOKUP; |
| } |
| |
| spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table, |
| const spv_ext_inst_type_t type, |
| const uint32_t value, |
| spv_ext_inst_desc *pEntry) { |
| if (!table) return SPV_ERROR_INVALID_TABLE; |
| if (!pEntry) return SPV_ERROR_INVALID_POINTER; |
| |
| for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) { |
| auto &group = table->groups[groupIndex]; |
| if (type == group.type) { |
| for (uint32_t index = 0; index < group.count; index++) { |
| auto &entry = group.entries[index]; |
| if (value == entry.ext_inst) { |
| *pEntry = &table->groups[groupIndex].entries[index]; |
| return SPV_SUCCESS; |
| } |
| } |
| } |
| } |
| |
| return SPV_ERROR_INVALID_LOOKUP; |
| } |