+void
+fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
+{
+ fs_reg *reg = new(this->mem_ctx) fs_reg(this, ir->type);
+ fs_reg wpos = *reg;
+ fs_reg neg_y = this->pixel_y;
+ neg_y.negate = true;
+
+ /* gl_FragCoord.x */
+ if (ir->pixel_center_integer) {
+ emit(fs_inst(BRW_OPCODE_MOV, wpos, this->pixel_x));
+ } else {
+ emit(fs_inst(BRW_OPCODE_ADD, wpos, this->pixel_x, fs_reg(0.5f)));
+ }
+ wpos.reg_offset++;
+
+ /* gl_FragCoord.y */
+ if (ir->origin_upper_left && ir->pixel_center_integer) {
+ emit(fs_inst(BRW_OPCODE_MOV, wpos, this->pixel_y));
+ } else {
+ fs_reg pixel_y = this->pixel_y;
+ float offset = (ir->pixel_center_integer ? 0.0 : 0.5);
+
+ if (!ir->origin_upper_left) {
+ pixel_y.negate = true;
+ offset += c->key.drawable_height - 1.0;
+ }
+
+ emit(fs_inst(BRW_OPCODE_ADD, wpos, pixel_y, fs_reg(offset)));
+ }
+ wpos.reg_offset++;
+
+ /* gl_FragCoord.z */
+ emit(fs_inst(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
+ interp_reg(FRAG_ATTRIB_WPOS, 2)));
+ wpos.reg_offset++;
+
+ /* gl_FragCoord.w: Already set up in emit_interpolation */
+ emit(fs_inst(BRW_OPCODE_MOV, wpos, this->wpos_w));
+
+ hash_table_insert(this->variable_ht, reg, ir);
+}
+