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