r600_state_common.c revision 68bbfc1afe210d82acfb14a78b0fd8c436a8f78c
1/*
2 * Copyright 2010 Red Hat Inc.
3 *           2010 Jerome Glisse
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie <airlied@redhat.com>
25 *          Jerome Glisse <jglisse@redhat.com>
26 */
27#include "r600_formats.h"
28#include "r600d.h"
29
30#include "util/u_blitter.h"
31#include "tgsi/tgsi_parse.h"
32
33static void r600_emit_command_buffer(struct r600_context *rctx, struct r600_atom *atom)
34{
35	struct radeon_winsys_cs *cs = rctx->cs;
36	struct r600_command_buffer *cb = (struct r600_command_buffer*)atom;
37
38	assert(cs->cdw + cb->atom.num_dw <= RADEON_MAX_CMDBUF_DWORDS);
39	memcpy(cs->buf + cs->cdw, cb->buf, 4 * cb->atom.num_dw);
40	cs->cdw += cb->atom.num_dw;
41}
42
43void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags)
44{
45	cb->atom.emit = r600_emit_command_buffer;
46	cb->atom.num_dw = 0;
47	cb->atom.flags = flags;
48	cb->buf = CALLOC(1, 4 * num_dw);
49	cb->max_num_dw = num_dw;
50}
51
52void r600_release_command_buffer(struct r600_command_buffer *cb)
53{
54	FREE(cb->buf);
55}
56
57static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom)
58{
59	struct radeon_winsys_cs *cs = rctx->cs;
60	struct r600_surface_sync_cmd *a = (struct r600_surface_sync_cmd*)atom;
61
62	cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
63	cs->buf[cs->cdw++] = a->flush_flags;  /* CP_COHER_CNTL */
64	cs->buf[cs->cdw++] = 0xffffffff;      /* CP_COHER_SIZE */
65	cs->buf[cs->cdw++] = 0;               /* CP_COHER_BASE */
66	cs->buf[cs->cdw++] = 0x0000000A;      /* POLL_INTERVAL */
67
68	a->flush_flags = 0;
69}
70
71static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_atom *atom)
72{
73	struct radeon_winsys_cs *cs = rctx->cs;
74	cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
75	cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
76}
77
78void r600_init_atom(struct r600_atom *atom,
79		    void (*emit)(struct r600_context *ctx, struct r600_atom *state),
80		    unsigned num_dw, enum r600_atom_flags flags)
81{
82	atom->emit = emit;
83	atom->num_dw = num_dw;
84	atom->flags = flags;
85}
86
87void r600_init_common_atoms(struct r600_context *rctx)
88{
89	r600_init_atom(&rctx->surface_sync_cmd.atom,	r600_emit_surface_sync,		5, EMIT_EARLY);
90	r600_init_atom(&rctx->r6xx_flush_and_inv_cmd,	r600_emit_r6xx_flush_and_inv,	2, EMIT_EARLY);
91}
92
93unsigned r600_get_cb_flush_flags(struct r600_context *rctx)
94{
95	unsigned flags = 0;
96
97	if (rctx->framebuffer.nr_cbufs) {
98		flags |= S_0085F0_CB_ACTION_ENA(1) |
99			 (((1 << rctx->framebuffer.nr_cbufs) - 1) << S_0085F0_CB0_DEST_BASE_ENA_SHIFT);
100	}
101
102	/* Workaround for broken flushing on some R6xx chipsets. */
103	if (rctx->family == CHIP_RV670 ||
104	    rctx->family == CHIP_RS780 ||
105	    rctx->family == CHIP_RS880) {
106		flags |=  S_0085F0_CB1_DEST_BASE_ENA(1) |
107			  S_0085F0_DEST_BASE_0_ENA(1);
108	}
109	return flags;
110}
111
112void r600_texture_barrier(struct pipe_context *ctx)
113{
114	struct r600_context *rctx = (struct r600_context *)ctx;
115
116	rctx->surface_sync_cmd.flush_flags |= S_0085F0_TC_ACTION_ENA(1) | r600_get_cb_flush_flags(rctx);
117	r600_atom_dirty(rctx, &rctx->surface_sync_cmd.atom);
118}
119
120static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
121{
122	static const int prim_conv[] = {
123		V_008958_DI_PT_POINTLIST,
124		V_008958_DI_PT_LINELIST,
125		V_008958_DI_PT_LINELOOP,
126		V_008958_DI_PT_LINESTRIP,
127		V_008958_DI_PT_TRILIST,
128		V_008958_DI_PT_TRISTRIP,
129		V_008958_DI_PT_TRIFAN,
130		V_008958_DI_PT_QUADLIST,
131		V_008958_DI_PT_QUADSTRIP,
132		V_008958_DI_PT_POLYGON,
133		-1,
134		-1,
135		-1,
136		-1
137	};
138
139	*prim = prim_conv[pprim];
140	if (*prim == -1) {
141		fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim);
142		return false;
143	}
144	return true;
145}
146
147/* common state between evergreen and r600 */
148void r600_bind_blend_state(struct pipe_context *ctx, void *state)
149{
150	struct r600_context *rctx = (struct r600_context *)ctx;
151	struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
152	struct r600_pipe_state *rstate;
153
154	if (state == NULL)
155		return;
156	rstate = &blend->rstate;
157	rctx->states[rstate->id] = rstate;
158	rctx->cb_target_mask = blend->cb_target_mask;
159
160	/* Replace every bit except MULTIWRITE_ENABLE. */
161	rctx->cb_color_control &= ~C_028808_MULTIWRITE_ENABLE;
162	rctx->cb_color_control |= blend->cb_color_control & C_028808_MULTIWRITE_ENABLE;
163
164	r600_context_pipe_state_set(rctx, rstate);
165}
166
167void r600_set_blend_color(struct pipe_context *ctx,
168			  const struct pipe_blend_color *state)
169{
170	struct r600_context *rctx = (struct r600_context *)ctx;
171	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
172
173	if (rstate == NULL)
174		return;
175
176	rstate->id = R600_PIPE_STATE_BLEND_COLOR;
177	r600_pipe_state_add_reg(rstate, R_028414_CB_BLEND_RED, fui(state->color[0]), NULL, 0);
178	r600_pipe_state_add_reg(rstate, R_028418_CB_BLEND_GREEN, fui(state->color[1]), NULL, 0);
179	r600_pipe_state_add_reg(rstate, R_02841C_CB_BLEND_BLUE, fui(state->color[2]), NULL, 0);
180	r600_pipe_state_add_reg(rstate, R_028420_CB_BLEND_ALPHA, fui(state->color[3]), NULL, 0);
181
182	free(rctx->states[R600_PIPE_STATE_BLEND_COLOR]);
183	rctx->states[R600_PIPE_STATE_BLEND_COLOR] = rstate;
184	r600_context_pipe_state_set(rctx, rstate);
185}
186
187static void r600_set_stencil_ref(struct pipe_context *ctx,
188				 const struct r600_stencil_ref *state)
189{
190	struct r600_context *rctx = (struct r600_context *)ctx;
191	struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
192
193	if (rstate == NULL)
194		return;
195
196	rstate->id = R600_PIPE_STATE_STENCIL_REF;
197	r600_pipe_state_add_reg(rstate,
198				R_028430_DB_STENCILREFMASK,
199				S_028430_STENCILREF(state->ref_value[0]) |
200				S_028430_STENCILMASK(state->valuemask[0]) |
201				S_028430_STENCILWRITEMASK(state->writemask[0]),
202				NULL, 0);
203	r600_pipe_state_add_reg(rstate,
204				R_028434_DB_STENCILREFMASK_BF,
205				S_028434_STENCILREF_BF(state->ref_value[1]) |
206				S_028434_STENCILMASK_BF(state->valuemask[1]) |
207				S_028434_STENCILWRITEMASK_BF(state->writemask[1]),
208				NULL, 0);
209
210	free(rctx->states[R600_PIPE_STATE_STENCIL_REF]);
211	rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate;
212	r600_context_pipe_state_set(rctx, rstate);
213}
214
215void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
216			       const struct pipe_stencil_ref *state)
217{
218	struct r600_context *rctx = (struct r600_context *)ctx;
219	struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA];
220	struct r600_stencil_ref ref;
221
222	rctx->stencil_ref = *state;
223
224	if (!dsa)
225		return;
226
227	ref.ref_value[0] = state->ref_value[0];
228	ref.ref_value[1] = state->ref_value[1];
229	ref.valuemask[0] = dsa->valuemask[0];
230	ref.valuemask[1] = dsa->valuemask[1];
231	ref.writemask[0] = dsa->writemask[0];
232	ref.writemask[1] = dsa->writemask[1];
233
234	r600_set_stencil_ref(ctx, &ref);
235}
236
237void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
238{
239	struct r600_context *rctx = (struct r600_context *)ctx;
240	struct r600_pipe_dsa *dsa = state;
241	struct r600_pipe_state *rstate;
242	struct r600_stencil_ref ref;
243
244	if (state == NULL)
245		return;
246	rstate = &dsa->rstate;
247	rctx->states[rstate->id] = rstate;
248	rctx->alpha_ref = dsa->alpha_ref;
249	rctx->alpha_ref_dirty = true;
250	r600_context_pipe_state_set(rctx, rstate);
251
252	ref.ref_value[0] = rctx->stencil_ref.ref_value[0];
253	ref.ref_value[1] = rctx->stencil_ref.ref_value[1];
254	ref.valuemask[0] = dsa->valuemask[0];
255	ref.valuemask[1] = dsa->valuemask[1];
256	ref.writemask[0] = dsa->writemask[0];
257	ref.writemask[1] = dsa->writemask[1];
258
259	r600_set_stencil_ref(ctx, &ref);
260
261	if (rctx->db_misc_state.flush_depthstencil_enabled != dsa->is_flush) {
262		rctx->db_misc_state.flush_depthstencil_enabled = dsa->is_flush;
263		r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
264	}
265}
266
267void r600_set_max_scissor(struct r600_context *rctx)
268{
269	/* Set a scissor state such that it doesn't do anything. */
270	struct pipe_scissor_state scissor;
271	scissor.minx = 0;
272	scissor.miny = 0;
273	scissor.maxx = 8192;
274	scissor.maxy = 8192;
275
276	r600_set_scissor_state(rctx, &scissor);
277}
278
279void r600_bind_rs_state(struct pipe_context *ctx, void *state)
280{
281	struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
282	struct r600_context *rctx = (struct r600_context *)ctx;
283
284	if (state == NULL)
285		return;
286
287	rctx->sprite_coord_enable = rs->sprite_coord_enable;
288	rctx->two_side = rs->two_side;
289	rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
290	rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
291
292	rctx->rasterizer = rs;
293
294	rctx->states[rs->rstate.id] = &rs->rstate;
295	r600_context_pipe_state_set(rctx, &rs->rstate);
296
297	if (rctx->chip_class >= EVERGREEN) {
298		evergreen_polygon_offset_update(rctx);
299	} else {
300		r600_polygon_offset_update(rctx);
301	}
302
303	/* Workaround for a missing scissor enable on r600. */
304	if (rctx->chip_class == R600) {
305		if (rs->scissor_enable != rctx->scissor_enable) {
306			rctx->scissor_enable = rs->scissor_enable;
307
308			if (rs->scissor_enable) {
309				r600_set_scissor_state(rctx, &rctx->scissor_state);
310			} else {
311				r600_set_max_scissor(rctx);
312			}
313		}
314	}
315}
316
317void r600_delete_rs_state(struct pipe_context *ctx, void *state)
318{
319	struct r600_context *rctx = (struct r600_context *)ctx;
320	struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state;
321
322	if (rctx->rasterizer == rs) {
323		rctx->rasterizer = NULL;
324	}
325	if (rctx->states[rs->rstate.id] == &rs->rstate) {
326		rctx->states[rs->rstate.id] = NULL;
327	}
328	free(rs);
329}
330
331void r600_sampler_view_destroy(struct pipe_context *ctx,
332			       struct pipe_sampler_view *state)
333{
334	struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state;
335
336	pipe_resource_reference(&state->texture, NULL);
337	FREE(resource);
338}
339
340void r600_delete_state(struct pipe_context *ctx, void *state)
341{
342	struct r600_context *rctx = (struct r600_context *)ctx;
343	struct r600_pipe_state *rstate = (struct r600_pipe_state *)state;
344
345	if (rctx->states[rstate->id] == rstate) {
346		rctx->states[rstate->id] = NULL;
347	}
348	for (int i = 0; i < rstate->nregs; i++) {
349		pipe_resource_reference((struct pipe_resource**)&rstate->regs[i].bo, NULL);
350	}
351	free(rstate);
352}
353
354void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
355{
356	struct r600_context *rctx = (struct r600_context *)ctx;
357	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
358
359	rctx->vertex_elements = v;
360	if (v) {
361		r600_inval_shader_cache(rctx);
362		u_vbuf_bind_vertex_elements(rctx->vbuf_mgr, state,
363						v->vmgr_elements);
364
365		rctx->states[v->rstate.id] = &v->rstate;
366		r600_context_pipe_state_set(rctx, &v->rstate);
367	}
368}
369
370void r600_delete_vertex_element(struct pipe_context *ctx, void *state)
371{
372	struct r600_context *rctx = (struct r600_context *)ctx;
373	struct r600_vertex_element *v = (struct r600_vertex_element*)state;
374
375	if (rctx->states[v->rstate.id] == &v->rstate) {
376		rctx->states[v->rstate.id] = NULL;
377	}
378	if (rctx->vertex_elements == state)
379		rctx->vertex_elements = NULL;
380
381	pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL);
382	u_vbuf_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements);
383	FREE(state);
384}
385
386
387void r600_set_index_buffer(struct pipe_context *ctx,
388			   const struct pipe_index_buffer *ib)
389{
390	struct r600_context *rctx = (struct r600_context *)ctx;
391
392	u_vbuf_set_index_buffer(rctx->vbuf_mgr, ib);
393}
394
395void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
396			     const struct pipe_vertex_buffer *buffers)
397{
398	struct r600_context *rctx = (struct r600_context *)ctx;
399
400	u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers);
401	rctx->vertex_buffers_dirty = true;
402}
403
404void *r600_create_vertex_elements(struct pipe_context *ctx,
405				  unsigned count,
406				  const struct pipe_vertex_element *elements)
407{
408	struct r600_context *rctx = (struct r600_context *)ctx;
409	struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
410
411	assert(count < 32);
412	if (!v)
413		return NULL;
414
415	v->count = count;
416	v->vmgr_elements =
417		u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count,
418						  elements, v->elements);
419
420	if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
421		FREE(v);
422		return NULL;
423	}
424
425	return v;
426}
427
428void *r600_create_shader_state(struct pipe_context *ctx,
429			       const struct pipe_shader_state *state)
430{
431	struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
432	int r;
433
434	shader->tokens = tgsi_dup_tokens(state->tokens);
435	shader->so = state->stream_output;
436
437	r =  r600_pipe_shader_create(ctx, shader);
438	if (r) {
439		return NULL;
440	}
441	return shader;
442}
443
444void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
445{
446	struct r600_context *rctx = (struct r600_context *)ctx;
447
448	if (!state) {
449		state = rctx->dummy_pixel_shader;
450	}
451
452	rctx->ps_shader = (struct r600_pipe_shader *)state;
453
454	r600_inval_shader_cache(rctx);
455	r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
456
457	rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE;
458	rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all);
459
460	if (rctx->ps_shader && rctx->vs_shader) {
461		r600_adjust_gprs(rctx);
462	}
463}
464
465void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
466{
467	struct r600_context *rctx = (struct r600_context *)ctx;
468
469	rctx->vs_shader = (struct r600_pipe_shader *)state;
470	if (state) {
471		r600_inval_shader_cache(rctx);
472		r600_context_pipe_state_set(rctx, &rctx->vs_shader->rstate);
473	}
474	if (rctx->ps_shader && rctx->vs_shader) {
475		r600_adjust_gprs(rctx);
476	}
477}
478
479void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
480{
481	struct r600_context *rctx = (struct r600_context *)ctx;
482	struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
483
484	if (rctx->ps_shader == shader) {
485		rctx->ps_shader = NULL;
486	}
487
488	free(shader->tokens);
489	r600_pipe_shader_destroy(ctx, shader);
490	free(shader);
491}
492
493void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
494{
495	struct r600_context *rctx = (struct r600_context *)ctx;
496	struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
497
498	if (rctx->vs_shader == shader) {
499		rctx->vs_shader = NULL;
500	}
501
502	free(shader->tokens);
503	r600_pipe_shader_destroy(ctx, shader);
504	free(shader);
505}
506
507static void r600_update_alpha_ref(struct r600_context *rctx)
508{
509	unsigned alpha_ref;
510	struct r600_pipe_state rstate;
511
512	alpha_ref = rctx->alpha_ref;
513	rstate.nregs = 0;
514	if (rctx->export_16bpc)
515		alpha_ref &= ~0x1FFF;
516	r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, NULL, 0);
517
518	r600_context_pipe_state_set(rctx, &rstate);
519	rctx->alpha_ref_dirty = false;
520}
521
522void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state)
523{
524	state->atom.num_dw = rctx->chip_class >= EVERGREEN ? util_bitcount(state->dirty_mask)*20
525							   : util_bitcount(state->dirty_mask)*19;
526	r600_atom_dirty(rctx, &state->atom);
527}
528
529void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
530			      struct pipe_resource *buffer)
531{
532	struct r600_context *rctx = (struct r600_context *)ctx;
533	struct r600_resource *rbuffer = r600_resource(buffer);
534	struct r600_constbuf_state *state;
535	struct r600_constant_buffer *cb;
536	uint32_t offset;
537
538	switch (shader) {
539	case PIPE_SHADER_VERTEX:
540		state = &rctx->vs_constbuf_state;
541		break;
542	case PIPE_SHADER_FRAGMENT:
543		state = &rctx->ps_constbuf_state;
544		break;
545	default:
546		return;
547	}
548
549	/* Note that the state tracker can unbind constant buffers by
550	 * passing NULL here.
551	 */
552	if (buffer == NULL) {
553		state->enabled_mask &= ~(1 << index);
554		state->dirty_mask &= ~(1 << index);
555		pipe_resource_reference(&state->cb[index].buffer, NULL);
556		return;
557	}
558
559	r600_inval_shader_cache(rctx);
560	r600_upload_const_buffer(rctx, &rbuffer, &offset);
561
562	cb = &state->cb[index];
563	pipe_resource_reference(&cb->buffer, &rbuffer->b.b.b);
564	cb->buffer_offset = offset;
565	cb->buffer_size = buffer->width0;
566
567	state->enabled_mask |= 1 << index;
568	state->dirty_mask |= 1 << index;
569	r600_constant_buffers_dirty(rctx, state);
570
571	if (buffer != &rbuffer->b.b.b)
572		pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
573}
574
575struct pipe_stream_output_target *
576r600_create_so_target(struct pipe_context *ctx,
577		      struct pipe_resource *buffer,
578		      unsigned buffer_offset,
579		      unsigned buffer_size)
580{
581	struct r600_context *rctx = (struct r600_context *)ctx;
582	struct r600_so_target *t;
583	void *ptr;
584
585	t = CALLOC_STRUCT(r600_so_target);
586	if (!t) {
587		return NULL;
588	}
589
590	t->b.reference.count = 1;
591	t->b.context = ctx;
592	pipe_resource_reference(&t->b.buffer, buffer);
593	t->b.buffer_offset = buffer_offset;
594	t->b.buffer_size = buffer_size;
595
596	t->filled_size = (struct r600_resource*)
597		pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4);
598	ptr = rctx->ws->buffer_map(t->filled_size->buf, rctx->cs, PIPE_TRANSFER_WRITE);
599	memset(ptr, 0, t->filled_size->buf->size);
600	rctx->ws->buffer_unmap(t->filled_size->buf);
601
602	return &t->b;
603}
604
605void r600_so_target_destroy(struct pipe_context *ctx,
606			    struct pipe_stream_output_target *target)
607{
608	struct r600_so_target *t = (struct r600_so_target*)target;
609	pipe_resource_reference(&t->b.buffer, NULL);
610	pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL);
611	FREE(t);
612}
613
614void r600_set_so_targets(struct pipe_context *ctx,
615			 unsigned num_targets,
616			 struct pipe_stream_output_target **targets,
617			 unsigned append_bitmask)
618{
619	struct r600_context *rctx = (struct r600_context *)ctx;
620	unsigned i;
621
622	/* Stop streamout. */
623	if (rctx->num_so_targets) {
624		r600_context_streamout_end(rctx);
625	}
626
627	/* Set the new targets. */
628	for (i = 0; i < num_targets; i++) {
629		pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]);
630	}
631	for (; i < rctx->num_so_targets; i++) {
632		pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL);
633	}
634
635	rctx->num_so_targets = num_targets;
636	rctx->streamout_start = num_targets != 0;
637	rctx->streamout_append_bitmask = append_bitmask;
638}
639
640static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
641{
642	struct r600_context *rctx = (struct r600_context *)ctx;
643	int r;
644
645	r600_pipe_shader_destroy(ctx, shader);
646	r = r600_pipe_shader_create(ctx, shader);
647	if (r) {
648		return r;
649	}
650	r600_context_pipe_state_set(rctx, &shader->rstate);
651
652	return 0;
653}
654
655static void r600_update_derived_state(struct r600_context *rctx)
656{
657	struct pipe_context * ctx = (struct pipe_context*)rctx;
658
659	if (!rctx->blitter->running) {
660		if (rctx->have_depth_fb || rctx->have_depth_texture)
661			r600_flush_depth_textures(rctx);
662	}
663
664	if (rctx->chip_class < EVERGREEN) {
665		r600_update_sampler_states(rctx);
666	}
667
668	if ((rctx->ps_shader->shader.two_side != rctx->two_side) ||
669	    ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all &&
670	     (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) {
671		r600_shader_rebuild(&rctx->context, rctx->ps_shader);
672	}
673
674	if (rctx->alpha_ref_dirty) {
675		r600_update_alpha_ref(rctx);
676	}
677
678	if (rctx->ps_shader && ((rctx->sprite_coord_enable &&
679		(rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) ||
680		(rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->flatshade))) {
681
682		if (rctx->chip_class >= EVERGREEN)
683			evergreen_pipe_shader_ps(ctx, rctx->ps_shader);
684		else
685			r600_pipe_shader_ps(ctx, rctx->ps_shader);
686
687		r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
688	}
689
690}
691
692static unsigned r600_conv_prim_to_gs_out(unsigned mode)
693{
694	static const int prim_conv[] = {
695		V_028A6C_OUTPRIM_TYPE_POINTLIST,
696		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
697		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
698		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
699		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
700		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
701		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
702		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
703		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
704		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
705		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
706		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
707		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
708		V_028A6C_OUTPRIM_TYPE_TRISTRIP
709	};
710	assert(mode < Elements(prim_conv));
711
712	return prim_conv[mode];
713}
714
715void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
716{
717	struct r600_context *rctx = (struct r600_context *)ctx;
718	struct pipe_draw_info info = *dinfo;
719	struct pipe_index_buffer ib = {};
720	unsigned prim, mask, ls_mask = 0;
721	struct r600_block *dirty_block = NULL, *next_block = NULL;
722	struct r600_atom *state = NULL, *next_state = NULL;
723	struct radeon_winsys_cs *cs = rctx->cs;
724	uint64_t va;
725
726	if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
727	    (info.indexed && !rctx->vbuf_mgr->index_buffer.buffer) ||
728	    !r600_conv_pipe_prim(info.mode, &prim)) {
729		assert(0);
730		return;
731	}
732
733	if (!rctx->vs_shader) {
734		assert(0);
735		return;
736	}
737
738	r600_update_derived_state(rctx);
739
740	/* Update vertex buffers. */
741	if ((u_vbuf_draw_begin(rctx->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) ||
742	    rctx->vertex_buffers_dirty) {
743		r600_inval_vertex_cache(rctx);
744		rctx->vertex_buffer_state.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
745						   rctx->vbuf_mgr->nr_real_vertex_buffers;
746		r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
747		rctx->vertex_buffers_dirty = FALSE;
748	}
749
750	if (info.indexed) {
751		/* Initialize the index buffer struct. */
752		pipe_resource_reference(&ib.buffer, rctx->vbuf_mgr->index_buffer.buffer);
753		ib.index_size = rctx->vbuf_mgr->index_buffer.index_size;
754		ib.offset = rctx->vbuf_mgr->index_buffer.offset + info.start * ib.index_size;
755
756		/* Translate or upload, if needed. */
757		r600_translate_index_buffer(rctx, &ib, info.count);
758
759		if (u_vbuf_resource(ib.buffer)->user_ptr) {
760			r600_upload_index_buffer(rctx, &ib, info.count);
761		}
762	} else {
763		info.index_bias = info.start;
764		if (info.count_from_stream_output) {
765			r600_context_draw_opaque_count(rctx, (struct r600_so_target*)info.count_from_stream_output);
766		}
767	}
768
769	mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
770
771	if (rctx->vgt.id != R600_PIPE_STATE_VGT) {
772		rctx->vgt.id = R600_PIPE_STATE_VGT;
773		rctx->vgt.nregs = 0;
774		r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0);
775		r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0, NULL, 0);
776		r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0);
777		r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0);
778		r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index, NULL, 0);
779		r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart, NULL, 0);
780		r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance, NULL, 0);
781		r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0, NULL, 0);
782		if (rctx->chip_class <= R700)
783			r600_pipe_state_add_reg(&rctx->vgt, R_028808_CB_COLOR_CONTROL, rctx->cb_color_control, NULL, 0);
784		r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0, NULL, 0);
785		r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0, NULL, 0);
786	}
787
788	rctx->vgt.nregs = 0;
789	r600_pipe_state_mod_reg(&rctx->vgt, prim);
790	r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode));
791	r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask);
792	r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias);
793	r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index);
794	r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart);
795	r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance);
796
797	if (prim == V_008958_DI_PT_LINELIST)
798		ls_mask = 1;
799	else if (prim == V_008958_DI_PT_LINESTRIP)
800		ls_mask = 2;
801	r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple);
802	if (rctx->chip_class <= R700)
803		r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_color_control);
804	r600_pipe_state_mod_reg(&rctx->vgt,
805				rctx->vs_shader->pa_cl_vs_out_cntl |
806				(rctx->rasterizer->clip_plane_enable & rctx->vs_shader->shader.clip_dist_write));
807	r600_pipe_state_mod_reg(&rctx->vgt,
808				rctx->pa_cl_clip_cntl |
809				(rctx->vs_shader->shader.clip_dist_write ||
810				 rctx->vs_shader->shader.vs_prohibit_ucps ?
811				 0 : rctx->rasterizer->clip_plane_enable & 0x3F));
812
813	r600_context_pipe_state_set(rctx, &rctx->vgt);
814
815	/* Emit states (the function expects that we emit at most 17 dwords here). */
816	r600_need_cs_space(rctx, 0, TRUE);
817
818	LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) {
819		r600_emit_atom(rctx, state);
820	}
821	LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) {
822		r600_context_block_emit_dirty(rctx, dirty_block);
823	}
824	LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->resource_dirty,list) {
825		r600_context_block_resource_emit_dirty(rctx, dirty_block);
826	}
827	rctx->pm4_dirty_cdwords = 0;
828
829	/* Enable stream out if needed. */
830	if (rctx->streamout_start) {
831		r600_context_streamout_begin(rctx);
832		rctx->streamout_start = FALSE;
833	}
834
835	/* draw packet */
836	cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing);
837	cs->buf[cs->cdw++] = ib.index_size == 4 ?
838				(VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) :
839				(VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0));
840	cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing);
841	cs->buf[cs->cdw++] = info.instance_count;
842	if (info.indexed) {
843		va = r600_resource_va(ctx->screen, ib.buffer);
844		va += ib.offset;
845		cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing);
846		cs->buf[cs->cdw++] = va;
847		cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF;
848		cs->buf[cs->cdw++] = info.count;
849		cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA;
850		cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing);
851		cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ);
852	} else {
853		cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing);
854		cs->buf[cs->cdw++] = info.count;
855		cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX |
856					(info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0);
857	}
858
859	rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING;
860
861	if (rctx->framebuffer.zsbuf)
862	{
863		struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture;
864		((struct r600_resource_texture *)tex)->dirty_db = TRUE;
865	}
866
867	pipe_resource_reference(&ib.buffer, NULL);
868	u_vbuf_draw_end(rctx->vbuf_mgr);
869}
870
871void _r600_pipe_state_add_reg(struct r600_context *ctx,
872			      struct r600_pipe_state *state,
873			      uint32_t offset, uint32_t value,
874			      uint32_t range_id, uint32_t block_id,
875			      struct r600_resource *bo,
876			      enum radeon_bo_usage usage)
877{
878	struct r600_range *range;
879	struct r600_block *block;
880
881	if (bo) assert(usage);
882
883	range = &ctx->range[range_id];
884	block = range->blocks[block_id];
885	state->regs[state->nregs].block = block;
886	state->regs[state->nregs].id = (offset - block->start_offset) >> 2;
887
888	state->regs[state->nregs].value = value;
889	state->regs[state->nregs].bo = bo;
890	state->regs[state->nregs].bo_usage = usage;
891
892	state->nregs++;
893	assert(state->nregs < R600_BLOCK_MAX_REG);
894}
895
896void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state,
897				     uint32_t offset, uint32_t value,
898				     struct r600_resource *bo,
899				     enum radeon_bo_usage usage)
900{
901	if (bo) assert(usage);
902
903	state->regs[state->nregs].id = offset;
904	state->regs[state->nregs].block = NULL;
905	state->regs[state->nregs].value = value;
906	state->regs[state->nregs].bo = bo;
907	state->regs[state->nregs].bo_usage = usage;
908
909	state->nregs++;
910	assert(state->nregs < R600_BLOCK_MAX_REG);
911}
912
913uint32_t r600_translate_stencil_op(int s_op)
914{
915	switch (s_op) {
916	case PIPE_STENCIL_OP_KEEP:
917		return V_028800_STENCIL_KEEP;
918	case PIPE_STENCIL_OP_ZERO:
919		return V_028800_STENCIL_ZERO;
920	case PIPE_STENCIL_OP_REPLACE:
921		return V_028800_STENCIL_REPLACE;
922	case PIPE_STENCIL_OP_INCR:
923		return V_028800_STENCIL_INCR;
924	case PIPE_STENCIL_OP_DECR:
925		return V_028800_STENCIL_DECR;
926	case PIPE_STENCIL_OP_INCR_WRAP:
927		return V_028800_STENCIL_INCR_WRAP;
928	case PIPE_STENCIL_OP_DECR_WRAP:
929		return V_028800_STENCIL_DECR_WRAP;
930	case PIPE_STENCIL_OP_INVERT:
931		return V_028800_STENCIL_INVERT;
932	default:
933		R600_ERR("Unknown stencil op %d", s_op);
934		assert(0);
935		break;
936	}
937	return 0;
938}
939
940uint32_t r600_translate_fill(uint32_t func)
941{
942	switch(func) {
943	case PIPE_POLYGON_MODE_FILL:
944		return 2;
945	case PIPE_POLYGON_MODE_LINE:
946		return 1;
947	case PIPE_POLYGON_MODE_POINT:
948		return 0;
949	default:
950		assert(0);
951		return 0;
952	}
953}
954
955unsigned r600_tex_wrap(unsigned wrap)
956{
957	switch (wrap) {
958	default:
959	case PIPE_TEX_WRAP_REPEAT:
960		return V_03C000_SQ_TEX_WRAP;
961	case PIPE_TEX_WRAP_CLAMP:
962		return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
963	case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
964		return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
965	case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
966		return V_03C000_SQ_TEX_CLAMP_BORDER;
967	case PIPE_TEX_WRAP_MIRROR_REPEAT:
968		return V_03C000_SQ_TEX_MIRROR;
969	case PIPE_TEX_WRAP_MIRROR_CLAMP:
970		return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
971	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
972		return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
973	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
974		return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
975	}
976}
977
978unsigned r600_tex_filter(unsigned filter)
979{
980	switch (filter) {
981	default:
982	case PIPE_TEX_FILTER_NEAREST:
983		return V_03C000_SQ_TEX_XY_FILTER_POINT;
984	case PIPE_TEX_FILTER_LINEAR:
985		return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
986	}
987}
988
989unsigned r600_tex_mipfilter(unsigned filter)
990{
991	switch (filter) {
992	case PIPE_TEX_MIPFILTER_NEAREST:
993		return V_03C000_SQ_TEX_Z_FILTER_POINT;
994	case PIPE_TEX_MIPFILTER_LINEAR:
995		return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
996	default:
997	case PIPE_TEX_MIPFILTER_NONE:
998		return V_03C000_SQ_TEX_Z_FILTER_NONE;
999	}
1000}
1001
1002unsigned r600_tex_compare(unsigned compare)
1003{
1004	switch (compare) {
1005	default:
1006	case PIPE_FUNC_NEVER:
1007		return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
1008	case PIPE_FUNC_LESS:
1009		return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
1010	case PIPE_FUNC_EQUAL:
1011		return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
1012	case PIPE_FUNC_LEQUAL:
1013		return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
1014	case PIPE_FUNC_GREATER:
1015		return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
1016	case PIPE_FUNC_NOTEQUAL:
1017		return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
1018	case PIPE_FUNC_GEQUAL:
1019		return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
1020	case PIPE_FUNC_ALWAYS:
1021		return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
1022	}
1023}
1024