+void r600_draw_rectangle(struct blitter_context *blitter,
+ unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth,
+ enum blitter_attrib_type type, const union pipe_color_union *attrib);
+uint32_t r600_translate_stencil_op(int s_op);
+uint32_t r600_translate_fill(uint32_t func);
+unsigned r600_tex_wrap(unsigned wrap);
+unsigned r600_tex_filter(unsigned filter);
+unsigned r600_tex_mipfilter(unsigned filter);
+unsigned r600_tex_compare(unsigned compare);
+
+/*
+ * Helpers for building command buffers
+ */
+
+#define PKT3_SET_CONFIG_REG 0x68
+#define PKT3_SET_CONTEXT_REG 0x69
+#define PKT3_SET_CTL_CONST 0x6F
+#define PKT3_SET_LOOP_CONST 0x6C
+
+#define R600_CONFIG_REG_OFFSET 0x08000
+#define R600_CONTEXT_REG_OFFSET 0x28000
+#define R600_CTL_CONST_OFFSET 0x3CFF0
+#define R600_LOOP_CONST_OFFSET 0X0003E200
+#define EG_LOOP_CONST_OFFSET 0x0003A200
+
+#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8)
+#define PKT3_PREDICATE(x) (((x) >> 0) & 0x1)
+#define PKT3(op, count, predicate) (PKT_TYPE_S(3) | PKT_COUNT_S(count) | PKT3_IT_OPCODE_S(op) | PKT3_PREDICATE(predicate))
+
+#define RADEON_CP_PACKET3_COMPUTE_MODE 0x00000002
+
+/*Evergreen Compute packet3*/
+#define PKT3C(op, count, predicate) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count) | PKT3_PREDICATE(predicate) | RADEON_CP_PACKET3_COMPUTE_MODE)
+
+static INLINE void r600_store_value(struct r600_command_buffer *cb, unsigned value)
+{
+ cb->buf[cb->atom.num_dw++] = value;
+}
+
+static INLINE void r600_store_config_reg_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num)
+{
+ assert(reg < R600_CONTEXT_REG_OFFSET);
+ assert(cb->atom.num_dw+2+num <= cb->max_num_dw);
+ cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CONFIG_REG, num, 0);
+ cb->buf[cb->atom.num_dw++] = (reg - R600_CONFIG_REG_OFFSET) >> 2;
+}
+
+/**
+ * Needs cb->pkt_flags set to RADEON_CP_PACKET3_COMPUTE_MODE for compute
+ * shaders.
+ */
+static INLINE void r600_store_context_reg_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num)
+{
+ assert(reg >= R600_CONTEXT_REG_OFFSET && reg < R600_CTL_CONST_OFFSET);
+ assert(cb->atom.num_dw+2+num <= cb->max_num_dw);
+ cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CONTEXT_REG, num, 0) | cb->pkt_flags;
+ cb->buf[cb->atom.num_dw++] = (reg - R600_CONTEXT_REG_OFFSET) >> 2;
+}
+
+/**
+ * Needs cb->pkt_flags set to RADEON_CP_PACKET3_COMPUTE_MODE for compute
+ * shaders.
+ */
+static INLINE void r600_store_ctl_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num)
+{
+ assert(reg >= R600_CTL_CONST_OFFSET);
+ assert(cb->atom.num_dw+2+num <= cb->max_num_dw);
+ cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_CTL_CONST, num, 0) | cb->pkt_flags;
+ cb->buf[cb->atom.num_dw++] = (reg - R600_CTL_CONST_OFFSET) >> 2;
+}
+
+static INLINE void r600_store_loop_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num)
+{
+ assert(reg >= R600_LOOP_CONST_OFFSET);
+ assert(cb->atom.num_dw+2+num <= cb->max_num_dw);
+ cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_LOOP_CONST, num, 0);
+ cb->buf[cb->atom.num_dw++] = (reg - R600_LOOP_CONST_OFFSET) >> 2;
+}
+
+/**
+ * Needs cb->pkt_flags set to RADEON_CP_PACKET3_COMPUTE_MODE for compute
+ * shaders.
+ */
+static INLINE void eg_store_loop_const_seq(struct r600_command_buffer *cb, unsigned reg, unsigned num)
+{
+ assert(reg >= EG_LOOP_CONST_OFFSET);
+ assert(cb->atom.num_dw+2+num <= cb->max_num_dw);
+ cb->buf[cb->atom.num_dw++] = PKT3(PKT3_SET_LOOP_CONST, num, 0) | cb->pkt_flags;
+ cb->buf[cb->atom.num_dw++] = (reg - EG_LOOP_CONST_OFFSET) >> 2;
+}
+
+static INLINE void r600_store_config_reg(struct r600_command_buffer *cb, unsigned reg, unsigned value)
+{
+ r600_store_config_reg_seq(cb, reg, 1);
+ r600_store_value(cb, value);
+}
+
+static INLINE void r600_store_context_reg(struct r600_command_buffer *cb, unsigned reg, unsigned value)
+{
+ r600_store_context_reg_seq(cb, reg, 1);
+ r600_store_value(cb, value);
+}
+
+static INLINE void r600_store_ctl_const(struct r600_command_buffer *cb, unsigned reg, unsigned value)
+{
+ r600_store_ctl_const_seq(cb, reg, 1);
+ r600_store_value(cb, value);
+}
+
+static INLINE void r600_store_loop_const(struct r600_command_buffer *cb, unsigned reg, unsigned value)
+{
+ r600_store_loop_const_seq(cb, reg, 1);
+ r600_store_value(cb, value);
+}
+
+static INLINE void eg_store_loop_const(struct r600_command_buffer *cb, unsigned reg, unsigned value)
+{
+ eg_store_loop_const_seq(cb, reg, 1);
+ r600_store_value(cb, value);
+}
+
+void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags);
+void r600_release_command_buffer(struct r600_command_buffer *cb);
+
+/*
+ * Helpers for emitting state into a command stream directly.
+ */
+
+static INLINE unsigned r600_context_bo_reloc(struct r600_context *ctx, struct r600_resource *rbo,
+ enum radeon_bo_usage usage)
+{
+ assert(usage);
+ return ctx->ws->cs_add_reloc(ctx->cs, rbo->cs_buf, usage, rbo->domains) * 4;
+}
+
+static INLINE void r600_write_value(struct radeon_winsys_cs *cs, unsigned value)
+{
+ cs->buf[cs->cdw++] = value;
+}
+
+static INLINE void r600_write_array(struct radeon_winsys_cs *cs, unsigned num, unsigned *ptr)
+{
+ assert(cs->cdw+num <= RADEON_MAX_CMDBUF_DWORDS);
+ memcpy(&cs->buf[cs->cdw], ptr, num * sizeof(ptr[0]));
+ cs->cdw += num;
+}
+
+static INLINE void r600_write_config_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+ assert(reg < R600_CONTEXT_REG_OFFSET);
+ assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+ cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONFIG_REG, num, 0);
+ cs->buf[cs->cdw++] = (reg - R600_CONFIG_REG_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_context_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+ assert(reg >= R600_CONTEXT_REG_OFFSET && reg < R600_CTL_CONST_OFFSET);
+ assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+ cs->buf[cs->cdw++] = PKT3(PKT3_SET_CONTEXT_REG, num, 0);
+ cs->buf[cs->cdw++] = (reg - R600_CONTEXT_REG_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_compute_context_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+ r600_write_context_reg_seq(cs, reg, num);
+ /* Set the compute bit on the packet header */
+ cs->buf[cs->cdw - 2] |= RADEON_CP_PACKET3_COMPUTE_MODE;
+}
+
+static INLINE void r600_write_ctl_const_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
+{
+ assert(reg >= R600_CTL_CONST_OFFSET);
+ assert(cs->cdw+2+num <= RADEON_MAX_CMDBUF_DWORDS);
+ cs->buf[cs->cdw++] = PKT3(PKT3_SET_CTL_CONST, num, 0);
+ cs->buf[cs->cdw++] = (reg - R600_CTL_CONST_OFFSET) >> 2;
+}
+
+static INLINE void r600_write_config_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+ r600_write_config_reg_seq(cs, reg, 1);
+ r600_write_value(cs, value);
+}
+
+static INLINE void r600_write_context_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+ r600_write_context_reg_seq(cs, reg, 1);
+ r600_write_value(cs, value);
+}
+
+static INLINE void r600_write_compute_context_reg(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+ r600_write_compute_context_reg_seq(cs, reg, 1);
+ r600_write_value(cs, value);
+}
+
+static INLINE void r600_write_ctl_const(struct radeon_winsys_cs *cs, unsigned reg, unsigned value)
+{
+ r600_write_ctl_const_seq(cs, reg, 1);
+ r600_write_value(cs, value);
+}