mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 22:10:10 +01:00
r600/sfn: correct handling of loading vec4 with fetching constants
Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5963>
This commit is contained in:
parent
aca99e6fc9
commit
d31ef0b7a4
4 changed files with 53 additions and 18 deletions
|
|
@ -93,9 +93,9 @@ EmitInstruction::get_deref_location(const nir_src& v) const
|
||||||
return m_proc.get_deref_location(v);
|
return m_proc.get_deref_location(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
PValue EmitInstruction::from_nir_with_fetch_constant(const nir_src& src, unsigned component)
|
PValue EmitInstruction::from_nir_with_fetch_constant(const nir_src& src, unsigned component, int channel)
|
||||||
{
|
{
|
||||||
return m_proc.from_nir_with_fetch_constant(src, component);
|
return m_proc.from_nir_with_fetch_constant(src, component, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPRVector EmitInstruction::vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
GPRVector EmitInstruction::vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ protected:
|
||||||
std::vector<PValue> src0,
|
std::vector<PValue> src0,
|
||||||
const std::set<AluModifiers>& m_flags);
|
const std::set<AluModifiers>& m_flags);
|
||||||
|
|
||||||
PValue from_nir_with_fetch_constant(const nir_src& src, unsigned component);
|
PValue from_nir_with_fetch_constant(const nir_src& src, unsigned component, int channel = -1);
|
||||||
GPRVector vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
GPRVector vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
||||||
const GPRVector::Swizzle& swizzle, bool match = false);
|
const GPRVector::Swizzle& swizzle, bool match = false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -746,48 +746,83 @@ GPRVector ShaderFromNirProcessor::vec_from_nir_with_fetch_constant(const nir_src
|
||||||
bool use_same = true;
|
bool use_same = true;
|
||||||
GPRVector::Values v;
|
GPRVector::Values v;
|
||||||
|
|
||||||
|
std::array<bool,4> used_swizzles = {false, false, false, false};
|
||||||
|
|
||||||
|
/* Check whether all sources come from a GPR, and,
|
||||||
|
* if requested, whether they are swizzled as epected */
|
||||||
|
|
||||||
for (int i = 0; i < 4 && use_same; ++i) {
|
for (int i = 0; i < 4 && use_same; ++i) {
|
||||||
if ((1 << i) & mask) {
|
if ((1 << i) & mask) {
|
||||||
if (swizzle[i] < 4) {
|
if (swizzle[i] < 4) {
|
||||||
v[i] = from_nir(src, swizzle[i]);
|
v[i] = from_nir(src, swizzle[i]);
|
||||||
assert(v[i]);
|
assert(v[i]);
|
||||||
if (v[i]->type() != Value::gpr)
|
use_same &= (v[i]->type() == Value::gpr);
|
||||||
use_same = false;
|
if (match) {
|
||||||
if (match && (v[i]->chan() != swizzle[i]))
|
use_same &= (v[i]->chan() == swizzle[i]);
|
||||||
use_same = false;
|
}
|
||||||
|
used_swizzles[v[i]->chan()] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now check whether all inputs come from the same GPR, and fill
|
||||||
|
* empty slots in the vector with unused swizzles, bail out if
|
||||||
|
* the sources are not from the same GPR
|
||||||
|
*/
|
||||||
|
|
||||||
if (use_same) {
|
if (use_same) {
|
||||||
|
int next_free_swizzle = 0;
|
||||||
|
while (used_swizzles[next_free_swizzle] && next_free_swizzle < 4)
|
||||||
|
next_free_swizzle++;
|
||||||
|
|
||||||
|
/* Find the first GPR index used */
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!v[i] && i < 4) ++i;
|
while (!v[i] && i < 4) ++i;
|
||||||
assert(i < 4);
|
assert(i < 4);
|
||||||
|
|
||||||
unsigned sel = v[i]->sel();
|
unsigned sel = v[i]->sel();
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 4 && use_same; ++i) {
|
for (i = 0; i < 4 && use_same; ++i) {
|
||||||
if (!v[i])
|
if (!v[i]) {
|
||||||
v[i] = PValue(new GPRValue(sel, swizzle[i]));
|
if (swizzle[i] >= 4)
|
||||||
|
v[i] = PValue(new GPRValue(sel, swizzle[i]));
|
||||||
|
else {
|
||||||
|
assert(next_free_swizzle < 4);
|
||||||
|
v[i] = PValue(new GPRValue(sel, next_free_swizzle));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swizzle[i] < 4) {
|
||||||
|
used_swizzles[next_free_swizzle] = true;
|
||||||
|
while (next_free_swizzle < 4 && used_swizzles[swizzle[next_free_swizzle]])
|
||||||
|
next_free_swizzle++;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
use_same &= v[i]->sel() == sel;
|
use_same &= v[i]->sel() == sel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We can't re-use the source data because they either need re-swizzling, or
|
||||||
|
* they didn't come all from a GPR or the same GPR, so copy to a new vector
|
||||||
|
*/
|
||||||
if (!use_same) {
|
if (!use_same) {
|
||||||
AluInstruction *ir = nullptr;
|
AluInstruction *ir = nullptr;
|
||||||
int sel = allocate_temp_register();
|
GPRVector result(allocate_temp_register(), swizzle);
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
v[i] = PValue(new GPRValue(sel, swizzle[i]));
|
|
||||||
if (swizzle[i] < 4 && (mask & (1 << i))) {
|
if (swizzle[i] < 4 && (mask & (1 << i))) {
|
||||||
ir = new AluInstruction(op1_mov, v[i], from_nir(src, swizzle[i]),
|
ir = new AluInstruction(op1_mov, result[i], from_nir(src, swizzle[i]),
|
||||||
EmitInstruction::write);
|
EmitInstruction::write);
|
||||||
emit_instruction(ir);
|
emit_instruction(ir);
|
||||||
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ir)
|
if (ir)
|
||||||
ir->set_flag(alu_last_instr);
|
ir->set_flag(alu_last_instr);
|
||||||
}
|
return result;
|
||||||
return GPRVector(v);;
|
} else
|
||||||
|
return GPRVector(v);;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderFromNirProcessor::emit_load_ubo(nir_intrinsic_instr* instr)
|
bool ShaderFromNirProcessor::emit_load_ubo(nir_intrinsic_instr* instr)
|
||||||
|
|
@ -983,13 +1018,13 @@ AluInstruction *ShaderFromNirProcessor::emit_load_literal(const nir_load_const_i
|
||||||
return ir;
|
return ir;
|
||||||
}
|
}
|
||||||
|
|
||||||
PValue ShaderFromNirProcessor::from_nir_with_fetch_constant(const nir_src& src, unsigned component)
|
PValue ShaderFromNirProcessor::from_nir_with_fetch_constant(const nir_src& src, unsigned component, int channel)
|
||||||
{
|
{
|
||||||
PValue value = from_nir(src, component);
|
PValue value = from_nir(src, component);
|
||||||
if (value->type() != Value::gpr &&
|
if (value->type() != Value::gpr &&
|
||||||
value->type() != Value::gpr_vector &&
|
value->type() != Value::gpr_vector &&
|
||||||
value->type() != Value::gpr_array_value) {
|
value->type() != Value::gpr_array_value) {
|
||||||
PValue retval = get_temp_register();
|
PValue retval = get_temp_register(channel);
|
||||||
emit_instruction(new AluInstruction(op1_mov, retval, value,
|
emit_instruction(new AluInstruction(op1_mov, retval, value,
|
||||||
EmitInstruction::last_write));
|
EmitInstruction::last_write));
|
||||||
value = retval;
|
value = retval;
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
void emit_instruction(Instruction *ir);
|
void emit_instruction(Instruction *ir);
|
||||||
|
|
||||||
PValue from_nir_with_fetch_constant(const nir_src& src, unsigned component);
|
PValue from_nir_with_fetch_constant(const nir_src& src, unsigned component, int channel = -1);
|
||||||
GPRVector vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
GPRVector vec_from_nir_with_fetch_constant(const nir_src& src, unsigned mask,
|
||||||
const GPRVector::Swizzle& swizzle, bool match = false);
|
const GPRVector::Swizzle& swizzle, bool match = false);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue