Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/microsoft/compiler/dxil_function.c
4564 views
1
/*
2
* Copyright © Microsoft Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "dxil_function.h"
25
#include "dxil_module.h"
26
27
#define MAX_FUNC_PARAMS 17
28
29
struct predefined_func_descr {
30
const char *base_name;
31
const char *retval_descr;
32
const char *param_descr;
33
enum dxil_attr_kind attr;
34
};
35
36
static struct predefined_func_descr predefined_funcs[] = {
37
{"dx.op.atomicBinOp", "O", "i@iiiii", DXIL_ATTR_KIND_READ_NONE},
38
{"dx.op.cbufferLoad", "O", "i@ii", DXIL_ATTR_KIND_READ_ONLY},
39
{"dx.op.cbufferLoadLegacy", "B", "i@i", DXIL_ATTR_KIND_READ_ONLY},
40
{"dx.op.createHandle", "@", "iciib", DXIL_ATTR_KIND_READ_ONLY},
41
{"dx.op.storeOutput", "v", "iiicO", DXIL_ATTR_KIND_NO_UNWIND},
42
{"dx.op.loadInput", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
43
{"dx.op.tertiary", "O", "iOOO", DXIL_ATTR_KIND_READ_NONE},
44
{"dx.op.threadId", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
45
{"dx.op.threadIdInGroup", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
46
{"dx.op.groupId", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
47
{"dx.op.unary", "O", "iO", DXIL_ATTR_KIND_READ_NONE},
48
{"dx.op.unaryBits", "i", "iO", DXIL_ATTR_KIND_READ_NONE},
49
{"dx.op.isSpecialFloat", "b", "iO", DXIL_ATTR_KIND_READ_NONE},
50
{"dx.op.binary", "O", "iOO", DXIL_ATTR_KIND_READ_NONE},
51
{"dx.op.bufferStore", "v", "i@iiOOOOc", DXIL_ATTR_KIND_NONE},
52
{"dx.op.bufferLoad", "R", "i@ii", DXIL_ATTR_KIND_READ_ONLY},
53
{"dx.op.attributeAtVertex", "O", "iiicc", DXIL_ATTR_KIND_READ_NONE},
54
{"dx.op.sample", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
55
{"dx.op.sampleBias", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY},
56
{"dx.op.sampleLevel", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
57
{"dx.op.sampleGrad", "R", "i@@ffffiiifffffff", DXIL_ATTR_KIND_READ_ONLY},
58
{"dx.op.sampleCmp", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY},
59
{"dx.op.sampleCmpLevelZero", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
60
{"dx.op.textureLoad", "R", "i@iiiiiii", DXIL_ATTR_KIND_READ_ONLY},
61
{"dx.op.discard", "v", "ib", DXIL_ATTR_KIND_READ_NONE},
62
{"dx.op.emitStream", "v", "ic", DXIL_ATTR_KIND_NONE},
63
{"dx.op.cutStream", "v", "ic", DXIL_ATTR_KIND_NONE},
64
{"dx.op.getDimensions", "D", "i@i", DXIL_ATTR_KIND_READ_ONLY},
65
{"dx.op.calculateLOD", "f", "i@@fffb", DXIL_ATTR_KIND_READ_ONLY},
66
{"dx.op.barrier", "v", "ii", DXIL_ATTR_KIND_NO_DUPLICATE},
67
{"dx.op.atomicCompareExchange", "O", "i@iiiii", DXIL_ATTR_KIND_READ_NONE},
68
{"dx.op.textureStore", "v", "i@iiiOOOOc", DXIL_ATTR_KIND_NONE},
69
{"dx.op.primitiveID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
70
{"dx.op.legacyF16ToF32", "f", "ii", DXIL_ATTR_KIND_READ_ONLY},
71
{"dx.op.legacyF32ToF16", "i", "if", DXIL_ATTR_KIND_READ_ONLY},
72
{"dx.op.makeDouble", "g", "iii", DXIL_ATTR_KIND_READ_NONE},
73
{"dx.op.splitDouble", "G", "ig", DXIL_ATTR_KIND_READ_NONE},
74
};
75
76
struct func_descr {
77
const char *name;
78
enum overload_type overload;
79
};
80
81
struct func_rb_node {
82
struct rb_node node;
83
const struct dxil_func *func;
84
struct func_descr descr;
85
};
86
87
static inline
88
const struct func_rb_node *
89
func_rb_node(const struct rb_node *n)
90
{
91
return (const struct func_rb_node *)n;
92
}
93
94
static int
95
func_compare_to_name_and_overload(const struct rb_node *node, const void *data)
96
{
97
const struct func_descr *descr = (const struct func_descr *)data;
98
const struct func_rb_node *f = func_rb_node(node);
99
if (f->descr.overload < descr->overload)
100
return -1;
101
if (f->descr.overload > descr->overload)
102
return 1;
103
104
return strcmp(f->descr.name, descr->name);
105
}
106
107
static const struct dxil_func *
108
allocate_function_from_predefined(struct dxil_module *mod,
109
const char *name,
110
enum overload_type overload)
111
{
112
for (unsigned i = 0; i < ARRAY_SIZE(predefined_funcs); ++i) {
113
if (!strcmp(predefined_funcs[i].base_name, name)) {
114
return dxil_alloc_func(mod, name, overload,
115
predefined_funcs[i].retval_descr,
116
predefined_funcs[i].param_descr,
117
predefined_funcs[i].attr);
118
}
119
}
120
return false;
121
}
122
123
const struct dxil_func *
124
dxil_get_function(struct dxil_module *mod,
125
const char *name, enum overload_type overload)
126
{
127
struct func_descr descr = { name, overload };
128
const struct rb_node *node = rb_tree_search(mod->functions, &descr,
129
func_compare_to_name_and_overload);
130
if (node)
131
return func_rb_node(node)->func;
132
133
return allocate_function_from_predefined(mod, name, overload);
134
}
135
136
static int func_compare_name(const struct rb_node *lhs, const struct rb_node *rhs)
137
{
138
const struct func_rb_node *node = func_rb_node(rhs);
139
return func_compare_to_name_and_overload(lhs, &node->descr);
140
}
141
142
static void
143
dxil_add_function(struct rb_tree *functions, const struct dxil_func *func,
144
const char *name, enum overload_type overload)
145
{
146
struct func_rb_node *f = rzalloc(functions, struct func_rb_node);
147
f->func = func;
148
f->descr.name = name;
149
f->descr.overload = overload;
150
rb_tree_insert(functions, &f->node, func_compare_name);
151
}
152
153
static const struct dxil_type *
154
get_type_from_string(struct dxil_module *mod, const char *param_descr,
155
enum overload_type overload, int *idx)
156
{
157
assert(param_descr);
158
char type_id = param_descr[(*idx)++];
159
assert(*idx <= (int)strlen(param_descr));
160
161
switch (type_id) {
162
case DXIL_FUNC_PARAM_INT64: return dxil_module_get_int_type(mod, 64);
163
case DXIL_FUNC_PARAM_INT32: return dxil_module_get_int_type(mod, 32);
164
case DXIL_FUNC_PARAM_INT16: return dxil_module_get_int_type(mod, 16);
165
case DXIL_FUNC_PARAM_INT8: return dxil_module_get_int_type(mod, 8);
166
case DXIL_FUNC_PARAM_BOOL: return dxil_module_get_int_type(mod, 1);
167
case DXIL_FUNC_PARAM_FLOAT64: return dxil_module_get_float_type(mod, 64);
168
case DXIL_FUNC_PARAM_FLOAT32: return dxil_module_get_float_type(mod, 32);
169
case DXIL_FUNC_PARAM_FLOAT16: return dxil_module_get_float_type(mod, 16);
170
case DXIL_FUNC_PARAM_HANDLE: return dxil_module_get_handle_type(mod);
171
case DXIL_FUNC_PARAM_VOID: return dxil_module_get_void_type(mod);
172
case DXIL_FUNC_PARAM_FROM_OVERLOAD: return dxil_get_overload_type(mod, overload);
173
case DXIL_FUNC_PARAM_RESRET: return dxil_module_get_resret_type(mod, overload);
174
case DXIL_FUNC_PARAM_DIM: return dxil_module_get_dimret_type(mod);
175
case DXIL_FUNC_PARAM_CBUF_RET: return dxil_module_get_cbuf_ret_type(mod, overload);
176
case DXIL_FUNC_PARAM_SPLIT_DOUBLE: return dxil_module_get_split_double_ret_type(mod);
177
case DXIL_FUNC_PARAM_POINTER: {
178
const struct dxil_type *target = get_type_from_string(mod, param_descr, overload, idx);
179
return dxil_module_get_pointer_type(mod, target);
180
}
181
default:
182
assert(0 && "unknown type identifier");
183
}
184
return NULL;
185
}
186
187
const struct dxil_func *
188
dxil_alloc_func_with_rettype(struct dxil_module *mod, const char *name,
189
enum overload_type overload,
190
const struct dxil_type *retval_type,
191
const char *param_descr,
192
enum dxil_attr_kind attr)
193
{
194
assert(param_descr);
195
const struct dxil_type *arg_types[MAX_FUNC_PARAMS];
196
197
int index = 0;
198
unsigned num_params = 0;
199
200
while (param_descr[num_params]) {
201
const struct dxil_type *t = get_type_from_string(mod, param_descr, overload, &index);
202
if (!t)
203
return false;
204
assert(num_params < MAX_FUNC_PARAMS);
205
arg_types[num_params++] = t;
206
}
207
208
const struct dxil_type *func_type =
209
dxil_module_add_function_type(mod, retval_type,
210
arg_types, num_params);
211
if (!func_type) {
212
fprintf(stderr, "%s: Func type allocation failed\n", __func__);
213
return false;
214
}
215
216
char full_name[100];
217
snprintf(full_name, sizeof (full_name), "%s%s%s", name,
218
overload == DXIL_NONE ? "" : ".", dxil_overload_suffix(overload));
219
const struct dxil_func *func = dxil_add_function_decl(mod, full_name, func_type, attr);
220
221
if (func)
222
dxil_add_function(mod->functions, func, name, overload);
223
224
return func;
225
}
226
227
const struct dxil_func *
228
dxil_alloc_func(struct dxil_module *mod, const char *name, enum overload_type overload,
229
const char *retval_type_descr,
230
const char *param_descr, enum dxil_attr_kind attr)
231
{
232
233
int index = 0;
234
const struct dxil_type *retval_type = get_type_from_string(mod, retval_type_descr, overload, &index);
235
assert(retval_type_descr[index] == 0);
236
237
return dxil_alloc_func_with_rettype(mod, name, overload, retval_type,
238
param_descr, attr);
239
}
240
241