return type == BRW_REGISTER_TYPE_F ? imm.f == 1.0 : imm.i == 1;
}
+bool
+fs_reg::is_null() const
+{
+ return file == HW_REG &&
+ fixed_hw_reg.file == BRW_ARCHITECTURE_REGISTER_FILE &&
+ fixed_hw_reg.nr == BRW_ARF_NULL;
+}
+
bool
fs_reg::is_valid_3src() const
{
return 1;
}
+bool
+fs_inst::reads_flag()
+{
+ return predicate;
+}
+
+bool
+fs_inst::writes_flag()
+{
+ return (conditional_mod && opcode != BRW_OPCODE_SEL) ||
+ opcode == FS_OPCODE_MOV_DISPATCH_TO_FLAGS;
+}
+
/**
* Returns how many MRFs an FS opcode will write over.
*
case FS_OPCODE_FB_WRITE:
return 2;
case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD:
- case FS_OPCODE_UNSPILL:
+ case SHADER_OPCODE_GEN4_SCRATCH_READ:
return 1;
case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD:
return inst->mlen;
- case FS_OPCODE_SPILL:
+ case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
return 2;
+ case SHADER_OPCODE_UNTYPED_ATOMIC:
+ case SHADER_OPCODE_UNTYPED_SURFACE_READ:
+ return 0;
default:
assert(!"not reached");
return inst->mlen;
return reg;
}
+void
+fs_visitor::compute_sample_position(fs_reg dst, fs_reg int_sample_pos)
+{
+ assert(dst.type == BRW_REGISTER_TYPE_F);
+
+ if (c->key.compute_pos_offset) {
+ /* Convert int_sample_pos to floating point */
+ emit(MOV(dst, int_sample_pos));
+ /* Scale to the range [0, 1] */
+ emit(MUL(dst, dst, fs_reg(1 / 16.0f)));
+ }
+ else {
+ /* From ARB_sample_shading specification:
+ * "When rendering to a non-multisample buffer, or if multisample
+ * rasterization is disabled, gl_SamplePosition will always be
+ * (0.5, 0.5).
+ */
+ emit(MOV(dst, fs_reg(0.5f)));
+ }
+}
+
+fs_reg *
+fs_visitor::emit_samplepos_setup(ir_variable *ir)
+{
+ assert(brw->gen >= 6);
+ assert(ir->type == glsl_type::vec2_type);
+
+ this->current_annotation = "compute sample position";
+ fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
+ fs_reg pos = *reg;
+ fs_reg int_sample_x = fs_reg(this, glsl_type::int_type);
+ fs_reg int_sample_y = fs_reg(this, glsl_type::int_type);
+
+ /* WM will be run in MSDISPMODE_PERSAMPLE. So, only one of SIMD8 or SIMD16
+ * mode will be enabled.
+ *
+ * From the Ivy Bridge PRM, volume 2 part 1, page 344:
+ * R31.1:0 Position Offset X/Y for Slot[3:0]
+ * R31.3:2 Position Offset X/Y for Slot[7:4]
+ * .....
+ *
+ * The X, Y sample positions come in as bytes in thread payload. So, read
+ * the positions using vstride=16, width=8, hstride=2.
+ */
+ struct brw_reg sample_pos_reg =
+ stride(retype(brw_vec1_grf(c->sample_pos_reg, 0),
+ BRW_REGISTER_TYPE_B), 16, 8, 2);
+
+ emit(MOV(int_sample_x, fs_reg(sample_pos_reg)));
+ if (dispatch_width == 16) {
+ int_sample_x.sechalf = true;
+ fs_inst *inst = emit(MOV(int_sample_x,
+ fs_reg(suboffset(sample_pos_reg, 16))));
+ inst->force_sechalf = true;
+ int_sample_x.sechalf = false;
+ }
+ /* Compute gl_SamplePosition.x */
+ compute_sample_position(pos, int_sample_x);
+ pos.reg_offset++;
+ emit(MOV(int_sample_y, fs_reg(suboffset(sample_pos_reg, 1))));
+ if (dispatch_width == 16) {
+ int_sample_y.sechalf = true;
+ fs_inst *inst = emit(MOV(int_sample_y,
+ fs_reg(suboffset(sample_pos_reg, 17))));
+ inst->force_sechalf = true;
+ int_sample_y.sechalf = false;
+ }
+ /* Compute gl_SamplePosition.y */
+ compute_sample_position(pos, int_sample_y);
+ return reg;
+}
+
fs_reg
fs_visitor::fix_math_operand(fs_reg src)
{
break;
}
break;
+ case BRW_OPCODE_OR:
+ if (inst->src[0].equals(inst->src[1])) {
+ inst->opcode = BRW_OPCODE_MOV;
+ inst->src[1] = reg_undef;
+ progress = true;
+ break;
+ }
+ break;
+ case BRW_OPCODE_SEL:
+ if (inst->saturate && inst->src[1].file == IMM) {
+ switch (inst->conditional_mod) {
+ case BRW_CONDITIONAL_LE:
+ case BRW_CONDITIONAL_L:
+ switch (inst->src[1].type) {
+ case BRW_REGISTER_TYPE_F:
+ if (inst->src[1].imm.f >= 1.0f) {
+ inst->opcode = BRW_OPCODE_MOV;
+ inst->src[1] = reg_undef;
+ progress = true;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case BRW_CONDITIONAL_GE:
+ case BRW_CONDITIONAL_G:
+ switch (inst->src[1].type) {
+ case BRW_REGISTER_TYPE_F:
+ if (inst->src[1].imm.f <= 0.0f) {
+ inst->opcode = BRW_OPCODE_MOV;
+ inst->src[1] = reg_undef;
+ inst->conditional_mod = BRW_CONDITIONAL_NONE;
+ progress = true;
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ break;
default:
break;
}
c->nr_payload_regs++;
}
}
+
+ c->prog_data.uses_pos_offset = c->key.compute_pos_offset;
/* R31: MSAA position offsets. */
+ if (c->prog_data.uses_pos_offset) {
+ c->sample_pos_reg = c->nr_payload_regs;
+ c->nr_payload_regs++;
+ }
+
/* R32-: bary for 32-pixel. */
/* R58-59: interp W for 32-pixel. */
split_virtual_grfs();
move_uniform_array_access_to_pull_constants();
+ remove_dead_constants();
setup_pull_constants();
bool progress;
progress = compute_to_mrf() || progress;
} while (progress);
- remove_dead_constants();
-
schedule_instructions(false);
lower_uniform_pull_constant_loads();
assign_curb_setup();
assign_urb_setup();
- if (0) {
- /* Debug of register spilling: Go spill everything. */
- for (int i = 0; i < virtual_grf_count; i++) {
- spill_reg(i);
- }
- }
-
if (0)
assign_regs_trivial();
else {