07f84f0c73fa38ae4f4ba88579cc2da7d0c1092a
[mesa.git] / src / gallium / state_trackers / d3d1x / d3d1xshader / include / sm4.h
1 /**************************************************************************
2 *
3 * Copyright 2010 Luca Barbieri
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 **************************************************************************/
26
27 /* Header for Shader Model 4.0, 4.1 and 5.0 */
28
29 #ifndef SM4_H_
30 #define SM4_H_
31
32 #include <stdint.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <memory>
36 #include <vector>
37 #include <map>
38 #include <iostream>
39 #include "le32.h"
40
41 #include "sm4_defs.h"
42
43 extern const char* sm4_opcode_names[];
44 extern const char* sm4_file_names[];
45 extern const char* sm4_file_ms_names[];
46 extern const char* sm4_target_names[];
47 extern const char* sm4_interpolation_names[];
48 extern const char* sm4_sv_names[];
49
50 struct sm4_token_version
51 {
52 unsigned minor : 4;
53 unsigned major : 4;
54 unsigned format : 8;
55 unsigned type : 16;
56 };
57
58 struct sm4_token_instruction
59 {
60 // we don't make it an union directly because unions can't be inherited from
61 union
62 {
63 // length and extended are always present, but they are only here to reduce duplication
64 struct
65 {
66 unsigned opcode : 11;
67 unsigned _11_23 : 13;
68 unsigned length : 7;
69 unsigned extended : 1;
70 };
71 struct
72 {
73 unsigned opcode : 11;
74 unsigned resinfo_return_type : 2;
75 unsigned sat : 1;
76 unsigned _14_17 : 4;
77 unsigned test_nz : 1; // bit 18
78 unsigned precise_mask : 4;
79 unsigned _23 : 1;
80 unsigned length : 7;
81 unsigned extended : 1;
82 } insn;
83 struct
84 {
85 unsigned opcode : 11;
86 unsigned threads_in_group : 1;
87 unsigned shared_memory : 1;
88 unsigned uav_group : 1;
89 unsigned uav_global : 1;
90 unsigned _15_17 : 3;
91 } sync;
92 struct
93 {
94 unsigned opcode : 11;
95 unsigned allow_refactoring : 1;
96 unsigned fp64 : 1;
97 unsigned early_depth_stencil : 1;
98 unsigned enable_raw_and_structured_in_non_cs : 1;
99 } dcl_global_flags;
100 struct
101 {
102 unsigned opcode : 11;
103 unsigned target : 5;
104 unsigned nr_samples : 7;
105 } dcl_resource;
106 struct
107 {
108 unsigned opcode : 11;
109 unsigned shadow : 1;
110 unsigned mono : 1;
111 } dcl_sampler;
112 struct
113 {
114 unsigned opcode : 11;
115 unsigned interpolation : 5;
116 } dcl_input_ps;
117 struct
118 {
119 unsigned opcode : 11;
120 unsigned dynamic : 1;
121 } dcl_constant_buffer;
122 struct
123 {
124 unsigned opcode : 11;
125 unsigned primitive : 6;
126 } dcl_gs_input_primitive;
127 struct
128 {
129 unsigned opcode : 11;
130 unsigned primitive_topology : 7;
131 } dcl_gs_output_primitive_topology;
132 struct
133 {
134 unsigned opcode : 11;
135 unsigned control_points : 6;
136 } dcl_input_control_point_count;
137 struct
138 {
139 unsigned opcode : 11;
140 unsigned control_points : 6;
141 } dcl_output_control_point_count;
142 struct
143 {
144 unsigned opcode : 11;
145 unsigned domain : 3; /* D3D_TESSELLATOR_DOMAIN */
146 } dcl_tess_domain;
147 struct
148 {
149 unsigned opcode : 11;
150 unsigned partitioning : 3; /* D3D_TESSELLATOR_PARTITIONING */
151 } dcl_tess_partitioning;
152 struct
153 {
154 unsigned opcode : 11;
155 unsigned primitive : 3; /* D3D_TESSELLATOR_OUTPUT_PRIMITIVE */
156 } dcl_tess_output_primitive;
157 };
158 };
159
160 union sm4_token_instruction_extended
161 {
162 struct
163 {
164 unsigned type : 6;
165 unsigned _6_30 : 25;
166 unsigned extended :1;
167 };
168 struct
169 {
170 unsigned type : 6;
171 unsigned _6_8 : 3;
172 int offset_u : 4;
173 int offset_v : 4;
174 int offset_w : 4;
175 } sample_controls;
176 struct
177 {
178 unsigned type : 6;
179 unsigned target : 5;
180 } resource_target;
181 struct
182 {
183 unsigned type : 6;
184 unsigned x : 4;
185 unsigned y : 4;
186 unsigned z : 4;
187 unsigned w : 4;
188 } resource_return_type;
189 };
190
191 struct sm4_token_resource_return_type
192 {
193 unsigned x : 4;
194 unsigned y : 4;
195 unsigned z : 4;
196 unsigned w : 4;
197 };
198
199 struct sm4_token_operand
200 {
201 unsigned comps_enum : 2; /* sm4_operands_comps */
202 unsigned mode : 2; /* sm4_operand_mode */
203 unsigned sel : 8;
204 unsigned file : 8; /* sm4_file */
205 unsigned num_indices : 2;
206 unsigned index0_repr : 3; /* sm4_operand_index_repr */
207 unsigned index1_repr : 3; /* sm4_operand_index_repr */
208 unsigned index2_repr : 3; /* sm4_operand_index_repr */
209 unsigned extended : 1;
210 };
211
212 #define SM4_OPERAND_SEL_MASK(sel) ((sel) & 0xf)
213 #define SM4_OPERAND_SEL_SWZ(sel, i) (((sel) >> ((i) * 2)) & 3)
214 #define SM4_OPERAND_SEL_SCALAR(sel) ((sel) & 3)
215
216 struct sm4_token_operand_extended
217 {
218 unsigned type : 6;
219 unsigned neg : 1;
220 unsigned abs : 1;
221 };
222
223 union sm4_any
224 {
225 double f64;
226 float f32;
227 int64_t i64;
228 int32_t i32;
229 uint64_t u64;
230 int64_t u32;
231 };
232
233 struct sm4_op;
234 struct sm4_insn;
235 struct sm4_dcl;
236 struct sm4_program;
237 std::ostream& operator <<(std::ostream& out, const sm4_op& op);
238 std::ostream& operator <<(std::ostream& out, const sm4_insn& op);
239 std::ostream& operator <<(std::ostream& out, const sm4_dcl& op);
240 std::ostream& operator <<(std::ostream& out, const sm4_program& op);
241
242 struct sm4_op
243 {
244 uint8_t mode;
245 uint8_t comps;
246 uint8_t mask;
247 uint8_t num_indices;
248 uint8_t swizzle[4];
249 sm4_file file;
250 sm4_any imm_values[4];
251 bool neg;
252 bool abs;
253 struct
254 {
255 int64_t disp;
256 std::auto_ptr<sm4_op> reg;
257 } indices[3];
258
259 bool is_index_simple(unsigned i) const
260 {
261 return !indices[i].reg.get() && indices[i].disp >= 0 && (int64_t)(int32_t)indices[i].disp == indices[i].disp;
262 }
263
264 bool has_simple_index() const
265 {
266 return num_indices == 1 && is_index_simple(0);
267 }
268
269 sm4_op()
270 {
271 memset(this, 0, sizeof(*this));
272 }
273
274 void dump();
275
276 private:
277 sm4_op(const sm4_op& op)
278 {}
279 };
280
281 /* for sample_d */
282 #define SM4_MAX_OPS 6
283
284 struct sm4_insn : public sm4_token_instruction
285 {
286 int8_t sample_offset[3];
287 uint8_t resource_target;
288 uint8_t resource_return_type[4];
289
290 unsigned num;
291 unsigned num_ops;
292 std::auto_ptr<sm4_op> ops[SM4_MAX_OPS];
293
294 sm4_insn()
295 {
296 memset(this, 0, sizeof(*this));
297 }
298
299 void dump();
300
301 private:
302 sm4_insn(const sm4_insn& op)
303 {}
304 };
305
306 struct sm4_dcl : public sm4_token_instruction
307 {
308 std::auto_ptr<sm4_op> op;
309 union
310 {
311 unsigned num;
312 float f32;
313 sm4_sv sv;
314 struct
315 {
316 unsigned id;
317 unsigned expected_function_table_length;
318 unsigned table_length;
319 unsigned array_length;
320 } intf;
321 unsigned thread_group_size[3];
322 sm4_token_resource_return_type rrt;
323 struct
324 {
325 unsigned num;
326 unsigned comps;
327 } indexable_temp;
328 struct
329 {
330 unsigned stride;
331 unsigned count;
332 } structured;
333 };
334
335 void* data;
336
337 sm4_dcl()
338 {
339 memset(this, 0, sizeof(*this));
340 }
341
342 ~sm4_dcl()
343 {
344 free(data);
345 }
346
347 void dump();
348
349 private:
350 sm4_dcl(const sm4_dcl& op)
351 {}
352 };
353
354 struct sm4_program
355 {
356 sm4_token_version version;
357 std::vector<sm4_dcl*> dcls;
358 std::vector<sm4_insn*> insns;
359
360 /* for ifs, the insn number of the else or endif if there is no else
361 * for elses, the insn number of the endif
362 * for endifs, the insn number of the if
363 * for loops, the insn number of the endloop
364 * for endloops, the insn number of the loop
365 * for all others, -1
366 */
367 std::vector<int> cf_insn_linked;
368
369 /* NOTE: sampler 0 is the unnormalized nearest sampler for LD/LD_MS, while
370 * sampler 1 is user-specified sampler 0
371 */
372 bool resource_sampler_slots_assigned;
373 std::vector<int> slot_to_resource;
374 std::vector<int> slot_to_sampler;
375 std::map<std::pair<int, int>, int> resource_sampler_to_slot;
376 std::map<int, int> resource_to_slot;
377
378 bool labels_found;
379 std::vector<int> label_to_insn_num;
380
381 sm4_program()
382 {
383 memset(&version, 0, sizeof(version));
384 labels_found = false;
385 resource_sampler_slots_assigned = false;
386 }
387
388 ~sm4_program()
389 {
390 for(std::vector<sm4_dcl*>::iterator i = dcls.begin(), e = dcls.end(); i != e; ++i)
391 delete *i;
392 for(std::vector<sm4_insn*>::iterator i = insns.begin(), e = insns.end(); i != e; ++i)
393 delete *i;
394 }
395
396 void dump();
397
398 private:
399 sm4_program(const sm4_dcl& op)
400 {}
401 };
402
403 sm4_program* sm4_parse(void* tokens, int size);
404
405 bool sm4_link_cf_insns(sm4_program& program);
406 bool sm4_find_labels(sm4_program& program);
407 bool sm4_allocate_resource_sampler_pairs(sm4_program& program);
408
409 #endif /* SM4_H_ */
410