return emit_load_scratch(instr);
case nir_intrinsic_store_deref:
return emit_store_deref(instr);
+ case nir_intrinsic_load_uniform:
+ return load_uniform(instr);
case nir_intrinsic_discard:
case nir_intrinsic_discard_if:
return emit_discard_if(instr);
for (unsigned i = 0; i < nir_dest_num_components(instr->dest); ++i) {
int cmp = buf_cmp + i;
assert(cmp < 4);
- auto u = PValue(new UniformValue(512 + buf_offset->u32, cmp, bufid->u32));
+ auto u = PValue(new UniformValue(512 + buf_offset->u32, cmp, bufid->u32 + 1));
if (instr->dest.is_ssa)
load_preloaded_value(instr->dest, i, u);
else {
return true;
} else {
- return load_uniform_indirect(instr, from_nir(instr->src[1], 0, 0), 0, bufid->u32);
+ return load_uniform_indirect(instr, from_nir(instr->src[1], 0, 0), 0, bufid->u32 + 1);
}
} else {
if (buf_offset) {
}
auto ir = new FetchInstruction(vc_fetch, no_index_offset, trgt, addr, 0,
- 0, bufid, bim_zero);
+ 1, bufid, bim_zero);
ir->set_dest_swizzle(swz);
emit_instruction(ir);
return do_emit_load_deref(var, instr);
}
+bool ShaderFromNirProcessor::load_uniform(nir_intrinsic_instr* instr)
+{
+ r600::sfn_log << SfnLog::instr << __func__ << ": emit '"
+ << *reinterpret_cast<nir_instr*>(instr)
+ << "'\n";
+
+
+ /* If the target register is a SSA register and the loading is not
+ * indirect then we can do lazy loading, i.e. the uniform value can
+ * be used directly. Otherwise we have to load the data for real
+ * rigt away.
+ */
+ auto literal = nir_src_as_const_value(instr->src[0]);
+ int base = nir_intrinsic_base(instr);
+
+ if (literal) {
+ AluInstruction *ir = nullptr;
+
+ for (int i = 0; i < instr->num_components ; ++i) {
+ PValue u = PValue(new UniformValue(512 + literal->u32 + base, i));
+ sfn_log << SfnLog::io << "uniform "
+ << instr->dest.ssa.index << " const["<< i << "]: "<< instr->const_index[i] << "\n";
+
+ if (instr->dest.is_ssa)
+ load_preloaded_value(instr->dest, i, u);
+ else {
+ ir = new AluInstruction(op1_mov, from_nir(instr->dest, i),
+ u, {alu_write});
+ emit_instruction(ir);
+ }
+ }
+ if (ir)
+ ir->set_flag(alu_last_instr);
+ } else {
+ PValue addr = from_nir(instr->src[0], 0, 0);
+ return load_uniform_indirect(instr, addr, 16 * base, 0);
+ }
+ return true;
+}
+
bool ShaderFromNirProcessor::load_uniform_indirect(nir_intrinsic_instr* instr, PValue addr, int offest, int bufferid)
{
if (!addr) {
std::array<int, 4> swz = {7,7,7,7};
for (int i = 0; i < 4; ++i) {
trgt.set_reg_i(i, from_nir(instr->dest, i));
- swz[i] = i + nir_intrinsic_component(instr);
+ swz[i] = i;
}
if (addr->type() != Value::gpr) {
addr = trgt.reg_i(0);
}
- /* FIXME: buffer index and index mode are not set correctly */
auto ir = new FetchInstruction(vc_fetch, no_index_offset, trgt, addr, offest,
bufferid, PValue(), bim_none);
ir->set_dest_swizzle(swz);