blob: a971694ad2af1dbf89f969f4224b580947dcf4c3 [file] [log] [blame]
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01001#include <libspirv/libspirv.h>
2
3#include <string.h>
4
Lei Zhang2d879b92015-08-27 11:22:14 -04005/// Generate a spv_ext_inst_desc_t literal for a GLSL std450 extended
6/// instruction with one/two/three <id> parameter(s).
7#define GLSL450Inst1(name) \
Lei Zhangdca65b32015-08-27 10:00:16 -04008 #name, GLSLstd450::GLSLstd450##name, { SPV_OPERAND_TYPE_ID }
Lei Zhang2d879b92015-08-27 11:22:14 -04009#define GLSL450Inst2(name) \
Lei Zhangdca65b32015-08-27 10:00:16 -040010 #name, GLSLstd450::GLSLstd450##name, { \
11 SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID \
12 }
Lei Zhang2d879b92015-08-27 11:22:14 -040013#define GLSL450Inst3(name) \
Lei Zhangdca65b32015-08-27 10:00:16 -040014 #name, GLSLstd450::GLSLstd450##name, { \
15 SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID \
16 }
Andrew Woloszyn1d2a87e2015-08-21 13:39:34 -040017
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010018static const spv_ext_inst_desc_t glslStd450Entries[] = {
Lei Zhang2d879b92015-08-27 11:22:14 -040019 {GLSL450Inst1(Round)},
20 {GLSL450Inst1(RoundEven)},
21 {GLSL450Inst1(Trunc)},
22 {GLSL450Inst1(FAbs)},
23 {GLSL450Inst1(SAbs)},
24 {GLSL450Inst1(FSign)},
25 {GLSL450Inst1(SSign)},
26 {GLSL450Inst1(Floor)},
27 {GLSL450Inst1(Ceil)},
28 {GLSL450Inst1(Fract)},
29 {GLSL450Inst1(Radians)},
30 {GLSL450Inst1(Degrees)},
31 {GLSL450Inst1(Sin)},
32 {GLSL450Inst1(Cos)},
33 {GLSL450Inst1(Tan)},
34 {GLSL450Inst1(Asin)},
35 {GLSL450Inst1(Acos)},
36 {GLSL450Inst1(Atan)},
37 {GLSL450Inst1(Sinh)},
38 {GLSL450Inst1(Cosh)},
39 {GLSL450Inst1(Tanh)},
40 {GLSL450Inst1(Asinh)},
41 {GLSL450Inst1(Acosh)},
42 {GLSL450Inst1(Atanh)},
43 {GLSL450Inst2(Atan2)},
44 {GLSL450Inst2(Pow)},
45 {GLSL450Inst1(Exp)},
46 {GLSL450Inst1(Log)},
47 {GLSL450Inst1(Exp2)},
48 {GLSL450Inst1(Log2)},
49 {GLSL450Inst1(Sqrt)},
Lei Zhangdca65b32015-08-27 10:00:16 -040050 // clang-format off
51 {"Inversesqrt", GLSLstd450::GLSLstd450InverseSqrt, {SPV_OPERAND_TYPE_ID}},
Lei Zhang2d879b92015-08-27 11:22:14 -040052 {GLSL450Inst1(Determinant)},
Lei Zhangdca65b32015-08-27 10:00:16 -040053 {"Inverse", GLSLstd450::GLSLstd450MatrixInverse, {SPV_OPERAND_TYPE_ID}},
54 // clang-format on
Lei Zhang2d879b92015-08-27 11:22:14 -040055 {GLSL450Inst2(Modf)},
56 {GLSL450Inst1(ModfStruct)},
57 {GLSL450Inst2(FMin)},
58 {GLSL450Inst2(UMin)},
59 {GLSL450Inst2(SMin)},
60 {GLSL450Inst2(FMax)},
61 {GLSL450Inst2(UMax)},
62 {GLSL450Inst2(SMax)},
63 {GLSL450Inst3(FClamp)},
64 {GLSL450Inst3(UClamp)},
65 {GLSL450Inst3(SClamp)},
66 {GLSL450Inst3(Mix)},
67 {GLSL450Inst2(Step)},
Lei Zhangdca65b32015-08-27 10:00:16 -040068 // clang-format off
69 {"Smoothstep", GLSLstd450::GLSLstd450SmoothStep, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}},
70 // clang-format on
Lei Zhang2d879b92015-08-27 11:22:14 -040071 {GLSL450Inst3(Fma)},
72 {GLSL450Inst2(Frexp)},
73 {GLSL450Inst1(FrexpStruct)},
74 {GLSL450Inst2(Ldexp)},
Lei Zhang3cb58962015-08-27 13:44:31 -040075 {GLSL450Inst1(Length)},
76 {GLSL450Inst2(Distance)},
77 {GLSL450Inst2(Cross)},
78 {GLSL450Inst1(Normalize)},
79 // clang-format off
80 {"Faceforward", GLSLstd450::GLSLstd450FaceForward, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}},
81 // clang-format on
82 {GLSL450Inst2(Reflect)},
83 {GLSL450Inst3(Refract)},
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010084 // TODO: Add remaining GLSL.std.450 instructions
85};
86
87static const spv_ext_inst_desc_t openclStd12Entries[] = {
88 {"placeholder", 0, {}},
89 // TODO: Add remaining OpenCL.std.12 instructions
90};
91
92static const spv_ext_inst_desc_t openclStd20Entries[] = {
93 {"placeholder", 0, {}},
94 // TODO: Add remaining OpenCL.std.20 instructions
95};
96
97static const spv_ext_inst_desc_t openclStd21Entries[] = {
98 {"placeholder", 0, {}},
99 // TODO: Add remaining OpenCL.std.21 instructions
100};
101
102spv_result_t spvExtInstTableGet(spv_ext_inst_table *pExtInstTable) {
103 spvCheck(!pExtInstTable, return SPV_ERROR_INVALID_POINTER);
104
105 static const spv_ext_inst_group_t groups[] = {
106 {SPV_EXT_INST_TYPE_GLSL_STD_450,
107 sizeof(glslStd450Entries) / sizeof(spv_ext_inst_desc_t),
108 glslStd450Entries},
109 {SPV_EXT_INST_TYPE_OPENCL_STD_12,
110 sizeof(openclStd12Entries) / sizeof(spv_ext_inst_desc_t),
111 openclStd12Entries},
112 {SPV_EXT_INST_TYPE_OPENCL_STD_20,
113 sizeof(openclStd20Entries) / sizeof(spv_ext_inst_desc_t),
114 openclStd20Entries},
115 {SPV_EXT_INST_TYPE_OPENCL_STD_21,
116 sizeof(openclStd21Entries) / sizeof(spv_ext_inst_desc_t),
117 openclStd21Entries},
118 };
119
120 static const spv_ext_inst_table_t table = {
121 sizeof(groups) / sizeof(spv_ext_inst_group_t), groups};
122
123 *pExtInstTable = &table;
124
125 return SPV_SUCCESS;
126}
127
128spv_ext_inst_type_t spvExtInstImportTypeGet(const char *name) {
129 if (!strcmp("GLSL.std.450", name)) {
130 return SPV_EXT_INST_TYPE_GLSL_STD_450;
131 }
132 if (!strcmp("OpenCL.std.12", name)) {
133 return SPV_EXT_INST_TYPE_OPENCL_STD_12;
134 }
135 if (!strcmp("OpenCL.std.20", name)) {
136 return SPV_EXT_INST_TYPE_OPENCL_STD_20;
137 }
138 if (!strcmp("OpenCL.std.21", name)) {
139 return SPV_EXT_INST_TYPE_OPENCL_STD_21;
140 }
141 return SPV_EXT_INST_TYPE_NONE;
142}
143
144spv_result_t spvExtInstTableNameLookup(const spv_ext_inst_table table,
145 const spv_ext_inst_type_t type,
146 const char *name,
147 spv_ext_inst_desc *pEntry) {
148 spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
149 spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
150
151 for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) {
152 auto &group = table->groups[groupIndex];
153 if (type == group.type) {
154 for (uint32_t index = 0; index < group.count; index++) {
155 auto &entry = group.entries[index];
156 if (!strcmp(name, entry.name)) {
157 *pEntry = &table->groups[groupIndex].entries[index];
158 return SPV_SUCCESS;
159 }
160 }
161 }
162 }
163
164 return SPV_ERROR_INVALID_LOOKUP;
165}
166
167spv_result_t spvExtInstTableValueLookup(const spv_ext_inst_table table,
168 const spv_ext_inst_type_t type,
169 const uint32_t value,
170 spv_ext_inst_desc *pEntry) {
171 spvCheck(!table, return SPV_ERROR_INVALID_TABLE);
172 spvCheck(!pEntry, return SPV_ERROR_INVALID_POINTER);
173
174 for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) {
175 auto &group = table->groups[groupIndex];
176 if (type == group.type) {
177 for (uint32_t index = 0; index < group.count; index++) {
178 auto &entry = group.entries[index];
179 if (value == entry.ext_inst) {
180 *pEntry = &table->groups[groupIndex].entries[index];
181 return SPV_SUCCESS;
182 }
183 }
184 }
185 }
186
187 return SPV_ERROR_INVALID_LOOKUP;
188}