3 * Copyright (c) 2018 Collabora LTD
5 * Author: Gert Wollny <gert.wollny@collabora.com>
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:
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
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.
27 #include "sfn_instruction_fetch.h"
29 #include "gallium/drivers/r600/r600_pipe.h"
33 /* refactor this to add status create methods for specific tasks */
34 FetchInstruction::FetchInstruction(EVFetchInstr op
,
37 PValue src
, int offset
,
38 int buffer_id
, PValue buffer_offset
,
39 EBufferIndexMode cp_rel
,
40 bool use_const_field
):
44 m_endian_swap(vtx_es_none
),
49 m_mega_fetch_count(16),
50 m_buffer_id(buffer_id
),
52 m_buffer_index_mode(cp_rel
),
59 m_buffer_offset(buffer_offset
),
60 m_dest_swizzle({0,1,2,3})
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
;
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
;
72 add_remappable_src_value(&m_src
);
73 add_remappable_src_value(&m_buffer_offset
);
75 add_remappable_dst_value(&m_dst
);
79 FetchInstruction::FetchInstruction(EVFetchInstr vc_opcode
,
80 EVFetchType fetch_type
,
81 EVTXDataFormat data_format
,
82 EVFetchNumFormat num_format
,
83 EVFetchEndianSwap endian_swap
,
88 uint32_t mega_fetch_count
,
92 EBufferIndexMode buffer_index_mode
,
99 const std::array
<int, 4>& dest_swizzle
):
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
),
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
),
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
)
122 add_remappable_src_value(&m_src
);
123 add_remappable_dst_value(&m_dst
);
124 add_remappable_src_value(&m_buffer_offset
);
127 FetchInstruction::FetchInstruction(GPRVector dst
,
129 int buffer_id
, PValue buffer_offset
,
130 EVTXDataFormat format
,
131 EVFetchNumFormat num_format
):
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
),
142 m_mega_fetch_count(0),
143 m_buffer_id(buffer_id
),
145 m_buffer_index_mode(bim_none
),
152 m_buffer_offset(buffer_offset
),
153 m_dest_swizzle({0,1,2,3})
155 m_flags
.set(vtx_format_comp_signed
);
157 add_remappable_src_value(&m_src
);
158 add_remappable_dst_value(&m_dst
);
159 add_remappable_src_value(&m_buffer_offset
);
164 FetchInstruction::FetchInstruction(GPRVector dst
,
167 EBufferIndexMode cp_rel
):
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
),
178 m_mega_fetch_count(16),
179 m_buffer_id(buffer_id
),
181 m_buffer_index_mode(cp_rel
),
188 m_dest_swizzle({0,1,2,3})
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
);
196 FetchInstruction::FetchInstruction(GPRVector dst
, PValue src
, int scratch_size
):
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
),
206 m_mega_fetch_count(16),
209 m_buffer_index_mode(bim_none
),
215 m_dest_swizzle({0,1,2,3})
217 if (src
->type() == Value::literal
) {
218 const auto& lv
= static_cast<const LiteralValue
&>(*src
);
219 m_array_base
= lv
.value();
221 m_src
.reset(new GPRValue(0,0));
227 m_array_size
= scratch_size
- 1;
229 add_remappable_src_value(&m_src
);
230 add_remappable_dst_value(&m_dst
);
231 add_remappable_src_value(&m_buffer_offset
);
234 void FetchInstruction::replace_values(const ValueSet
& candiates
, PValue new_value
)
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
);
249 bool FetchInstruction::is_equal_to(const Instruction
& lhs
) const
251 auto& l
= static_cast<const FetchInstruction
&>(lhs
);
255 if (*m_src
!= *l
.m_src
)
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
&&
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
;
277 void FetchInstruction::set_format(EVTXDataFormat fmt
)
283 void FetchInstruction::set_dest_swizzle(const std::array
<int,4>& swz
)
285 m_dest_swizzle
= swz
;
288 void FetchInstruction::prelude_append(Instruction
*instr
)
291 m_prelude
.push_back(PInstruction(instr
));
294 const std::vector
<PInstruction
>& FetchInstruction::prelude() const
299 LoadFromScratch::LoadFromScratch(GPRVector dst
, PValue src
, int scratch_size
):
300 FetchInstruction(dst
, src
, scratch_size
)
304 FetchGDSOpResult::FetchGDSOpResult(const GPRVector dst
, const PValue src
):
305 FetchInstruction(vc_fetch
,
315 R600_IMAGE_IMMED_RESOURCE_OFFSET
,
326 set_flag(vtx_srf_mode
);
331 static const char *fmt_descr
[64] = {
399 void FetchInstruction::do_print(std::ostream
& os
) const
401 static const std::string num_format_char
[] = {"norm", "int", "scaled"};
402 static const std::string endian_swap_code
[] = {
403 "noswap", "8in16", "8in32"
405 static const char buffer_index_mode_char
[] = "_01E";
406 static const char *flag_string
[] = {"WQM", "CF", "signed", "no_zero",
408 switch (m_vc_opcode
) {
410 os
<< "Fetch " << m_dst
;
413 os
<< "Fetch Semantic ID:" << m_semantic_id
;
415 case vc_get_buf_resinfo
:
416 os
<< "Fetch BufResinfo:" << m_dst
;
418 case vc_read_scratch
:
419 os
<< "MEM_READ_SCRATCH:" << m_dst
;
426 os
<< ", " << *m_src
;
429 os
<< "+" << m_offset
;
431 os
<< " BUFID:" << m_buffer_id
432 << " FMT:(" << fmt_descr
[m_data_format
]
433 << " " << num_format_char
[m_num_format
]
434 << " " << endian_swap_code
[m_endian_swap
]
436 if (m_buffer_index_mode
> 0)
437 os
<< " IndexMode:" << buffer_index_mode_char
[m_buffer_index_mode
];
441 os
<< " MFC:" << m_mega_fetch_count
;
443 os
<< " mfc*:" << m_mega_fetch_count
;
447 for( int i
= 0; i
< vtx_unknwon
; ++i
) {
449 os
<< ' ' << flag_string
[i
];