#include "brw_context.h"
#include "brw_eu.h"
#include "brw_wm.h"
+#include "brw_cs.h"
#include "brw_vec4.h"
#include "brw_fs.h"
#include "main/uniforms.h"
}
}
+void
+fs_visitor::emit_uniformize(const fs_reg &dst, const fs_reg &src)
+{
+ const fs_reg chan_index = vgrf(glsl_type::uint_type);
+
+ emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, component(chan_index, 0))
+ ->force_writemask_all = true;
+ emit(SHADER_OPCODE_BROADCAST, component(dst, 0),
+ src, component(chan_index, 0))
+ ->force_writemask_all = true;
+}
+
bool
fs_visitor::try_emit_saturate(ir_expression *ir)
{
}
break;
case ir_binop_imul_high: {
- if (devinfo->gen == 7)
+ if (devinfo->gen >= 7)
no16("SIMD16 explicit accumulator operands unsupported\n");
struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
mul->src[1].type == BRW_REGISTER_TYPE_UD);
if (mul->src[1].type == BRW_REGISTER_TYPE_D) {
mul->src[1].type = BRW_REGISTER_TYPE_W;
+ mul->src[1].stride = 2;
} else {
mul->src[1].type = BRW_REGISTER_TYPE_UW;
+ mul->src[1].stride = 2;
}
}
emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
break;
case ir_binop_carry: {
- if (devinfo->gen == 7)
+ if (devinfo->gen >= 7)
no16("SIMD16 explicit accumulator operands unsupported\n");
struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
break;
}
case ir_binop_borrow: {
- if (devinfo->gen == 7)
+ if (devinfo->gen >= 7)
no16("SIMD16 explicit accumulator operands unsupported\n");
struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
const_uniform_block->value.u[0]);
} else {
/* The block index is not a constant. Evaluate the index expression
- * per-channel and add the base UBO index; the generator will select
- * a value from any live channel.
+ * per-channel and add the base UBO index; we have to select a value
+ * from any live channel.
*/
surf_index = vgrf(glsl_type::uint_type);
emit(ADD(surf_index, op[0],
- fs_reg(stage_prog_data->binding_table.ubo_start)))
- ->force_writemask_all = true;
+ fs_reg(stage_prog_data->binding_table.ubo_start)));
+ emit_uniformize(surf_index, surf_index);
/* Assume this may touch any UBO. It would be nice to provide
* a tighter bound, but the array information is already lowered away.
/* Emit the instruction. */
fs_inst *inst = emit(SHADER_OPCODE_UNTYPED_ATOMIC, dst, src_payload,
- fs_reg(atomic_op), fs_reg(surf_index));
+ fs_reg(surf_index), fs_reg(atomic_op));
inst->mlen = mlen;
}
/* Emit the instruction. */
inst = emit(SHADER_OPCODE_UNTYPED_SURFACE_READ, dst, src_payload,
- fs_reg(surf_index));
+ fs_reg(surf_index), fs_reg(1));
inst->mlen = mlen;
}
*reg = temp;
}
+void
+fs_visitor::emit_cs_terminate()
+{
+ assert(brw->gen >= 7);
+
+ /* We are getting the thread ID from the compute shader header */
+ assert(stage == MESA_SHADER_COMPUTE);
+
+ /* We can't directly send from g0, since sends with EOT have to use
+ * g112-127. So, copy it to a virtual register, The register allocator will
+ * make sure it uses the appropriate register range.
+ */
+ struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD);
+ fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
+ fs_inst *inst = emit(MOV(payload, g0));
+ inst->force_writemask_all = true;
+
+ /* Send a message to the thread spawner to terminate the thread. */
+ inst = emit(CS_OPCODE_CS_TERMINATE, reg_undef, payload);
+ inst->eot = true;
+}
+
/**
* Resolve the result of a Gen4-5 CMP instruction to a proper boolean.
*
init();
}
+fs_visitor::fs_visitor(struct brw_context *brw,
+ void *mem_ctx,
+ const struct brw_cs_prog_key *key,
+ struct brw_cs_prog_data *prog_data,
+ struct gl_shader_program *shader_prog,
+ struct gl_compute_program *cp,
+ unsigned dispatch_width)
+ : backend_visitor(brw, shader_prog, &cp->Base, &prog_data->base,
+ MESA_SHADER_COMPUTE),
+ reg_null_f(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_F)),
+ reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
+ reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
+ key(key), prog_data(&prog_data->base),
+ dispatch_width(dispatch_width)
+{
+ this->mem_ctx = mem_ctx;
+ init();
+}
+
void
fs_visitor::init()
{
case MESA_SHADER_GEOMETRY:
key_tex = &((const brw_vue_prog_key *) key)->tex;
break;
+ case MESA_SHADER_COMPUTE:
+ key_tex = &((const brw_cs_prog_key*) key)->tex;
+ break;
default:
unreachable("unhandled shader stage");
}