r600/sfn: Add support for geometry shader
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_instruction_base.cpp
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
28 #include <algorithm>
29 #include <cassert>
30
31 #include "sfn_instruction_base.h"
32 #include "sfn_liverange.h"
33 #include "sfn_valuepool.h"
34
35 namespace r600 {
36
37 ValueRemapper::ValueRemapper(std::vector<rename_reg_pair>& m,
38 ValueMap& values):
39 m_map(m),
40 m_values(values)
41 {
42 }
43
44 void ValueRemapper::remap(PValue& v)
45 {
46 if (!v)
47 return;
48 if (v->type() == Value::gpr) {
49 v = remap_one_registers(v);
50 } else if (v->type() == Value::gpr_array_value) {
51 GPRArrayValue& val = static_cast<GPRArrayValue&>(*v);
52 auto value = val.value();
53 auto addr = val.indirect();
54 val.reset_value(remap_one_registers(value));
55 if (addr) {
56 if (addr->type() == Value::gpr)
57 val.reset_addr(remap_one_registers(addr));
58 }
59 size_t range_start = val.sel();
60 size_t range_end = range_start + val.array_size();
61 while (range_start < range_end)
62 m_map[range_start++].used = true;
63 }
64 }
65
66 void ValueRemapper::remap(GPRVector& v)
67 {
68 for (int i = 0; i < 4; ++i) {
69 if (v.reg_i(i)) {
70 auto& ns_idx = m_map[v.reg_i(i)->sel()];
71 if (ns_idx.valid)
72 v.set_reg_i(i,m_values.get_or_inject(ns_idx.new_reg, v.reg_i(i)->chan()));
73 m_map[v.reg_i(i)->sel()].used = true;
74 }
75 }
76 }
77
78 PValue ValueRemapper::remap_one_registers(PValue& reg)
79 {
80 auto new_index = m_map[reg->sel()];
81 if (new_index.valid)
82 reg = m_values.get_or_inject(new_index.new_reg, reg->chan());
83 m_map[reg->sel()].used = true;
84 return reg;
85 }
86
87
88 Instruction::Instruction(instr_type t):
89 m_type(t)
90 {
91 }
92
93 Instruction::~Instruction()
94 {
95 }
96
97 void Instruction::print(std::ostream& os) const
98 {
99 os << "OP:";
100 do_print(os);
101 }
102
103
104 void Instruction::remap_registers(ValueRemapper& map)
105 {
106 sfn_log << SfnLog::merge << "REMAP " << *this << "\n";
107 for (auto& v: m_mappable_src_registers)
108 map.remap(*v);
109
110 for (auto& v: m_mappable_src_vectors)
111 map.remap(*v);
112
113 for (auto& v: m_mappable_dst_registers)
114 map.remap(*v);
115
116 for (auto& v: m_mappable_dst_vectors)
117 map.remap(*v);
118 sfn_log << SfnLog::merge << "TO " << *this << "\n\n";
119 }
120
121 void Instruction::add_remappable_src_value(PValue *v)
122 {
123 m_mappable_src_registers.push_back(v);
124 }
125
126 void Instruction::add_remappable_src_value(GPRVector *v)
127 {
128 m_mappable_src_vectors.push_back(v);
129 }
130
131 void Instruction::add_remappable_dst_value(PValue *v)
132 {
133 m_mappable_dst_registers.push_back(v);
134 }
135
136 void Instruction::add_remappable_dst_value(GPRVector *v)
137 {
138 m_mappable_dst_vectors.push_back(v);
139 }
140
141 void Instruction::replace_values(UNUSED const ValueSet& candiates, UNUSED PValue new_value)
142 {
143
144 }
145
146 void Instruction::evalue_liveness(LiverangeEvaluator& eval) const
147 {
148 sfn_log << SfnLog::merge << "Scan " << *this << "\n";
149 for (const auto& s: m_mappable_src_registers)
150 if (*s)
151 eval.record_read(**s);
152
153 for (const auto& s: m_mappable_src_vectors)
154 eval.record_read(*s);
155
156 for (const auto& s: m_mappable_dst_registers)
157 if (*s)
158 eval.record_write(**s);
159
160 for (const auto& s: m_mappable_dst_vectors)
161 eval.record_write(*s);
162
163 do_evalue_liveness(eval);
164 }
165
166 void Instruction::do_evalue_liveness(UNUSED LiverangeEvaluator& eval) const
167 {
168
169 }
170
171 bool operator == (const Instruction& lhs, const Instruction& rhs)
172 {
173 if (rhs.m_type != lhs.m_type)
174 return false;
175
176 return lhs.is_equal_to(rhs);
177 }
178
179 }