si_state.c revision e4e6f954ae8c83251c39da4327c29ba12fca8236
1/*
2 * Copyright 2012 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 *      Christian König <christian.koenig@amd.com>
25 */
26
27#include "util/u_memory.h"
28#include "util/u_framebuffer.h"
29#include "radeonsi_pipe.h"
30#include "si_state.h"
31#include "sid.h"
32
33/*
34 * inferred framebuffer and blender state
35 */
36static void si_update_fb_blend_state(struct r600_context *rctx)
37{
38	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
39	struct si_state_blend *blend = rctx->queued.named.blend;
40	uint32_t mask;
41
42	if (pm4 == NULL || blend == NULL)
43		return;
44
45	mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
46	mask &= blend->cb_target_mask;
47	si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
48
49	si_pm4_set_state(rctx, fb_blend, pm4);
50}
51
52/*
53 * Blender functions
54 */
55
56static uint32_t si_translate_blend_function(int blend_func)
57{
58	switch (blend_func) {
59	case PIPE_BLEND_ADD:
60		return V_028780_COMB_DST_PLUS_SRC;
61	case PIPE_BLEND_SUBTRACT:
62		return V_028780_COMB_SRC_MINUS_DST;
63	case PIPE_BLEND_REVERSE_SUBTRACT:
64		return V_028780_COMB_DST_MINUS_SRC;
65	case PIPE_BLEND_MIN:
66		return V_028780_COMB_MIN_DST_SRC;
67	case PIPE_BLEND_MAX:
68		return V_028780_COMB_MAX_DST_SRC;
69	default:
70		R600_ERR("Unknown blend function %d\n", blend_func);
71		assert(0);
72		break;
73	}
74	return 0;
75}
76
77static uint32_t si_translate_blend_factor(int blend_fact)
78{
79	switch (blend_fact) {
80	case PIPE_BLENDFACTOR_ONE:
81		return V_028780_BLEND_ONE;
82	case PIPE_BLENDFACTOR_SRC_COLOR:
83		return V_028780_BLEND_SRC_COLOR;
84	case PIPE_BLENDFACTOR_SRC_ALPHA:
85		return V_028780_BLEND_SRC_ALPHA;
86	case PIPE_BLENDFACTOR_DST_ALPHA:
87		return V_028780_BLEND_DST_ALPHA;
88	case PIPE_BLENDFACTOR_DST_COLOR:
89		return V_028780_BLEND_DST_COLOR;
90	case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
91		return V_028780_BLEND_SRC_ALPHA_SATURATE;
92	case PIPE_BLENDFACTOR_CONST_COLOR:
93		return V_028780_BLEND_CONSTANT_COLOR;
94	case PIPE_BLENDFACTOR_CONST_ALPHA:
95		return V_028780_BLEND_CONSTANT_ALPHA;
96	case PIPE_BLENDFACTOR_ZERO:
97		return V_028780_BLEND_ZERO;
98	case PIPE_BLENDFACTOR_INV_SRC_COLOR:
99		return V_028780_BLEND_ONE_MINUS_SRC_COLOR;
100	case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
101		return V_028780_BLEND_ONE_MINUS_SRC_ALPHA;
102	case PIPE_BLENDFACTOR_INV_DST_ALPHA:
103		return V_028780_BLEND_ONE_MINUS_DST_ALPHA;
104	case PIPE_BLENDFACTOR_INV_DST_COLOR:
105		return V_028780_BLEND_ONE_MINUS_DST_COLOR;
106	case PIPE_BLENDFACTOR_INV_CONST_COLOR:
107		return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR;
108	case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
109		return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA;
110	case PIPE_BLENDFACTOR_SRC1_COLOR:
111		return V_028780_BLEND_SRC1_COLOR;
112	case PIPE_BLENDFACTOR_SRC1_ALPHA:
113		return V_028780_BLEND_SRC1_ALPHA;
114	case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
115		return V_028780_BLEND_INV_SRC1_COLOR;
116	case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
117		return V_028780_BLEND_INV_SRC1_ALPHA;
118	default:
119		R600_ERR("Bad blend factor %d not supported!\n", blend_fact);
120		assert(0);
121		break;
122	}
123	return 0;
124}
125
126static void *si_create_blend_state(struct pipe_context *ctx,
127				   const struct pipe_blend_state *state)
128{
129	struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend);
130	struct si_pm4_state *pm4 = &blend->pm4;
131
132	uint32_t color_control;
133
134	if (blend == NULL)
135		return NULL;
136
137	color_control = S_028808_MODE(V_028808_CB_NORMAL);
138	if (state->logicop_enable) {
139		color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
140	} else {
141		color_control |= S_028808_ROP3(0xcc);
142	}
143	si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control);
144
145	si_pm4_set_reg(pm4, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0);
146	si_pm4_set_reg(pm4, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0);
147
148	blend->cb_target_mask = 0;
149	for (int i = 0; i < 8; i++) {
150		/* state->rt entries > 0 only written if independent blending */
151		const int j = state->independent_blend_enable ? i : 0;
152
153		unsigned eqRGB = state->rt[j].rgb_func;
154		unsigned srcRGB = state->rt[j].rgb_src_factor;
155		unsigned dstRGB = state->rt[j].rgb_dst_factor;
156		unsigned eqA = state->rt[j].alpha_func;
157		unsigned srcA = state->rt[j].alpha_src_factor;
158		unsigned dstA = state->rt[j].alpha_dst_factor;
159
160		unsigned blend_cntl = 0;
161
162		/* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */
163		blend->cb_target_mask |= state->rt[j].colormask << (4 * i);
164
165		if (!state->rt[j].blend_enable) {
166			si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
167			continue;
168		}
169
170		blend_cntl |= S_028780_ENABLE(1);
171		blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
172		blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB));
173		blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB));
174
175		if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
176			blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1);
177			blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
178			blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA));
179			blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA));
180		}
181		si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl);
182	}
183
184	return blend;
185}
186
187static void si_bind_blend_state(struct pipe_context *ctx, void *state)
188{
189	struct r600_context *rctx = (struct r600_context *)ctx;
190	si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state);
191	si_update_fb_blend_state(rctx);
192}
193
194static void si_delete_blend_state(struct pipe_context *ctx, void *state)
195{
196	struct r600_context *rctx = (struct r600_context *)ctx;
197	si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state);
198}
199
200static void si_set_blend_color(struct pipe_context *ctx,
201			       const struct pipe_blend_color *state)
202{
203	struct r600_context *rctx = (struct r600_context *)ctx;
204	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
205
206        if (pm4 == NULL)
207                return;
208
209	si_pm4_set_reg(pm4, R_028414_CB_BLEND_RED, fui(state->color[0]));
210	si_pm4_set_reg(pm4, R_028418_CB_BLEND_GREEN, fui(state->color[1]));
211	si_pm4_set_reg(pm4, R_02841C_CB_BLEND_BLUE, fui(state->color[2]));
212	si_pm4_set_reg(pm4, R_028420_CB_BLEND_ALPHA, fui(state->color[3]));
213
214	si_pm4_set_state(rctx, blend_color, pm4);
215}
216
217/*
218 * Clipping, scissors and viewport
219 */
220
221static void si_set_clip_state(struct pipe_context *ctx,
222			      const struct pipe_clip_state *state)
223{
224	struct r600_context *rctx = (struct r600_context *)ctx;
225	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
226
227	if (pm4 == NULL)
228		return;
229
230	for (int i = 0; i < 6; i++) {
231		si_pm4_set_reg(pm4, R_0285BC_PA_CL_UCP_0_X + i * 16,
232			       fui(state->ucp[i][0]));
233		si_pm4_set_reg(pm4, R_0285C0_PA_CL_UCP_0_Y + i * 16,
234			       fui(state->ucp[i][1]));
235		si_pm4_set_reg(pm4, R_0285C4_PA_CL_UCP_0_Z + i * 16,
236			       fui(state->ucp[i][2]));
237		si_pm4_set_reg(pm4, R_0285C8_PA_CL_UCP_0_W + i * 16,
238			       fui(state->ucp[i][3]));
239        }
240
241	si_pm4_set_state(rctx, clip, pm4);
242}
243
244static void si_set_scissor_state(struct pipe_context *ctx,
245				 const struct pipe_scissor_state *state)
246{
247	struct r600_context *rctx = (struct r600_context *)ctx;
248	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
249	uint32_t tl, br;
250
251	if (pm4 == NULL)
252		return;
253
254	tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny);
255	br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
256	si_pm4_set_reg(pm4, R_028210_PA_SC_CLIPRECT_0_TL, tl);
257	si_pm4_set_reg(pm4, R_028214_PA_SC_CLIPRECT_0_BR, br);
258	si_pm4_set_reg(pm4, R_028218_PA_SC_CLIPRECT_1_TL, tl);
259	si_pm4_set_reg(pm4, R_02821C_PA_SC_CLIPRECT_1_BR, br);
260	si_pm4_set_reg(pm4, R_028220_PA_SC_CLIPRECT_2_TL, tl);
261	si_pm4_set_reg(pm4, R_028224_PA_SC_CLIPRECT_2_BR, br);
262	si_pm4_set_reg(pm4, R_028228_PA_SC_CLIPRECT_3_TL, tl);
263	si_pm4_set_reg(pm4, R_02822C_PA_SC_CLIPRECT_3_BR, br);
264
265	si_pm4_set_state(rctx, scissor, pm4);
266}
267
268static void si_set_viewport_state(struct pipe_context *ctx,
269				  const struct pipe_viewport_state *state)
270{
271	struct r600_context *rctx = (struct r600_context *)ctx;
272	struct si_state_viewport *viewport = CALLOC_STRUCT(si_state_viewport);
273	struct si_pm4_state *pm4 = &viewport->pm4;
274
275	if (viewport == NULL)
276		return;
277
278	viewport->viewport = *state;
279	si_pm4_set_reg(pm4, R_0282D0_PA_SC_VPORT_ZMIN_0, 0x00000000);
280	si_pm4_set_reg(pm4, R_0282D4_PA_SC_VPORT_ZMAX_0, 0x3F800000);
281	si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000);
282	si_pm4_set_reg(pm4, R_02843C_PA_CL_VPORT_XSCALE_0, fui(state->scale[0]));
283	si_pm4_set_reg(pm4, R_028440_PA_CL_VPORT_XOFFSET_0, fui(state->translate[0]));
284	si_pm4_set_reg(pm4, R_028444_PA_CL_VPORT_YSCALE_0, fui(state->scale[1]));
285	si_pm4_set_reg(pm4, R_028448_PA_CL_VPORT_YOFFSET_0, fui(state->translate[1]));
286	si_pm4_set_reg(pm4, R_02844C_PA_CL_VPORT_ZSCALE_0, fui(state->scale[2]));
287	si_pm4_set_reg(pm4, R_028450_PA_CL_VPORT_ZOFFSET_0, fui(state->translate[2]));
288	si_pm4_set_reg(pm4, R_028818_PA_CL_VTE_CNTL, 0x0000043F);
289
290	si_pm4_set_state(rctx, viewport, viewport);
291}
292
293/*
294 * inferred state between framebuffer and rasterizer
295 */
296static void si_update_fb_rs_state(struct r600_context *rctx)
297{
298	struct si_state_rasterizer *rs = rctx->queued.named.rasterizer;
299	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
300	unsigned offset_db_fmt_cntl = 0, depth;
301	float offset_units;
302
303	if (!rs || !rctx->framebuffer.zsbuf) {
304		FREE(pm4);
305		return;
306	}
307
308	offset_units = rctx->queued.named.rasterizer->offset_units;
309	switch (rctx->framebuffer.zsbuf->texture->format) {
310	case PIPE_FORMAT_Z24X8_UNORM:
311	case PIPE_FORMAT_Z24_UNORM_S8_UINT:
312		depth = -24;
313		offset_units *= 2.0f;
314		break;
315	case PIPE_FORMAT_Z32_FLOAT:
316	case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
317		depth = -23;
318		offset_units *= 1.0f;
319		offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
320		break;
321	case PIPE_FORMAT_Z16_UNORM:
322		depth = -16;
323		offset_units *= 4.0f;
324		break;
325	default:
326		return;
327	}
328
329	/* FIXME some of those reg can be computed with cso */
330	offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth);
331	si_pm4_set_reg(pm4, R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE,
332		       fui(rctx->queued.named.rasterizer->offset_scale));
333	si_pm4_set_reg(pm4, R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, fui(offset_units));
334	si_pm4_set_reg(pm4, R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE,
335		       fui(rctx->queued.named.rasterizer->offset_scale));
336	si_pm4_set_reg(pm4, R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, fui(offset_units));
337	si_pm4_set_reg(pm4, R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, offset_db_fmt_cntl);
338
339	si_pm4_set_state(rctx, fb_rs, pm4);
340}
341
342/*
343 * Rasterizer
344 */
345
346static uint32_t si_translate_fill(uint32_t func)
347{
348	switch(func) {
349	case PIPE_POLYGON_MODE_FILL:
350		return V_028814_X_DRAW_TRIANGLES;
351	case PIPE_POLYGON_MODE_LINE:
352		return V_028814_X_DRAW_LINES;
353	case PIPE_POLYGON_MODE_POINT:
354		return V_028814_X_DRAW_POINTS;
355	default:
356		assert(0);
357		return V_028814_X_DRAW_POINTS;
358	}
359}
360
361static void *si_create_rs_state(struct pipe_context *ctx,
362				const struct pipe_rasterizer_state *state)
363{
364	struct si_state_rasterizer *rs = CALLOC_STRUCT(si_state_rasterizer);
365	struct si_pm4_state *pm4 = &rs->pm4;
366	unsigned tmp;
367	unsigned prov_vtx = 1, polygon_dual_mode;
368	unsigned clip_rule;
369	float psize_min, psize_max;
370
371	if (rs == NULL) {
372		return NULL;
373	}
374
375	polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
376				state->fill_back != PIPE_POLYGON_MODE_FILL);
377
378	if (state->flatshade_first)
379		prov_vtx = 0;
380
381	rs->flatshade = state->flatshade;
382	rs->sprite_coord_enable = state->sprite_coord_enable;
383	rs->pa_sc_line_stipple = state->line_stipple_enable ?
384				S_028A0C_LINE_PATTERN(state->line_stipple_pattern) |
385				S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0;
386	rs->pa_su_sc_mode_cntl =
387		S_028814_PROVOKING_VTX_LAST(prov_vtx) |
388		S_028814_CULL_FRONT(state->rasterizer_discard || (state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) |
389		S_028814_CULL_BACK(state->rasterizer_discard || (state->cull_face & PIPE_FACE_BACK) ? 1 : 0) |
390		S_028814_FACE(!state->front_ccw) |
391		S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
392		S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
393		S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri) |
394		S_028814_POLY_MODE(polygon_dual_mode) |
395		S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) |
396		S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back));
397	rs->pa_cl_clip_cntl =
398		S_028810_PS_UCP_MODE(3) |
399		S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) |
400		S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) |
401		S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
402	rs->pa_cl_vs_out_cntl =
403		S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) |
404		S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex);
405
406	clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
407
408	/* offset */
409	rs->offset_units = state->offset_units;
410	rs->offset_scale = state->offset_scale * 12.0f;
411
412	/* XXX: Flat shading hangs the GPU */
413	tmp = S_0286D4_FLAT_SHADE_ENA(0);
414	if (state->sprite_coord_enable) {
415		tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
416			S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
417			S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
418			S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) |
419			S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1);
420		if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) {
421			tmp |= S_0286D4_PNT_SPRITE_TOP_1(1);
422		}
423	}
424	si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0, tmp);
425
426	si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0x00000000);
427	/* point size 12.4 fixed point */
428	tmp = (unsigned)(state->point_size * 8.0);
429	si_pm4_set_reg(pm4, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
430
431	if (state->point_size_per_vertex) {
432		psize_min = util_get_min_point_size(state);
433		psize_max = 8192;
434	} else {
435		/* Force the point size to be as if the vertex output was disabled. */
436		psize_min = state->point_size;
437		psize_max = state->point_size;
438	}
439	/* Divide by two, because 0.5 = 1 pixel. */
440	si_pm4_set_reg(pm4, R_028A04_PA_SU_POINT_MINMAX,
441			S_028A04_MIN_SIZE(r600_pack_float_12p4(psize_min/2)) |
442			S_028A04_MAX_SIZE(r600_pack_float_12p4(psize_max/2)));
443
444	tmp = (unsigned)state->line_width * 8;
445	si_pm4_set_reg(pm4, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp));
446	si_pm4_set_reg(pm4, R_028A48_PA_SC_MODE_CNTL_0,
447			S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable));
448
449	si_pm4_set_reg(pm4, R_028BDC_PA_SC_LINE_CNTL, 0x00000400);
450	si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL,
451			S_028BE4_PIX_CENTER(state->gl_rasterization_rules));
452	si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000);
453	si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000);
454	si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000);
455	si_pm4_set_reg(pm4, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000);
456
457	si_pm4_set_reg(pm4, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp));
458	si_pm4_set_reg(pm4, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule);
459
460	return rs;
461}
462
463static void si_bind_rs_state(struct pipe_context *ctx, void *state)
464{
465	struct r600_context *rctx = (struct r600_context *)ctx;
466	struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state;
467
468	if (state == NULL)
469		return;
470
471	// TODO
472	rctx->sprite_coord_enable = rs->sprite_coord_enable;
473	rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
474	rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
475	rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
476	rctx->pa_cl_vs_out_cntl = rs->pa_cl_vs_out_cntl;
477
478	si_pm4_bind_state(rctx, rasterizer, rs);
479	si_update_fb_rs_state(rctx);
480}
481
482static void si_delete_rs_state(struct pipe_context *ctx, void *state)
483{
484	struct r600_context *rctx = (struct r600_context *)ctx;
485	si_pm4_delete_state(rctx, rasterizer, (struct si_state_rasterizer *)state);
486}
487
488/*
489 * infeered state between dsa and stencil ref
490 */
491static void si_update_dsa_stencil_ref(struct r600_context *rctx)
492{
493	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
494	struct pipe_stencil_ref *ref = &rctx->stencil_ref;
495        struct si_state_dsa *dsa = rctx->queued.named.dsa;
496
497        if (pm4 == NULL)
498                return;
499
500	si_pm4_set_reg(pm4, R_028430_DB_STENCILREFMASK,
501		       S_028430_STENCILTESTVAL(ref->ref_value[0]) |
502		       S_028430_STENCILMASK(dsa->valuemask[0]) |
503		       S_028430_STENCILWRITEMASK(dsa->writemask[0]));
504	si_pm4_set_reg(pm4, R_028434_DB_STENCILREFMASK_BF,
505		       S_028434_STENCILTESTVAL_BF(ref->ref_value[1]) |
506		       S_028434_STENCILMASK_BF(dsa->valuemask[1]) |
507		       S_028434_STENCILWRITEMASK_BF(dsa->writemask[1]));
508
509	si_pm4_set_state(rctx, dsa_stencil_ref, pm4);
510}
511
512static void si_set_pipe_stencil_ref(struct pipe_context *ctx,
513				    const struct pipe_stencil_ref *state)
514{
515        struct r600_context *rctx = (struct r600_context *)ctx;
516        rctx->stencil_ref = *state;
517	si_update_dsa_stencil_ref(rctx);
518}
519
520
521/*
522 * DSA
523 */
524
525/* transnates straight */
526static uint32_t si_translate_ds_func(int func)
527{
528        return func;
529}
530
531static void *si_create_dsa_state(struct pipe_context *ctx,
532				 const struct pipe_depth_stencil_alpha_state *state)
533{
534	struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa);
535	struct si_pm4_state *pm4 = &dsa->pm4;
536	unsigned db_depth_control, /* alpha_test_control, */ alpha_ref;
537	unsigned db_render_override, db_render_control;
538
539	if (dsa == NULL) {
540		return NULL;
541	}
542
543	dsa->valuemask[0] = state->stencil[0].valuemask;
544	dsa->valuemask[1] = state->stencil[1].valuemask;
545	dsa->writemask[0] = state->stencil[0].writemask;
546	dsa->writemask[1] = state->stencil[1].writemask;
547
548	db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
549		S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
550		S_028800_ZFUNC(state->depth.func);
551
552	/* stencil */
553	if (state->stencil[0].enabled) {
554		db_depth_control |= S_028800_STENCIL_ENABLE(1);
555		db_depth_control |= S_028800_STENCILFUNC(si_translate_ds_func(state->stencil[0].func));
556		//db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op));
557		//db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op));
558		//db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op));
559
560		if (state->stencil[1].enabled) {
561			db_depth_control |= S_028800_BACKFACE_ENABLE(1);
562			db_depth_control |= S_028800_STENCILFUNC_BF(si_translate_ds_func(state->stencil[1].func));
563			//db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op));
564			//db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op));
565			//db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op));
566		}
567	}
568
569	/* alpha */
570	//alpha_test_control = 0;
571	alpha_ref = 0;
572	if (state->alpha.enabled) {
573		//alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func);
574		//alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
575		alpha_ref = fui(state->alpha.ref_value);
576	}
577	dsa->alpha_ref = alpha_ref;
578
579	/* misc */
580	db_render_control = 0;
581	db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
582		S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
583		S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE);
584	/* TODO db_render_override depends on query */
585	si_pm4_set_reg(pm4, R_028020_DB_DEPTH_BOUNDS_MIN, 0x00000000);
586	si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, 0x00000000);
587	si_pm4_set_reg(pm4, R_028028_DB_STENCIL_CLEAR, 0x00000000);
588	si_pm4_set_reg(pm4, R_02802C_DB_DEPTH_CLEAR, 0x3F800000);
589	//si_pm4_set_reg(pm4, R_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control);
590	si_pm4_set_reg(pm4, R_028800_DB_DEPTH_CONTROL, db_depth_control);
591	si_pm4_set_reg(pm4, R_028000_DB_RENDER_CONTROL, db_render_control);
592	si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE, db_render_override);
593	si_pm4_set_reg(pm4, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0);
594	si_pm4_set_reg(pm4, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0);
595	si_pm4_set_reg(pm4, R_028AC8_DB_PRELOAD_CONTROL, 0x0);
596	si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK, 0x0000AA00);
597	dsa->db_render_override = db_render_override;
598
599	return dsa;
600}
601
602static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
603{
604        struct r600_context *rctx = (struct r600_context *)ctx;
605        struct si_state_dsa *dsa = state;
606
607        if (state == NULL)
608                return;
609
610	si_pm4_bind_state(rctx, dsa, dsa);
611	si_update_dsa_stencil_ref(rctx);
612
613	// TODO
614        rctx->alpha_ref = dsa->alpha_ref;
615        rctx->alpha_ref_dirty = true;
616}
617
618static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
619{
620	struct r600_context *rctx = (struct r600_context *)ctx;
621	si_pm4_delete_state(rctx, dsa, (struct si_state_dsa *)state);
622}
623
624static void *si_create_db_flush_dsa(struct r600_context *rctx)
625{
626	struct pipe_depth_stencil_alpha_state dsa;
627        struct si_state_dsa *state;
628
629	memset(&dsa, 0, sizeof(dsa));
630
631	state = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
632	si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
633		       S_028000_DEPTH_COPY(1) |
634		       S_028000_STENCIL_COPY(1) |
635		       S_028000_COPY_CENTROID(1));
636        return state;
637}
638
639/*
640 * format translation
641 */
642static uint32_t si_translate_colorformat(enum pipe_format format)
643{
644	switch (format) {
645	/* 8-bit buffers. */
646	case PIPE_FORMAT_A8_UNORM:
647	case PIPE_FORMAT_A8_UINT:
648	case PIPE_FORMAT_A8_SINT:
649	case PIPE_FORMAT_I8_UNORM:
650	case PIPE_FORMAT_I8_UINT:
651	case PIPE_FORMAT_I8_SINT:
652	case PIPE_FORMAT_L8_UNORM:
653	case PIPE_FORMAT_L8_UINT:
654	case PIPE_FORMAT_L8_SINT:
655	case PIPE_FORMAT_L8_SRGB:
656	case PIPE_FORMAT_R8_UNORM:
657	case PIPE_FORMAT_R8_SNORM:
658	case PIPE_FORMAT_R8_UINT:
659	case PIPE_FORMAT_R8_SINT:
660		return V_028C70_COLOR_8;
661
662	/* 16-bit buffers. */
663	case PIPE_FORMAT_B5G6R5_UNORM:
664		return V_028C70_COLOR_5_6_5;
665
666	case PIPE_FORMAT_B5G5R5A1_UNORM:
667	case PIPE_FORMAT_B5G5R5X1_UNORM:
668		return V_028C70_COLOR_1_5_5_5;
669
670	case PIPE_FORMAT_B4G4R4A4_UNORM:
671	case PIPE_FORMAT_B4G4R4X4_UNORM:
672		return V_028C70_COLOR_4_4_4_4;
673
674	case PIPE_FORMAT_L8A8_UNORM:
675	case PIPE_FORMAT_L8A8_UINT:
676	case PIPE_FORMAT_L8A8_SINT:
677	case PIPE_FORMAT_L8A8_SRGB:
678	case PIPE_FORMAT_R8G8_UNORM:
679	case PIPE_FORMAT_R8G8_UINT:
680	case PIPE_FORMAT_R8G8_SINT:
681		return V_028C70_COLOR_8_8;
682
683	case PIPE_FORMAT_Z16_UNORM:
684	case PIPE_FORMAT_R16_UNORM:
685	case PIPE_FORMAT_R16_UINT:
686	case PIPE_FORMAT_R16_SINT:
687	case PIPE_FORMAT_R16_FLOAT:
688	case PIPE_FORMAT_R16G16_FLOAT:
689		return V_028C70_COLOR_16;
690
691	/* 32-bit buffers. */
692	case PIPE_FORMAT_A8B8G8R8_SRGB:
693	case PIPE_FORMAT_A8B8G8R8_UNORM:
694	case PIPE_FORMAT_A8R8G8B8_UNORM:
695	case PIPE_FORMAT_B8G8R8A8_SRGB:
696	case PIPE_FORMAT_B8G8R8A8_UNORM:
697	case PIPE_FORMAT_B8G8R8X8_UNORM:
698	case PIPE_FORMAT_R8G8B8A8_SNORM:
699	case PIPE_FORMAT_R8G8B8A8_UNORM:
700	case PIPE_FORMAT_R8G8B8X8_UNORM:
701	case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
702	case PIPE_FORMAT_X8B8G8R8_UNORM:
703	case PIPE_FORMAT_X8R8G8B8_UNORM:
704	case PIPE_FORMAT_R8G8B8_UNORM:
705	case PIPE_FORMAT_R8G8B8A8_SSCALED:
706	case PIPE_FORMAT_R8G8B8A8_USCALED:
707	case PIPE_FORMAT_R8G8B8A8_SINT:
708	case PIPE_FORMAT_R8G8B8A8_UINT:
709		return V_028C70_COLOR_8_8_8_8;
710
711	case PIPE_FORMAT_R10G10B10A2_UNORM:
712	case PIPE_FORMAT_R10G10B10X2_SNORM:
713	case PIPE_FORMAT_B10G10R10A2_UNORM:
714	case PIPE_FORMAT_B10G10R10A2_UINT:
715	case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
716		return V_028C70_COLOR_2_10_10_10;
717
718	case PIPE_FORMAT_Z24X8_UNORM:
719	case PIPE_FORMAT_Z24_UNORM_S8_UINT:
720		return V_028C70_COLOR_8_24;
721
722	case PIPE_FORMAT_X8Z24_UNORM:
723	case PIPE_FORMAT_S8_UINT_Z24_UNORM:
724		return V_028C70_COLOR_24_8;
725
726	case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
727		return V_028C70_COLOR_X24_8_32_FLOAT;
728
729	case PIPE_FORMAT_R32_FLOAT:
730	case PIPE_FORMAT_Z32_FLOAT:
731		return V_028C70_COLOR_32;
732
733	case PIPE_FORMAT_R16G16_SSCALED:
734	case PIPE_FORMAT_R16G16_UNORM:
735	case PIPE_FORMAT_R16G16_UINT:
736	case PIPE_FORMAT_R16G16_SINT:
737		return V_028C70_COLOR_16_16;
738
739	case PIPE_FORMAT_R11G11B10_FLOAT:
740		return V_028C70_COLOR_10_11_11;
741
742	/* 64-bit buffers. */
743	case PIPE_FORMAT_R16G16B16_USCALED:
744	case PIPE_FORMAT_R16G16B16_SSCALED:
745	case PIPE_FORMAT_R16G16B16A16_UINT:
746	case PIPE_FORMAT_R16G16B16A16_SINT:
747	case PIPE_FORMAT_R16G16B16A16_USCALED:
748	case PIPE_FORMAT_R16G16B16A16_SSCALED:
749	case PIPE_FORMAT_R16G16B16A16_UNORM:
750	case PIPE_FORMAT_R16G16B16A16_SNORM:
751	case PIPE_FORMAT_R16G16B16_FLOAT:
752	case PIPE_FORMAT_R16G16B16A16_FLOAT:
753		return V_028C70_COLOR_16_16_16_16;
754
755	case PIPE_FORMAT_R32G32_FLOAT:
756	case PIPE_FORMAT_R32G32_USCALED:
757	case PIPE_FORMAT_R32G32_SSCALED:
758	case PIPE_FORMAT_R32G32_SINT:
759	case PIPE_FORMAT_R32G32_UINT:
760		return V_028C70_COLOR_32_32;
761
762	/* 128-bit buffers. */
763	case PIPE_FORMAT_R32G32B32A32_SNORM:
764	case PIPE_FORMAT_R32G32B32A32_UNORM:
765	case PIPE_FORMAT_R32G32B32A32_SSCALED:
766	case PIPE_FORMAT_R32G32B32A32_USCALED:
767	case PIPE_FORMAT_R32G32B32A32_SINT:
768	case PIPE_FORMAT_R32G32B32A32_UINT:
769	case PIPE_FORMAT_R32G32B32A32_FLOAT:
770		return V_028C70_COLOR_32_32_32_32;
771
772	/* YUV buffers. */
773	case PIPE_FORMAT_UYVY:
774	case PIPE_FORMAT_YUYV:
775	/* 96-bit buffers. */
776	case PIPE_FORMAT_R32G32B32_FLOAT:
777	/* 8-bit buffers. */
778	case PIPE_FORMAT_L4A4_UNORM:
779	case PIPE_FORMAT_R4A4_UNORM:
780	case PIPE_FORMAT_A4R4_UNORM:
781	default:
782		return ~0U; /* Unsupported. */
783	}
784}
785
786static uint32_t si_translate_colorswap(enum pipe_format format)
787{
788	switch (format) {
789	/* 8-bit buffers. */
790	case PIPE_FORMAT_L4A4_UNORM:
791	case PIPE_FORMAT_A4R4_UNORM:
792		return V_028C70_SWAP_ALT;
793
794	case PIPE_FORMAT_A8_UNORM:
795	case PIPE_FORMAT_A8_UINT:
796	case PIPE_FORMAT_A8_SINT:
797	case PIPE_FORMAT_R4A4_UNORM:
798		return V_028C70_SWAP_ALT_REV;
799	case PIPE_FORMAT_I8_UNORM:
800	case PIPE_FORMAT_L8_UNORM:
801	case PIPE_FORMAT_I8_UINT:
802	case PIPE_FORMAT_I8_SINT:
803	case PIPE_FORMAT_L8_UINT:
804	case PIPE_FORMAT_L8_SINT:
805	case PIPE_FORMAT_L8_SRGB:
806	case PIPE_FORMAT_R8_UNORM:
807	case PIPE_FORMAT_R8_SNORM:
808	case PIPE_FORMAT_R8_UINT:
809	case PIPE_FORMAT_R8_SINT:
810		return V_028C70_SWAP_STD;
811
812	/* 16-bit buffers. */
813	case PIPE_FORMAT_B5G6R5_UNORM:
814		return V_028C70_SWAP_STD_REV;
815
816	case PIPE_FORMAT_B5G5R5A1_UNORM:
817	case PIPE_FORMAT_B5G5R5X1_UNORM:
818		return V_028C70_SWAP_ALT;
819
820	case PIPE_FORMAT_B4G4R4A4_UNORM:
821	case PIPE_FORMAT_B4G4R4X4_UNORM:
822		return V_028C70_SWAP_ALT;
823
824	case PIPE_FORMAT_Z16_UNORM:
825		return V_028C70_SWAP_STD;
826
827	case PIPE_FORMAT_L8A8_UNORM:
828	case PIPE_FORMAT_L8A8_UINT:
829	case PIPE_FORMAT_L8A8_SINT:
830	case PIPE_FORMAT_L8A8_SRGB:
831		return V_028C70_SWAP_ALT;
832	case PIPE_FORMAT_R8G8_UNORM:
833	case PIPE_FORMAT_R8G8_UINT:
834	case PIPE_FORMAT_R8G8_SINT:
835		return V_028C70_SWAP_STD;
836
837	case PIPE_FORMAT_R16_UNORM:
838	case PIPE_FORMAT_R16_UINT:
839	case PIPE_FORMAT_R16_SINT:
840	case PIPE_FORMAT_R16_FLOAT:
841		return V_028C70_SWAP_STD;
842
843	/* 32-bit buffers. */
844	case PIPE_FORMAT_A8B8G8R8_SRGB:
845		return V_028C70_SWAP_STD_REV;
846	case PIPE_FORMAT_B8G8R8A8_SRGB:
847		return V_028C70_SWAP_ALT;
848
849	case PIPE_FORMAT_B8G8R8A8_UNORM:
850	case PIPE_FORMAT_B8G8R8X8_UNORM:
851		return V_028C70_SWAP_ALT;
852
853	case PIPE_FORMAT_A8R8G8B8_UNORM:
854	case PIPE_FORMAT_X8R8G8B8_UNORM:
855		return V_028C70_SWAP_ALT_REV;
856	case PIPE_FORMAT_R8G8B8A8_SNORM:
857	case PIPE_FORMAT_R8G8B8A8_UNORM:
858	case PIPE_FORMAT_R8G8B8A8_SSCALED:
859	case PIPE_FORMAT_R8G8B8A8_USCALED:
860	case PIPE_FORMAT_R8G8B8A8_SINT:
861	case PIPE_FORMAT_R8G8B8A8_UINT:
862	case PIPE_FORMAT_R8G8B8X8_UNORM:
863		return V_028C70_SWAP_STD;
864
865	case PIPE_FORMAT_A8B8G8R8_UNORM:
866	case PIPE_FORMAT_X8B8G8R8_UNORM:
867	/* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
868		return V_028C70_SWAP_STD_REV;
869
870	case PIPE_FORMAT_Z24X8_UNORM:
871	case PIPE_FORMAT_Z24_UNORM_S8_UINT:
872		return V_028C70_SWAP_STD;
873
874	case PIPE_FORMAT_X8Z24_UNORM:
875	case PIPE_FORMAT_S8_UINT_Z24_UNORM:
876		return V_028C70_SWAP_STD;
877
878	case PIPE_FORMAT_R10G10B10A2_UNORM:
879	case PIPE_FORMAT_R10G10B10X2_SNORM:
880	case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
881		return V_028C70_SWAP_STD;
882
883	case PIPE_FORMAT_B10G10R10A2_UNORM:
884	case PIPE_FORMAT_B10G10R10A2_UINT:
885		return V_028C70_SWAP_ALT;
886
887	case PIPE_FORMAT_R11G11B10_FLOAT:
888	case PIPE_FORMAT_R32_FLOAT:
889	case PIPE_FORMAT_R32_UINT:
890	case PIPE_FORMAT_R32_SINT:
891	case PIPE_FORMAT_Z32_FLOAT:
892	case PIPE_FORMAT_R16G16_FLOAT:
893	case PIPE_FORMAT_R16G16_UNORM:
894	case PIPE_FORMAT_R16G16_UINT:
895	case PIPE_FORMAT_R16G16_SINT:
896		return V_028C70_SWAP_STD;
897
898	/* 64-bit buffers. */
899	case PIPE_FORMAT_R32G32_FLOAT:
900	case PIPE_FORMAT_R32G32_UINT:
901	case PIPE_FORMAT_R32G32_SINT:
902	case PIPE_FORMAT_R16G16B16A16_UNORM:
903	case PIPE_FORMAT_R16G16B16A16_SNORM:
904	case PIPE_FORMAT_R16G16B16A16_USCALED:
905	case PIPE_FORMAT_R16G16B16A16_SSCALED:
906	case PIPE_FORMAT_R16G16B16A16_UINT:
907	case PIPE_FORMAT_R16G16B16A16_SINT:
908	case PIPE_FORMAT_R16G16B16A16_FLOAT:
909	case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
910
911	/* 128-bit buffers. */
912	case PIPE_FORMAT_R32G32B32A32_FLOAT:
913	case PIPE_FORMAT_R32G32B32A32_SNORM:
914	case PIPE_FORMAT_R32G32B32A32_UNORM:
915	case PIPE_FORMAT_R32G32B32A32_SSCALED:
916	case PIPE_FORMAT_R32G32B32A32_USCALED:
917	case PIPE_FORMAT_R32G32B32A32_SINT:
918	case PIPE_FORMAT_R32G32B32A32_UINT:
919		return V_028C70_SWAP_STD;
920	default:
921		R600_ERR("unsupported colorswap format %d\n", format);
922		return ~0U;
923	}
924	return ~0U;
925}
926
927static uint32_t si_colorformat_endian_swap(uint32_t colorformat)
928{
929	if (R600_BIG_ENDIAN) {
930		switch(colorformat) {
931		/* 8-bit buffers. */
932		case V_028C70_COLOR_8:
933			return V_028C70_ENDIAN_NONE;
934
935		/* 16-bit buffers. */
936		case V_028C70_COLOR_5_6_5:
937		case V_028C70_COLOR_1_5_5_5:
938		case V_028C70_COLOR_4_4_4_4:
939		case V_028C70_COLOR_16:
940		case V_028C70_COLOR_8_8:
941			return V_028C70_ENDIAN_8IN16;
942
943		/* 32-bit buffers. */
944		case V_028C70_COLOR_8_8_8_8:
945		case V_028C70_COLOR_2_10_10_10:
946		case V_028C70_COLOR_8_24:
947		case V_028C70_COLOR_24_8:
948		case V_028C70_COLOR_16_16:
949			return V_028C70_ENDIAN_8IN32;
950
951		/* 64-bit buffers. */
952		case V_028C70_COLOR_16_16_16_16:
953			return V_028C70_ENDIAN_8IN16;
954
955		case V_028C70_COLOR_32_32:
956			return V_028C70_ENDIAN_8IN32;
957
958		/* 128-bit buffers. */
959		case V_028C70_COLOR_32_32_32_32:
960			return V_028C70_ENDIAN_8IN32;
961		default:
962			return V_028C70_ENDIAN_NONE; /* Unsupported. */
963		}
964	} else {
965		return V_028C70_ENDIAN_NONE;
966	}
967}
968
969static uint32_t si_translate_dbformat(enum pipe_format format)
970{
971	switch (format) {
972	case PIPE_FORMAT_Z16_UNORM:
973		return V_028040_Z_16;
974	case PIPE_FORMAT_Z24X8_UNORM:
975	case PIPE_FORMAT_Z24_UNORM_S8_UINT:
976		return V_028040_Z_24; /* XXX no longer supported on SI */
977	case PIPE_FORMAT_Z32_FLOAT:
978	case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
979		return V_028040_Z_32_FLOAT;
980	default:
981		return ~0U;
982	}
983}
984
985/*
986 * framebuffer handling
987 */
988
989static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
990		  const struct pipe_framebuffer_state *state, int cb)
991{
992	struct r600_resource_texture *rtex;
993	struct r600_surface *surf;
994	unsigned level = state->cbufs[cb]->u.tex.level;
995	unsigned pitch, slice;
996	unsigned color_info, color_attrib;
997	unsigned format, swap, ntype, endian;
998	uint64_t offset;
999	unsigned blocksize;
1000	const struct util_format_description *desc;
1001	int i;
1002	unsigned blend_clamp = 0, blend_bypass = 0;
1003
1004	surf = (struct r600_surface *)state->cbufs[cb];
1005	rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
1006	blocksize = util_format_get_blocksize(rtex->real_format);
1007
1008	if (rtex->depth)
1009		rctx->have_depth_fb = TRUE;
1010
1011	if (rtex->depth && !rtex->is_flushing_texture) {
1012	        r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE);
1013		rtex = rtex->flushed_depth_texture;
1014	}
1015
1016	offset = rtex->surface.level[level].offset;
1017	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
1018		offset += rtex->surface.level[level].slice_size *
1019			  state->cbufs[cb]->u.tex.first_layer;
1020	}
1021	pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
1022	slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
1023	if (slice) {
1024		slice = slice - 1;
1025	}
1026
1027	color_attrib = S_028C74_TILE_MODE_INDEX(8);
1028	switch (rtex->surface.level[level].mode) {
1029	case RADEON_SURF_MODE_LINEAR_ALIGNED:
1030		color_attrib = S_028C74_TILE_MODE_INDEX(8);
1031		break;
1032	case RADEON_SURF_MODE_1D:
1033		color_attrib = S_028C74_TILE_MODE_INDEX(9);
1034		break;
1035	case RADEON_SURF_MODE_2D:
1036		if (rtex->resource.b.b.bind & PIPE_BIND_SCANOUT) {
1037			switch (blocksize) {
1038			case 1:
1039				color_attrib = S_028C74_TILE_MODE_INDEX(10);
1040				break;
1041			case 2:
1042				color_attrib = S_028C74_TILE_MODE_INDEX(11);
1043				break;
1044			case 4:
1045				color_attrib = S_028C74_TILE_MODE_INDEX(12);
1046				break;
1047			}
1048			break;
1049		} else switch (blocksize) {
1050		case 1:
1051			color_attrib = S_028C74_TILE_MODE_INDEX(14);
1052			break;
1053		case 2:
1054			color_attrib = S_028C74_TILE_MODE_INDEX(15);
1055			break;
1056		case 4:
1057			color_attrib = S_028C74_TILE_MODE_INDEX(16);
1058			break;
1059		case 8:
1060			color_attrib = S_028C74_TILE_MODE_INDEX(17);
1061			break;
1062		default:
1063			color_attrib = S_028C74_TILE_MODE_INDEX(13);
1064		}
1065		break;
1066	}
1067
1068	desc = util_format_description(surf->base.format);
1069	for (i = 0; i < 4; i++) {
1070		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
1071			break;
1072		}
1073	}
1074	if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
1075		ntype = V_028C70_NUMBER_FLOAT;
1076	} else {
1077		ntype = V_028C70_NUMBER_UNORM;
1078		if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
1079			ntype = V_028C70_NUMBER_SRGB;
1080		else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
1081			if (desc->channel[i].normalized)
1082				ntype = V_028C70_NUMBER_SNORM;
1083			else if (desc->channel[i].pure_integer)
1084				ntype = V_028C70_NUMBER_SINT;
1085		} else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
1086			if (desc->channel[i].normalized)
1087				ntype = V_028C70_NUMBER_UNORM;
1088			else if (desc->channel[i].pure_integer)
1089				ntype = V_028C70_NUMBER_UINT;
1090		}
1091	}
1092
1093	format = si_translate_colorformat(surf->base.format);
1094	swap = si_translate_colorswap(surf->base.format);
1095	if (rtex->resource.b.b.usage == PIPE_USAGE_STAGING) {
1096		endian = V_028C70_ENDIAN_NONE;
1097	} else {
1098		endian = si_colorformat_endian_swap(format);
1099	}
1100
1101	/* blend clamp should be set for all NORM/SRGB types */
1102	if (ntype == V_028C70_NUMBER_UNORM ||
1103	    ntype == V_028C70_NUMBER_SNORM ||
1104	    ntype == V_028C70_NUMBER_SRGB)
1105		blend_clamp = 1;
1106
1107	/* set blend bypass according to docs if SINT/UINT or
1108	   8/24 COLOR variants */
1109	if (ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT ||
1110	    format == V_028C70_COLOR_8_24 || format == V_028C70_COLOR_24_8 ||
1111	    format == V_028C70_COLOR_X24_8_32_FLOAT) {
1112		blend_clamp = 0;
1113		blend_bypass = 1;
1114	}
1115
1116	color_info = S_028C70_FORMAT(format) |
1117		S_028C70_COMP_SWAP(swap) |
1118		S_028C70_BLEND_CLAMP(blend_clamp) |
1119		S_028C70_BLEND_BYPASS(blend_bypass) |
1120		S_028C70_NUMBER_TYPE(ntype) |
1121		S_028C70_ENDIAN(endian);
1122
1123	rctx->alpha_ref_dirty = true;
1124
1125	offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
1126	offset >>= 8;
1127
1128	/* FIXME handle enabling of CB beyond BASE8 which has different offset */
1129	si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
1130	si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset);
1131	si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, S_028C64_TILE_MAX(pitch));
1132	si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice));
1133
1134	if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
1135		si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 0x00000000);
1136	} else {
1137		si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
1138			       S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
1139			       S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
1140	}
1141	si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
1142	si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
1143}
1144
1145static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
1146		  const struct pipe_framebuffer_state *state)
1147{
1148	struct r600_resource_texture *rtex;
1149	struct r600_surface *surf;
1150	unsigned level, first_layer, pitch, slice, format;
1151	uint32_t db_z_info, stencil_info;
1152	uint64_t offset;
1153
1154	if (state->zsbuf == NULL) {
1155		si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
1156		si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
1157		return;
1158	}
1159
1160	surf = (struct r600_surface *)state->zsbuf;
1161	level = surf->base.u.tex.level;
1162	rtex = (struct r600_resource_texture*)surf->base.texture;
1163
1164	first_layer = surf->base.u.tex.first_layer;
1165	format = si_translate_dbformat(rtex->real_format);
1166
1167	offset = r600_resource_va(rctx->context.screen, surf->base.texture);
1168	offset += rtex->surface.level[level].offset;
1169	pitch = (rtex->surface.level[level].nblk_x / 8) - 1;
1170	slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
1171	if (slice) {
1172		slice = slice - 1;
1173	}
1174	offset >>= 8;
1175
1176	si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
1177	si_pm4_set_reg(pm4, R_028048_DB_Z_READ_BASE, offset);
1178	si_pm4_set_reg(pm4, R_028050_DB_Z_WRITE_BASE, offset);
1179	si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW,
1180		       S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
1181		       S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer));
1182
1183	db_z_info = S_028040_FORMAT(format);
1184	stencil_info = S_028044_FORMAT(rtex->stencil != 0);
1185
1186	switch (format) {
1187	case V_028040_Z_16:
1188		db_z_info |= S_028040_TILE_MODE_INDEX(5);
1189		stencil_info |= S_028044_TILE_MODE_INDEX(5);
1190		break;
1191	case V_028040_Z_24:
1192	case V_028040_Z_32_FLOAT:
1193		db_z_info |= S_028040_TILE_MODE_INDEX(6);
1194		stencil_info |= S_028044_TILE_MODE_INDEX(6);
1195		break;
1196	default:
1197		db_z_info |= S_028040_TILE_MODE_INDEX(7);
1198		stencil_info |= S_028044_TILE_MODE_INDEX(7);
1199	}
1200
1201	if (rtex->stencil) {
1202		uint64_t stencil_offset =
1203			r600_texture_get_offset(rtex->stencil, level, first_layer);
1204
1205		stencil_offset += r600_resource_va(rctx->context.screen, (void*)rtex->stencil);
1206		stencil_offset >>= 8;
1207
1208		si_pm4_add_bo(pm4, &rtex->stencil->resource, RADEON_USAGE_READWRITE);
1209		si_pm4_set_reg(pm4, R_02804C_DB_STENCIL_READ_BASE, stencil_offset);
1210		si_pm4_set_reg(pm4, R_028054_DB_STENCIL_WRITE_BASE, stencil_offset);
1211		si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, stencil_info);
1212	} else {
1213		si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
1214	}
1215
1216	if (format != ~0U) {
1217		si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, 0x1);
1218		si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, db_z_info);
1219		si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch));
1220		si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice));
1221
1222	} else {
1223		si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
1224	}
1225}
1226
1227static void si_set_framebuffer_state(struct pipe_context *ctx,
1228				     const struct pipe_framebuffer_state *state)
1229{
1230	struct r600_context *rctx = (struct r600_context *)ctx;
1231	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
1232	uint32_t shader_mask, tl, br;
1233	int tl_x, tl_y, br_x, br_y;
1234
1235	if (pm4 == NULL)
1236		return;
1237
1238	si_pm4_inval_fb_cache(pm4, state->nr_cbufs);
1239
1240	if (state->zsbuf)
1241		si_pm4_inval_zsbuf_cache(pm4);
1242
1243	util_copy_framebuffer_state(&rctx->framebuffer, state);
1244
1245	/* build states */
1246	rctx->have_depth_fb = 0;
1247	for (int i = 0; i < state->nr_cbufs; i++) {
1248		si_cb(rctx, pm4, state, i);
1249	}
1250	si_db(rctx, pm4, state);
1251
1252	shader_mask = 0;
1253	for (int i = 0; i < state->nr_cbufs; i++) {
1254		shader_mask |= 0xf << (i * 4);
1255	}
1256	tl_x = 0;
1257	tl_y = 0;
1258	br_x = state->width;
1259	br_y = state->height;
1260#if 0 /* These shouldn't be necessary on SI, see PA_SC_ENHANCE register */
1261	/* EG hw workaround */
1262	if (br_x == 0)
1263		tl_x = 1;
1264	if (br_y == 0)
1265		tl_y = 1;
1266	/* cayman hw workaround */
1267	if (rctx->chip_class == CAYMAN) {
1268		if (br_x == 1 && br_y == 1)
1269			br_x = 2;
1270	}
1271#endif
1272	tl = S_028240_TL_X(tl_x) | S_028240_TL_Y(tl_y);
1273	br = S_028244_BR_X(br_x) | S_028244_BR_Y(br_y);
1274
1275	si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, tl);
1276	si_pm4_set_reg(pm4, R_028244_PA_SC_GENERIC_SCISSOR_BR, br);
1277	si_pm4_set_reg(pm4, R_028250_PA_SC_VPORT_SCISSOR_0_TL, tl);
1278	si_pm4_set_reg(pm4, R_028254_PA_SC_VPORT_SCISSOR_0_BR, br);
1279	si_pm4_set_reg(pm4, R_028030_PA_SC_SCREEN_SCISSOR_TL, tl);
1280	si_pm4_set_reg(pm4, R_028034_PA_SC_SCREEN_SCISSOR_BR, br);
1281	si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, tl);
1282	si_pm4_set_reg(pm4, R_028208_PA_SC_WINDOW_SCISSOR_BR, br);
1283	si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000);
1284	si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
1285	si_pm4_set_reg(pm4, R_02823C_CB_SHADER_MASK, shader_mask);
1286	si_pm4_set_reg(pm4, R_028BE0_PA_SC_AA_CONFIG, 0x00000000);
1287
1288	si_pm4_set_state(rctx, framebuffer, pm4);
1289	si_update_fb_rs_state(rctx);
1290	si_update_fb_blend_state(rctx);
1291}
1292
1293void si_init_state_functions(struct r600_context *rctx)
1294{
1295	rctx->context.create_blend_state = si_create_blend_state;
1296	rctx->context.bind_blend_state = si_bind_blend_state;
1297	rctx->context.delete_blend_state = si_delete_blend_state;
1298	rctx->context.set_blend_color = si_set_blend_color;
1299
1300	rctx->context.create_rasterizer_state = si_create_rs_state;
1301	rctx->context.bind_rasterizer_state = si_bind_rs_state;
1302	rctx->context.delete_rasterizer_state = si_delete_rs_state;
1303
1304	rctx->context.create_depth_stencil_alpha_state = si_create_dsa_state;
1305	rctx->context.bind_depth_stencil_alpha_state = si_bind_dsa_state;
1306	rctx->context.delete_depth_stencil_alpha_state = si_delete_dsa_state;
1307	rctx->custom_dsa_flush = si_create_db_flush_dsa(rctx);
1308
1309	rctx->context.set_clip_state = si_set_clip_state;
1310	rctx->context.set_scissor_state = si_set_scissor_state;
1311	rctx->context.set_viewport_state = si_set_viewport_state;
1312	rctx->context.set_stencil_ref = si_set_pipe_stencil_ref;
1313
1314	rctx->context.set_framebuffer_state = si_set_framebuffer_state;
1315}
1316
1317static unsigned si_conv_pipe_prim(unsigned pprim)
1318{
1319        static const unsigned prim_conv[] = {
1320		[PIPE_PRIM_POINTS]			= V_008958_DI_PT_POINTLIST,
1321		[PIPE_PRIM_LINES]			= V_008958_DI_PT_LINELIST,
1322		[PIPE_PRIM_LINE_LOOP]			= V_008958_DI_PT_LINELOOP,
1323		[PIPE_PRIM_LINE_STRIP]			= V_008958_DI_PT_LINESTRIP,
1324		[PIPE_PRIM_TRIANGLES]			= V_008958_DI_PT_TRILIST,
1325		[PIPE_PRIM_TRIANGLE_STRIP]		= V_008958_DI_PT_TRISTRIP,
1326		[PIPE_PRIM_TRIANGLE_FAN]		= V_008958_DI_PT_TRIFAN,
1327		[PIPE_PRIM_QUADS]			= V_008958_DI_PT_QUADLIST,
1328		[PIPE_PRIM_QUAD_STRIP]			= V_008958_DI_PT_QUADSTRIP,
1329		[PIPE_PRIM_POLYGON]			= V_008958_DI_PT_POLYGON,
1330		[PIPE_PRIM_LINES_ADJACENCY]		= ~0,
1331		[PIPE_PRIM_LINE_STRIP_ADJACENCY]	= ~0,
1332		[PIPE_PRIM_TRIANGLES_ADJACENCY]		= ~0,
1333		[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]	= ~0
1334        };
1335	unsigned result = prim_conv[pprim];
1336        if (result == ~0) {
1337		R600_ERR("unsupported primitive type %d\n", pprim);
1338        }
1339	return result;
1340}
1341
1342bool si_update_draw_info_state(struct r600_context *rctx,
1343			       const struct pipe_draw_info *info)
1344{
1345	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
1346	unsigned prim = si_conv_pipe_prim(info->mode);
1347	unsigned ls_mask = 0;
1348
1349	if (pm4 == NULL)
1350		return false;
1351
1352	if (prim == ~0) {
1353		FREE(pm4);
1354		return false;
1355	}
1356
1357	si_pm4_set_reg(pm4, R_008958_VGT_PRIMITIVE_TYPE, prim);
1358	si_pm4_set_reg(pm4, R_028400_VGT_MAX_VTX_INDX, ~0);
1359	si_pm4_set_reg(pm4, R_028404_VGT_MIN_VTX_INDX, 0);
1360	si_pm4_set_reg(pm4, R_028408_VGT_INDX_OFFSET, info->index_bias);
1361	si_pm4_set_reg(pm4, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info->restart_index);
1362	si_pm4_set_reg(pm4, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info->primitive_restart);
1363#if 0
1364	si_pm4_set_reg(pm4, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0);
1365	si_pm4_set_reg(pm4, R_03CFF4_SQ_VTX_START_INST_LOC, info->start_instance);
1366#endif
1367
1368        if (prim == V_008958_DI_PT_LINELIST)
1369                ls_mask = 1;
1370        else if (prim == V_008958_DI_PT_LINESTRIP)
1371                ls_mask = 2;
1372	si_pm4_set_reg(pm4, R_028A0C_PA_SC_LINE_STIPPLE,
1373		       S_028A0C_AUTO_RESET_CNTL(ls_mask) |
1374		       rctx->pa_sc_line_stipple);
1375
1376        if (info->mode == PIPE_PRIM_QUADS || info->mode == PIPE_PRIM_QUAD_STRIP || info->mode == PIPE_PRIM_POLYGON) {
1377		si_pm4_set_reg(pm4, R_028814_PA_SU_SC_MODE_CNTL,
1378			       S_028814_PROVOKING_VTX_LAST(1) | rctx->pa_su_sc_mode_cntl);
1379        } else {
1380		si_pm4_set_reg(pm4, R_028814_PA_SU_SC_MODE_CNTL, rctx->pa_su_sc_mode_cntl);
1381        }
1382	si_pm4_set_reg(pm4, R_02881C_PA_CL_VS_OUT_CNTL,
1383		       prim == PIPE_PRIM_POINTS ? rctx->pa_cl_vs_out_cntl : 0
1384		       /*| (rctx->rasterizer->clip_plane_enable &
1385		       rctx->vs_shader->shader.clip_dist_write)*/);
1386	si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL, rctx->pa_cl_clip_cntl
1387			/*| (rctx->vs_shader->shader.clip_dist_write ||
1388			rctx->vs_shader->shader.vs_prohibit_ucps ?
1389			0 : rctx->rasterizer->clip_plane_enable & 0x3F)*/);
1390
1391	si_pm4_set_state(rctx, draw_info, pm4);
1392	return true;
1393}
1394