r600_state_common.c revision 5c03d1fa0fbe130153a2e4c937f684c680ca20b2
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	int i;
400
401	/* Zero states. */
402	for (i = 0; i < count; i++) {
403		if (!buffers[i].buffer) {
404			r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
405		}
406	}
407	for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) {
408		r600_context_pipe_state_set_fs_resource(rctx, NULL, i);
409	}
410
411	u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers);
412}
413
414void *r600_create_vertex_elements(struct pipe_context *ctx,
415				  unsigned count,
416				  const struct pipe_vertex_element *elements)
417{
418	struct r600_context *rctx = (struct r600_context *)ctx;
419	struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element);
420
421	assert(count < 32);
422	if (!v)
423		return NULL;
424
425	v->count = count;
426	v->vmgr_elements =
427		u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count,
428						  elements, v->elements);
429
430	if (r600_vertex_elements_build_fetch_shader(rctx, v)) {
431		FREE(v);
432		return NULL;
433	}
434
435	return v;
436}
437
438void *r600_create_shader_state(struct pipe_context *ctx,
439			       const struct pipe_shader_state *state)
440{
441	struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
442	int r;
443
444	shader->tokens = tgsi_dup_tokens(state->tokens);
445	shader->so = state->stream_output;
446
447	r =  r600_pipe_shader_create(ctx, shader);
448	if (r) {
449		return NULL;
450	}
451	return shader;
452}
453
454void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
455{
456	struct r600_context *rctx = (struct r600_context *)ctx;
457
458	if (!state) {
459		state = rctx->dummy_pixel_shader;
460	}
461
462	rctx->ps_shader = (struct r600_pipe_shader *)state;
463
464	r600_inval_shader_cache(rctx);
465	r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
466
467	rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE;
468	rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all);
469
470	if (rctx->ps_shader && rctx->vs_shader) {
471		r600_adjust_gprs(rctx);
472	}
473}
474
475void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
476{
477	struct r600_context *rctx = (struct r600_context *)ctx;
478
479	rctx->vs_shader = (struct r600_pipe_shader *)state;
480	if (state) {
481		r600_inval_shader_cache(rctx);
482		r600_context_pipe_state_set(rctx, &rctx->vs_shader->rstate);
483	}
484	if (rctx->ps_shader && rctx->vs_shader) {
485		r600_adjust_gprs(rctx);
486	}
487}
488
489void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
490{
491	struct r600_context *rctx = (struct r600_context *)ctx;
492	struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
493
494	if (rctx->ps_shader == shader) {
495		rctx->ps_shader = NULL;
496	}
497
498	free(shader->tokens);
499	r600_pipe_shader_destroy(ctx, shader);
500	free(shader);
501}
502
503void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
504{
505	struct r600_context *rctx = (struct r600_context *)ctx;
506	struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state;
507
508	if (rctx->vs_shader == shader) {
509		rctx->vs_shader = NULL;
510	}
511
512	free(shader->tokens);
513	r600_pipe_shader_destroy(ctx, shader);
514	free(shader);
515}
516
517static void r600_update_alpha_ref(struct r600_context *rctx)
518{
519	unsigned alpha_ref;
520	struct r600_pipe_state rstate;
521
522	alpha_ref = rctx->alpha_ref;
523	rstate.nregs = 0;
524	if (rctx->export_16bpc)
525		alpha_ref &= ~0x1FFF;
526	r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, NULL, 0);
527
528	r600_context_pipe_state_set(rctx, &rstate);
529	rctx->alpha_ref_dirty = false;
530}
531
532void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
533			      struct pipe_resource *buffer)
534{
535	struct r600_context *rctx = (struct r600_context *)ctx;
536	struct r600_resource *rbuffer = r600_resource(buffer);
537	struct r600_pipe_resource_state *rstate;
538	uint64_t va_offset;
539	uint32_t offset;
540
541	/* Note that the state tracker can unbind constant buffers by
542	 * passing NULL here.
543	 */
544	if (buffer == NULL) {
545		return;
546	}
547
548	r600_inval_shader_cache(rctx);
549
550	r600_upload_const_buffer(rctx, &rbuffer, &offset);
551	va_offset = r600_resource_va(ctx->screen, (void*)rbuffer);
552	va_offset += offset;
553	va_offset >>= 8;
554
555	switch (shader) {
556	case PIPE_SHADER_VERTEX:
557		rctx->vs_const_buffer.nregs = 0;
558		r600_pipe_state_add_reg(&rctx->vs_const_buffer,
559					R_028180_ALU_CONST_BUFFER_SIZE_VS_0 + index * 4,
560					ALIGN_DIVUP(buffer->width0 >> 4, 16),
561					NULL, 0);
562		r600_pipe_state_add_reg(&rctx->vs_const_buffer,
563					R_028980_ALU_CONST_CACHE_VS_0 + index * 4,
564					va_offset, rbuffer, RADEON_USAGE_READ);
565		r600_context_pipe_state_set(rctx, &rctx->vs_const_buffer);
566
567		rstate = &rctx->vs_const_buffer_resource[index];
568		if (!rstate->id) {
569			if (rctx->chip_class >= EVERGREEN) {
570				evergreen_pipe_init_buffer_resource(rctx, rstate);
571			} else {
572				r600_pipe_init_buffer_resource(rctx, rstate);
573			}
574		}
575
576		if (rctx->chip_class >= EVERGREEN) {
577			evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
578		} else {
579			r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
580		}
581		r600_context_pipe_state_set_vs_resource(rctx, rstate, index);
582		break;
583	case PIPE_SHADER_FRAGMENT:
584		rctx->ps_const_buffer.nregs = 0;
585		r600_pipe_state_add_reg(&rctx->ps_const_buffer,
586					R_028140_ALU_CONST_BUFFER_SIZE_PS_0,
587					ALIGN_DIVUP(buffer->width0 >> 4, 16),
588					NULL, 0);
589		r600_pipe_state_add_reg(&rctx->ps_const_buffer,
590					R_028940_ALU_CONST_CACHE_PS_0,
591					va_offset, rbuffer, RADEON_USAGE_READ);
592		r600_context_pipe_state_set(rctx, &rctx->ps_const_buffer);
593
594		rstate = &rctx->ps_const_buffer_resource[index];
595		if (!rstate->id) {
596			if (rctx->chip_class >= EVERGREEN) {
597				evergreen_pipe_init_buffer_resource(rctx, rstate);
598			} else {
599				r600_pipe_init_buffer_resource(rctx, rstate);
600			}
601		}
602		if (rctx->chip_class >= EVERGREEN) {
603			evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
604		} else {
605			r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ);
606		}
607		r600_context_pipe_state_set_ps_resource(rctx, rstate, index);
608		break;
609	default:
610		R600_ERR("unsupported %d\n", shader);
611		return;
612	}
613
614	if (buffer != &rbuffer->b.b.b)
615		pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
616}
617
618struct pipe_stream_output_target *
619r600_create_so_target(struct pipe_context *ctx,
620		      struct pipe_resource *buffer,
621		      unsigned buffer_offset,
622		      unsigned buffer_size)
623{
624	struct r600_context *rctx = (struct r600_context *)ctx;
625	struct r600_so_target *t;
626	void *ptr;
627
628	t = CALLOC_STRUCT(r600_so_target);
629	if (!t) {
630		return NULL;
631	}
632
633	t->b.reference.count = 1;
634	t->b.context = ctx;
635	pipe_resource_reference(&t->b.buffer, buffer);
636	t->b.buffer_offset = buffer_offset;
637	t->b.buffer_size = buffer_size;
638
639	t->filled_size = (struct r600_resource*)
640		pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4);
641	ptr = rctx->ws->buffer_map(t->filled_size->buf, rctx->cs, PIPE_TRANSFER_WRITE);
642	memset(ptr, 0, t->filled_size->buf->size);
643	rctx->ws->buffer_unmap(t->filled_size->buf);
644
645	return &t->b;
646}
647
648void r600_so_target_destroy(struct pipe_context *ctx,
649			    struct pipe_stream_output_target *target)
650{
651	struct r600_so_target *t = (struct r600_so_target*)target;
652	pipe_resource_reference(&t->b.buffer, NULL);
653	pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL);
654	FREE(t);
655}
656
657void r600_set_so_targets(struct pipe_context *ctx,
658			 unsigned num_targets,
659			 struct pipe_stream_output_target **targets,
660			 unsigned append_bitmask)
661{
662	struct r600_context *rctx = (struct r600_context *)ctx;
663	unsigned i;
664
665	/* Stop streamout. */
666	if (rctx->num_so_targets) {
667		r600_context_streamout_end(rctx);
668	}
669
670	/* Set the new targets. */
671	for (i = 0; i < num_targets; i++) {
672		pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]);
673	}
674	for (; i < rctx->num_so_targets; i++) {
675		pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL);
676	}
677
678	rctx->num_so_targets = num_targets;
679	rctx->streamout_start = num_targets != 0;
680	rctx->streamout_append_bitmask = append_bitmask;
681}
682
683static void r600_vertex_buffer_update(struct r600_context *rctx)
684{
685	unsigned i, count;
686
687	r600_inval_vertex_cache(rctx);
688
689	count = rctx->vbuf_mgr->nr_real_vertex_buffers;
690
691	for (i = 0 ; i < count; i++) {
692		struct r600_pipe_resource_state *rstate = &rctx->fs_resource[i];
693		struct pipe_vertex_buffer *vb = &rctx->vbuf_mgr->real_vertex_buffer[i];
694
695		if (!vb->buffer) {
696			continue;
697		}
698
699		if (!rstate->id) {
700			if (rctx->chip_class >= EVERGREEN) {
701				evergreen_pipe_init_buffer_resource(rctx, rstate);
702			} else {
703				r600_pipe_init_buffer_resource(rctx, rstate);
704			}
705		}
706
707		if (rctx->chip_class >= EVERGREEN) {
708			evergreen_pipe_mod_buffer_resource(&rctx->context, rstate, (struct r600_resource*)vb->buffer, vb->buffer_offset, vb->stride, RADEON_USAGE_READ);
709		} else {
710			r600_pipe_mod_buffer_resource(rstate, (struct r600_resource*)vb->buffer, vb->buffer_offset, vb->stride, RADEON_USAGE_READ);
711		}
712		r600_context_pipe_state_set_fs_resource(rctx, rstate, i);
713	}
714}
715
716static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
717{
718	struct r600_context *rctx = (struct r600_context *)ctx;
719	int r;
720
721	r600_pipe_shader_destroy(ctx, shader);
722	r = r600_pipe_shader_create(ctx, shader);
723	if (r) {
724		return r;
725	}
726	r600_context_pipe_state_set(rctx, &shader->rstate);
727
728	return 0;
729}
730
731static void r600_update_derived_state(struct r600_context *rctx)
732{
733	struct pipe_context * ctx = (struct pipe_context*)rctx;
734
735	if (!rctx->blitter->running) {
736		if (rctx->have_depth_fb || rctx->have_depth_texture)
737			r600_flush_depth_textures(rctx);
738	}
739
740	if (rctx->chip_class < EVERGREEN) {
741		r600_update_sampler_states(rctx);
742	}
743
744	if ((rctx->ps_shader->shader.two_side != rctx->two_side) ||
745	    ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all &&
746	     (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) {
747		r600_shader_rebuild(&rctx->context, rctx->ps_shader);
748	}
749
750	if (rctx->alpha_ref_dirty) {
751		r600_update_alpha_ref(rctx);
752	}
753
754	if (rctx->ps_shader && ((rctx->sprite_coord_enable &&
755		(rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) ||
756		(rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->flatshade))) {
757
758		if (rctx->chip_class >= EVERGREEN)
759			evergreen_pipe_shader_ps(ctx, rctx->ps_shader);
760		else
761			r600_pipe_shader_ps(ctx, rctx->ps_shader);
762
763		r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate);
764	}
765
766}
767
768static unsigned r600_conv_prim_to_gs_out(unsigned mode)
769{
770	static const int prim_conv[] = {
771		V_028A6C_OUTPRIM_TYPE_POINTLIST,
772		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
773		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
774		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
775		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
776		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
777		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
778		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
779		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
780		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
781		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
782		V_028A6C_OUTPRIM_TYPE_LINESTRIP,
783		V_028A6C_OUTPRIM_TYPE_TRISTRIP,
784		V_028A6C_OUTPRIM_TYPE_TRISTRIP
785	};
786	assert(mode < Elements(prim_conv));
787
788	return prim_conv[mode];
789}
790
791void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
792{
793	struct r600_context *rctx = (struct r600_context *)ctx;
794	struct pipe_draw_info info = *dinfo;
795	struct pipe_index_buffer ib = {};
796	unsigned prim, mask, ls_mask = 0;
797	struct r600_block *dirty_block = NULL, *next_block = NULL;
798	struct r600_atom *state = NULL, *next_state = NULL;
799	struct radeon_winsys_cs *cs = rctx->cs;
800	uint64_t va;
801
802	if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
803	    (info.indexed && !rctx->vbuf_mgr->index_buffer.buffer) ||
804	    !r600_conv_pipe_prim(info.mode, &prim)) {
805		assert(0);
806		return;
807	}
808
809	if (!rctx->vs_shader) {
810		assert(0);
811		return;
812	}
813
814	r600_update_derived_state(rctx);
815
816	u_vbuf_draw_begin(rctx->vbuf_mgr, &info);
817	r600_vertex_buffer_update(rctx);
818
819	if (info.indexed) {
820		/* Initialize the index buffer struct. */
821		pipe_resource_reference(&ib.buffer, rctx->vbuf_mgr->index_buffer.buffer);
822		ib.index_size = rctx->vbuf_mgr->index_buffer.index_size;
823		ib.offset = rctx->vbuf_mgr->index_buffer.offset + info.start * ib.index_size;
824
825		/* Translate or upload, if needed. */
826		r600_translate_index_buffer(rctx, &ib, info.count);
827
828		if (u_vbuf_resource(ib.buffer)->user_ptr) {
829			r600_upload_index_buffer(rctx, &ib, info.count);
830		}
831	} else {
832		info.index_bias = info.start;
833		if (info.count_from_stream_output) {
834			r600_context_draw_opaque_count(rctx, (struct r600_so_target*)info.count_from_stream_output);
835		}
836	}
837
838	mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
839
840	if (rctx->vgt.id != R600_PIPE_STATE_VGT) {
841		rctx->vgt.id = R600_PIPE_STATE_VGT;
842		rctx->vgt.nregs = 0;
843		r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0);
844		r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0, NULL, 0);
845		r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0);
846		r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0);
847		r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index, NULL, 0);
848		r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart, NULL, 0);
849		r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance, NULL, 0);
850		r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0, NULL, 0);
851		if (rctx->chip_class <= R700)
852			r600_pipe_state_add_reg(&rctx->vgt, R_028808_CB_COLOR_CONTROL, rctx->cb_color_control, NULL, 0);
853		r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0, NULL, 0);
854		r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0, NULL, 0);
855	}
856
857	rctx->vgt.nregs = 0;
858	r600_pipe_state_mod_reg(&rctx->vgt, prim);
859	r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode));
860	r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask);
861	r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias);
862	r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index);
863	r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart);
864	r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance);
865
866	if (prim == V_008958_DI_PT_LINELIST)
867		ls_mask = 1;
868	else if (prim == V_008958_DI_PT_LINESTRIP)
869		ls_mask = 2;
870	r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple);
871	if (rctx->chip_class <= R700)
872		r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_color_control);
873	r600_pipe_state_mod_reg(&rctx->vgt,
874				rctx->vs_shader->pa_cl_vs_out_cntl |
875				(rctx->rasterizer->clip_plane_enable & rctx->vs_shader->shader.clip_dist_write));
876	r600_pipe_state_mod_reg(&rctx->vgt,
877				rctx->pa_cl_clip_cntl |
878				(rctx->vs_shader->shader.clip_dist_write ||
879				 rctx->vs_shader->shader.vs_prohibit_ucps ?
880				 0 : rctx->rasterizer->clip_plane_enable & 0x3F));
881
882	r600_context_pipe_state_set(rctx, &rctx->vgt);
883
884	/* Emit states (the function expects that we emit at most 17 dwords here). */
885	r600_need_cs_space(rctx, 0, TRUE);
886
887	LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) {
888		r600_emit_atom(rctx, state);
889	}
890	LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) {
891		r600_context_block_emit_dirty(rctx, dirty_block);
892	}
893	LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->resource_dirty,list) {
894		r600_context_block_resource_emit_dirty(rctx, dirty_block);
895	}
896	rctx->pm4_dirty_cdwords = 0;
897
898	/* Enable stream out if needed. */
899	if (rctx->streamout_start) {
900		r600_context_streamout_begin(rctx);
901		rctx->streamout_start = FALSE;
902	}
903
904	/* draw packet */
905	cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing);
906	cs->buf[cs->cdw++] = ib.index_size == 4 ?
907				(VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) :
908				(VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0));
909	cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing);
910	cs->buf[cs->cdw++] = info.instance_count;
911	if (info.indexed) {
912		va = r600_resource_va(ctx->screen, ib.buffer);
913		va += ib.offset;
914		cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing);
915		cs->buf[cs->cdw++] = va;
916		cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF;
917		cs->buf[cs->cdw++] = info.count;
918		cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA;
919		cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing);
920		cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ);
921	} else {
922		cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing);
923		cs->buf[cs->cdw++] = info.count;
924		cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX |
925					(info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0);
926	}
927
928	rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING;
929
930	if (rctx->framebuffer.zsbuf)
931	{
932		struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture;
933		((struct r600_resource_texture *)tex)->dirty_db = TRUE;
934	}
935
936	pipe_resource_reference(&ib.buffer, NULL);
937	u_vbuf_draw_end(rctx->vbuf_mgr);
938}
939
940void _r600_pipe_state_add_reg(struct r600_context *ctx,
941			      struct r600_pipe_state *state,
942			      uint32_t offset, uint32_t value,
943			      uint32_t range_id, uint32_t block_id,
944			      struct r600_resource *bo,
945			      enum radeon_bo_usage usage)
946{
947	struct r600_range *range;
948	struct r600_block *block;
949
950	if (bo) assert(usage);
951
952	range = &ctx->range[range_id];
953	block = range->blocks[block_id];
954	state->regs[state->nregs].block = block;
955	state->regs[state->nregs].id = (offset - block->start_offset) >> 2;
956
957	state->regs[state->nregs].value = value;
958	state->regs[state->nregs].bo = bo;
959	state->regs[state->nregs].bo_usage = usage;
960
961	state->nregs++;
962	assert(state->nregs < R600_BLOCK_MAX_REG);
963}
964
965void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state,
966				     uint32_t offset, uint32_t value,
967				     struct r600_resource *bo,
968				     enum radeon_bo_usage usage)
969{
970	if (bo) assert(usage);
971
972	state->regs[state->nregs].id = offset;
973	state->regs[state->nregs].block = NULL;
974	state->regs[state->nregs].value = value;
975	state->regs[state->nregs].bo = bo;
976	state->regs[state->nregs].bo_usage = usage;
977
978	state->nregs++;
979	assert(state->nregs < R600_BLOCK_MAX_REG);
980}
981
982uint32_t r600_translate_stencil_op(int s_op)
983{
984	switch (s_op) {
985	case PIPE_STENCIL_OP_KEEP:
986		return V_028800_STENCIL_KEEP;
987	case PIPE_STENCIL_OP_ZERO:
988		return V_028800_STENCIL_ZERO;
989	case PIPE_STENCIL_OP_REPLACE:
990		return V_028800_STENCIL_REPLACE;
991	case PIPE_STENCIL_OP_INCR:
992		return V_028800_STENCIL_INCR;
993	case PIPE_STENCIL_OP_DECR:
994		return V_028800_STENCIL_DECR;
995	case PIPE_STENCIL_OP_INCR_WRAP:
996		return V_028800_STENCIL_INCR_WRAP;
997	case PIPE_STENCIL_OP_DECR_WRAP:
998		return V_028800_STENCIL_DECR_WRAP;
999	case PIPE_STENCIL_OP_INVERT:
1000		return V_028800_STENCIL_INVERT;
1001	default:
1002		R600_ERR("Unknown stencil op %d", s_op);
1003		assert(0);
1004		break;
1005	}
1006	return 0;
1007}
1008
1009uint32_t r600_translate_fill(uint32_t func)
1010{
1011	switch(func) {
1012	case PIPE_POLYGON_MODE_FILL:
1013		return 2;
1014	case PIPE_POLYGON_MODE_LINE:
1015		return 1;
1016	case PIPE_POLYGON_MODE_POINT:
1017		return 0;
1018	default:
1019		assert(0);
1020		return 0;
1021	}
1022}
1023
1024unsigned r600_tex_wrap(unsigned wrap)
1025{
1026	switch (wrap) {
1027	default:
1028	case PIPE_TEX_WRAP_REPEAT:
1029		return V_03C000_SQ_TEX_WRAP;
1030	case PIPE_TEX_WRAP_CLAMP:
1031		return V_03C000_SQ_TEX_CLAMP_HALF_BORDER;
1032	case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
1033		return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL;
1034	case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
1035		return V_03C000_SQ_TEX_CLAMP_BORDER;
1036	case PIPE_TEX_WRAP_MIRROR_REPEAT:
1037		return V_03C000_SQ_TEX_MIRROR;
1038	case PIPE_TEX_WRAP_MIRROR_CLAMP:
1039		return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER;
1040	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
1041		return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
1042	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
1043		return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER;
1044	}
1045}
1046
1047unsigned r600_tex_filter(unsigned filter)
1048{
1049	switch (filter) {
1050	default:
1051	case PIPE_TEX_FILTER_NEAREST:
1052		return V_03C000_SQ_TEX_XY_FILTER_POINT;
1053	case PIPE_TEX_FILTER_LINEAR:
1054		return V_03C000_SQ_TEX_XY_FILTER_BILINEAR;
1055	}
1056}
1057
1058unsigned r600_tex_mipfilter(unsigned filter)
1059{
1060	switch (filter) {
1061	case PIPE_TEX_MIPFILTER_NEAREST:
1062		return V_03C000_SQ_TEX_Z_FILTER_POINT;
1063	case PIPE_TEX_MIPFILTER_LINEAR:
1064		return V_03C000_SQ_TEX_Z_FILTER_LINEAR;
1065	default:
1066	case PIPE_TEX_MIPFILTER_NONE:
1067		return V_03C000_SQ_TEX_Z_FILTER_NONE;
1068	}
1069}
1070
1071unsigned r600_tex_compare(unsigned compare)
1072{
1073	switch (compare) {
1074	default:
1075	case PIPE_FUNC_NEVER:
1076		return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER;
1077	case PIPE_FUNC_LESS:
1078		return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS;
1079	case PIPE_FUNC_EQUAL:
1080		return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL;
1081	case PIPE_FUNC_LEQUAL:
1082		return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
1083	case PIPE_FUNC_GREATER:
1084		return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER;
1085	case PIPE_FUNC_NOTEQUAL:
1086		return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
1087	case PIPE_FUNC_GEQUAL:
1088		return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
1089	case PIPE_FUNC_ALWAYS:
1090		return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS;
1091	}
1092}
1093