1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2018 Collabora LTD
4 *
5 * Author: Gert Wollny <gert.wollny@collabora.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #include "sfn_instruction_fetch.h"
28
29 #include "gallium/drivers/r600/r600_pipe.h"
30
31 namespace r600 {
32
33 /* refactor this to add status create methods for specific tasks */
FetchInstruction(EVFetchInstr op,EVFetchType type,GPRVector dst,PValue src,int offset,int buffer_id,PValue buffer_offset,EBufferIndexMode cp_rel,bool use_const_field)34 FetchInstruction::FetchInstruction(EVFetchInstr op,
35 EVFetchType type,
36 GPRVector dst,
37 PValue src, int offset,
38 int buffer_id, PValue buffer_offset,
39 EBufferIndexMode cp_rel,
40 bool use_const_field):
41 Instruction(vtx),
42 m_vc_opcode(op),
43 m_fetch_type(type),
44 m_endian_swap(vtx_es_none),
45 m_src(src),
46 m_dst(dst),
47 m_offset(offset),
48 m_is_mega_fetch(1),
49 m_mega_fetch_count(16),
50 m_buffer_id(buffer_id),
51 m_semantic_id(0),
52 m_buffer_index_mode(cp_rel),
53 m_flags(0),
54 m_uncached(false),
55 m_indexed(false),
56 m_array_base(0),
57 m_array_size(0),
58 m_elm_size(0),
59 m_buffer_offset(buffer_offset),
60 m_dest_swizzle({0,1,2,3})
61 {
62 if (use_const_field) {
63 m_flags.set(vtx_use_const_field);
64 m_data_format = fmt_invalid;
65 m_num_format = vtx_nf_norm;
66 } else {
67 m_flags.set(vtx_format_comp_signed);
68 m_data_format = fmt_32_32_32_32_float;
69 m_num_format = vtx_nf_scaled;
70 }
71
72 add_remappable_src_value(&m_src);
73 add_remappable_src_value(&m_buffer_offset);
74
75 add_remappable_dst_value(&m_dst);
76 }
77
78 /* Resource query */
FetchInstruction(EVFetchInstr vc_opcode,EVFetchType fetch_type,EVTXDataFormat data_format,EVFetchNumFormat num_format,EVFetchEndianSwap endian_swap,const PValue src,const GPRVector dst,uint32_t offset,bool is_mega_fetch,uint32_t mega_fetch_count,uint32_t buffer_id,uint32_t semantic_id,EBufferIndexMode buffer_index_mode,bool uncached,bool indexed,int array_base,int array_size,int elm_size,PValue buffer_offset,const std::array<int,4> & dest_swizzle)79 FetchInstruction::FetchInstruction(EVFetchInstr vc_opcode,
80 EVFetchType fetch_type,
81 EVTXDataFormat data_format,
82 EVFetchNumFormat num_format,
83 EVFetchEndianSwap endian_swap,
84 const PValue src,
85 const GPRVector dst,
86 uint32_t offset,
87 bool is_mega_fetch,
88 uint32_t mega_fetch_count,
89 uint32_t buffer_id,
90 uint32_t semantic_id,
91
92 EBufferIndexMode buffer_index_mode,
93 bool uncached,
94 bool indexed,
95 int array_base,
96 int array_size,
97 int elm_size,
98 PValue buffer_offset,
99 const std::array<int, 4>& dest_swizzle):
100 Instruction(vtx),
101 m_vc_opcode(vc_opcode),
102 m_fetch_type(fetch_type),
103 m_data_format(data_format),
104 m_num_format(num_format),
105 m_endian_swap(endian_swap),
106 m_src(src),
107 m_dst(dst),
108 m_offset(offset),
109 m_is_mega_fetch(is_mega_fetch),
110 m_mega_fetch_count(mega_fetch_count),
111 m_buffer_id(buffer_id),
112 m_semantic_id(semantic_id),
113 m_buffer_index_mode(buffer_index_mode),
114 m_uncached(uncached),
115 m_indexed(indexed),
116 m_array_base(array_base),
117 m_array_size(array_size),
118 m_elm_size(elm_size),
119 m_buffer_offset(buffer_offset),
120 m_dest_swizzle(dest_swizzle)
121 {
122 add_remappable_src_value(&m_src);
123 add_remappable_dst_value(&m_dst);
124 add_remappable_src_value(&m_buffer_offset);
125 }
126
FetchInstruction(GPRVector dst,PValue src,int buffer_id,PValue buffer_offset,EVTXDataFormat format,EVFetchNumFormat num_format)127 FetchInstruction::FetchInstruction(GPRVector dst,
128 PValue src,
129 int buffer_id, PValue buffer_offset,
130 EVTXDataFormat format,
131 EVFetchNumFormat num_format):
132 Instruction(vtx),
133 m_vc_opcode(vc_fetch),
134 m_fetch_type(no_index_offset),
135 m_data_format(format),
136 m_num_format(num_format),
137 m_endian_swap(vtx_es_none),
138 m_src(src),
139 m_dst(dst),
140 m_offset(0),
141 m_is_mega_fetch(0),
142 m_mega_fetch_count(0),
143 m_buffer_id(buffer_id),
144 m_semantic_id(0),
145 m_buffer_index_mode(bim_none),
146 m_flags(0),
147 m_uncached(false),
148 m_indexed(false),
149 m_array_base(0),
150 m_array_size(0),
151 m_elm_size(1),
152 m_buffer_offset(buffer_offset),
153 m_dest_swizzle({0,1,2,3})
154 {
155 m_flags.set(vtx_format_comp_signed);
156
157 add_remappable_src_value(&m_src);
158 add_remappable_dst_value(&m_dst);
159 add_remappable_src_value(&m_buffer_offset);
160 }
161
162
163 /* Resource query */
FetchInstruction(GPRVector dst,PValue src,int buffer_id,EBufferIndexMode cp_rel)164 FetchInstruction::FetchInstruction(GPRVector dst,
165 PValue src,
166 int buffer_id,
167 EBufferIndexMode cp_rel):
168 Instruction(vtx),
169 m_vc_opcode(vc_get_buf_resinfo),
170 m_fetch_type(no_index_offset),
171 m_data_format(fmt_32_32_32_32),
172 m_num_format(vtx_nf_norm),
173 m_endian_swap(vtx_es_none),
174 m_src(src),
175 m_dst(dst),
176 m_offset(0),
177 m_is_mega_fetch(0),
178 m_mega_fetch_count(16),
179 m_buffer_id(buffer_id),
180 m_semantic_id(0),
181 m_buffer_index_mode(cp_rel),
182 m_flags(0),
183 m_uncached(false),
184 m_indexed(false),
185 m_array_base(0),
186 m_array_size(0),
187 m_elm_size(0),
188 m_dest_swizzle({0,1,2,3})
189 {
190 m_flags.set(vtx_format_comp_signed);
191 add_remappable_src_value(&m_src);
192 add_remappable_dst_value(&m_dst);
193 add_remappable_src_value(&m_buffer_offset);
194 }
195
FetchInstruction(GPRVector dst,PValue src,int scratch_size)196 FetchInstruction::FetchInstruction(GPRVector dst, PValue src, int scratch_size):
197 Instruction(vtx),
198 m_vc_opcode(vc_read_scratch),
199 m_fetch_type(vertex_data),
200 m_data_format(fmt_32_32_32_32),
201 m_num_format(vtx_nf_int),
202 m_endian_swap(vtx_es_none),
203 m_dst(dst),
204 m_offset(0),
205 m_is_mega_fetch(0),
206 m_mega_fetch_count(16),
207 m_buffer_id(0),
208 m_semantic_id(0),
209 m_buffer_index_mode(bim_none),
210 m_flags(0),
211 m_uncached(true),
212 m_array_base(0),
213 m_array_size(0),
214 m_elm_size(3),
215 m_dest_swizzle({0,1,2,3})
216 {
217 if (src->type() == Value::literal) {
218 const auto& lv = static_cast<const LiteralValue&>(*src);
219 m_array_base = lv.value();
220 m_indexed = false;
221 m_src.reset(new GPRValue(0,0));
222 m_array_size = 0;
223 } else {
224 m_array_base = 0;
225 m_src = src;
226 m_indexed = true;
227 m_array_size = scratch_size - 1;
228 }
229 add_remappable_src_value(&m_src);
230 add_remappable_dst_value(&m_dst);
231 add_remappable_src_value(&m_buffer_offset);
232 }
233
replace_values(const ValueSet & candiates,PValue new_value)234 void FetchInstruction::replace_values(const ValueSet& candiates, PValue new_value)
235 {
236 if (!m_src)
237 return;
238 for (auto c: candiates) {
239 for (int i = 0; i < 4; ++i) {
240 if (*c == *m_dst.reg_i(i))
241 m_dst.set_reg_i(i, new_value);
242 }
243 if (*m_src == *c)
244 m_src = new_value;
245 }
246 }
247
248
is_equal_to(const Instruction & lhs) const249 bool FetchInstruction::is_equal_to(const Instruction& lhs) const
250 {
251 auto& l = static_cast<const FetchInstruction&>(lhs);
252 if (m_src) {
253 if (!l.m_src)
254 return false;
255 if (*m_src != *l.m_src)
256 return false;
257 } else {
258 if (l.m_src)
259 return false;
260 }
261
262 return m_vc_opcode == l.m_vc_opcode &&
263 m_fetch_type == l.m_fetch_type &&
264 m_data_format == l.m_data_format &&
265 m_num_format == l.m_num_format &&
266 m_endian_swap == l.m_endian_swap &&
267 m_dst == l.m_dst &&
268 m_offset == l.m_offset &&
269 m_buffer_id == l.m_buffer_id &&
270 m_semantic_id == l.m_semantic_id &&
271 m_buffer_index_mode == l.m_buffer_index_mode &&
272 m_flags == l.m_flags &&
273 m_indexed == l.m_indexed &&
274 m_uncached == l.m_uncached;
275 }
276
set_format(EVTXDataFormat fmt)277 void FetchInstruction::set_format(EVTXDataFormat fmt)
278 {
279 m_data_format = fmt;
280 }
281
282
set_dest_swizzle(const std::array<int,4> & swz)283 void FetchInstruction::set_dest_swizzle(const std::array<int,4>& swz)
284 {
285 m_dest_swizzle = swz;
286 }
287
prelude_append(Instruction * instr)288 void FetchInstruction::prelude_append(Instruction *instr)
289 {
290 assert(instr);
291 m_prelude.push_back(PInstruction(instr));
292 }
293
prelude() const294 const std::vector<PInstruction>& FetchInstruction::prelude() const
295 {
296 return m_prelude;
297 }
298
LoadFromScratch(GPRVector dst,PValue src,int scratch_size)299 LoadFromScratch::LoadFromScratch(GPRVector dst, PValue src, int scratch_size):
300 FetchInstruction(dst, src, scratch_size)
301 {
302 }
303
FetchGDSOpResult(const GPRVector dst,const PValue src)304 FetchGDSOpResult::FetchGDSOpResult(const GPRVector dst, const PValue src):
305 FetchInstruction(vc_fetch,
306 no_index_offset,
307 fmt_32,
308 vtx_nf_int,
309 vtx_es_none,
310 src,
311 dst,
312 0,
313 false,
314 0xf,
315 R600_IMAGE_IMMED_RESOURCE_OFFSET,
316 0,
317 bim_none,
318 false,
319 false,
320 0,
321 0,
322 0,
323 PValue(),
324 {0,7,7,7})
325 {
326 set_flag(vtx_srf_mode);
327 set_flag(vtx_vpm);
328 }
329
FetchTCSIOParam(GPRVector dst,PValue src,int offset)330 FetchTCSIOParam::FetchTCSIOParam(GPRVector dst, PValue src, int offset):
331 FetchInstruction(vc_fetch,
332 no_index_offset,
333 fmt_32_32_32_32,
334 vtx_nf_scaled,
335 vtx_es_none,
336 src,
337 dst,
338 offset,
339 false,
340 16,
341 R600_LDS_INFO_CONST_BUFFER,
342 0,
343 bim_none,
344 false,
345 false,
346 0,
347 0,
348 0,
349 PValue(),
350 {0,1,2,3})
351 {
352 set_flag(vtx_srf_mode);
353 set_flag(vtx_format_comp_signed);
354 }
355
356
357 static const char *fmt_descr[64] = {
358 "INVALID",
359 "8",
360 "4_4",
361 "3_3_2",
362 "RESERVED_4",
363 "16",
364 "16F",
365 "8_8",
366 "5_6_5",
367 "6_5_5",
368 "1_5_5_5",
369 "4_4_4_4",
370 "5_5_5_1",
371 "32",
372 "32F",
373 "16_16",
374 "16_16F",
375 "8_24",
376 "8_24F",
377 "24_8",
378 "24_8F",
379 "10_11_11",
380 "10_11_11F",
381 "11_11_10",
382 "11_11_10F",
383 "2_10_10_10",
384 "8_8_8_8",
385 "10_10_10_2",
386 "X24_8_32F",
387 "32_32",
388 "32_32F",
389 "16_16_16_16",
390 "16_16_16_16F",
391 "RESERVED_33",
392 "32_32_32_32",
393 "32_32_32_32F",
394 "RESERVED_36",
395 "1",
396 "1_REVERSED",
397 "GB_GR",
398 "BG_RG",
399 "32_AS_8",
400 "32_AS_8_8",
401 "5_9_9_9_SHAREDEXP",
402 "8_8_8",
403 "16_16_16",
404 "16_16_16F",
405 "32_32_32",
406 "32_32_32F",
407 "BC1",
408 "BC2",
409 "BC3",
410 "BC4",
411 "BC5",
412 "APC0",
413 "APC1",
414 "APC2",
415 "APC3",
416 "APC4",
417 "APC5",
418 "APC6",
419 "APC7",
420 "CTX1",
421 "RESERVED_63"
422 };
423
424
do_print(std::ostream & os) const425 void FetchInstruction::do_print(std::ostream& os) const
426 {
427 static const std::string num_format_char[] = {"norm", "int", "scaled"};
428 static const std::string endian_swap_code[] = {
429 "noswap", "8in16", "8in32"
430 };
431 static const char buffer_index_mode_char[] = "_01E";
432 static const char *flag_string[] = {"WQM", "CF", "signed", "no_zero",
433 "nostride", "AC", "TC", "VPM"};
434 switch (m_vc_opcode) {
435 case vc_fetch:
436 os << "Fetch " << m_dst;
437 break;
438 case vc_semantic:
439 os << "Fetch Semantic ID:" << m_semantic_id;
440 break;
441 case vc_get_buf_resinfo:
442 os << "Fetch BufResinfo:" << m_dst;
443 break;
444 case vc_read_scratch:
445 os << "MEM_READ_SCRATCH:" << m_dst;
446 break;
447 default:
448 os << "Fetch ERROR";
449 return;
450 }
451
452 os << ", " << *m_src;
453
454 if (m_offset)
455 os << "+" << m_offset;
456
457 os << " BUFID:" << m_buffer_id
458 << " FMT:(" << fmt_descr[m_data_format]
459 << " " << num_format_char[m_num_format]
460 << " " << endian_swap_code[m_endian_swap]
461 << ")";
462 if (m_buffer_index_mode > 0)
463 os << " IndexMode:" << buffer_index_mode_char[m_buffer_index_mode];
464
465
466 if (m_is_mega_fetch)
467 os << " MFC:" << m_mega_fetch_count;
468 else
469 os << " mfc*:" << m_mega_fetch_count;
470
471 if (m_flags.any()) {
472 os << " Flags:";
473 for( int i = 0; i < vtx_unknwon; ++i) {
474 if (m_flags.test(i))
475 os << ' ' << flag_string[i];
476 }
477 }
478 }
479
480 }
481