radeonsi: move infeered fb/rs state to new handling
[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 * format translation
470 */
471 static uint32_t si_translate_colorformat(enum pipe_format format)
472 {
473 switch (format) {
474 /* 8-bit buffers. */
475 case PIPE_FORMAT_A8_UNORM:
476 case PIPE_FORMAT_A8_UINT:
477 case PIPE_FORMAT_A8_SINT:
478 case PIPE_FORMAT_I8_UNORM:
479 case PIPE_FORMAT_I8_UINT:
480 case PIPE_FORMAT_I8_SINT:
481 case PIPE_FORMAT_L8_UNORM:
482 case PIPE_FORMAT_L8_UINT:
483 case PIPE_FORMAT_L8_SINT:
484 case PIPE_FORMAT_L8_SRGB:
485 case PIPE_FORMAT_R8_UNORM:
486 case PIPE_FORMAT_R8_SNORM:
487 case PIPE_FORMAT_R8_UINT:
488 case PIPE_FORMAT_R8_SINT:
489 return V_028C70_COLOR_8;
490
491 /* 16-bit buffers. */
492 case PIPE_FORMAT_B5G6R5_UNORM:
493 return V_028C70_COLOR_5_6_5;
494
495 case PIPE_FORMAT_B5G5R5A1_UNORM:
496 case PIPE_FORMAT_B5G5R5X1_UNORM:
497 return V_028C70_COLOR_1_5_5_5;
498
499 case PIPE_FORMAT_B4G4R4A4_UNORM:
500 case PIPE_FORMAT_B4G4R4X4_UNORM:
501 return V_028C70_COLOR_4_4_4_4;
502
503 case PIPE_FORMAT_L8A8_UNORM:
504 case PIPE_FORMAT_L8A8_UINT:
505 case PIPE_FORMAT_L8A8_SINT:
506 case PIPE_FORMAT_L8A8_SRGB:
507 case PIPE_FORMAT_R8G8_UNORM:
508 case PIPE_FORMAT_R8G8_UINT:
509 case PIPE_FORMAT_R8G8_SINT:
510 return V_028C70_COLOR_8_8;
511
512 case PIPE_FORMAT_Z16_UNORM:
513 case PIPE_FORMAT_R16_UNORM:
514 case PIPE_FORMAT_R16_UINT:
515 case PIPE_FORMAT_R16_SINT:
516 case PIPE_FORMAT_R16_FLOAT:
517 case PIPE_FORMAT_R16G16_FLOAT:
518 return V_028C70_COLOR_16;
519
520 /* 32-bit buffers. */
521 case PIPE_FORMAT_A8B8G8R8_SRGB:
522 case PIPE_FORMAT_A8B8G8R8_UNORM:
523 case PIPE_FORMAT_A8R8G8B8_UNORM:
524 case PIPE_FORMAT_B8G8R8A8_SRGB:
525 case PIPE_FORMAT_B8G8R8A8_UNORM:
526 case PIPE_FORMAT_B8G8R8X8_UNORM:
527 case PIPE_FORMAT_R8G8B8A8_SNORM:
528 case PIPE_FORMAT_R8G8B8A8_UNORM:
529 case PIPE_FORMAT_R8G8B8X8_UNORM:
530 case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
531 case PIPE_FORMAT_X8B8G8R8_UNORM:
532 case PIPE_FORMAT_X8R8G8B8_UNORM:
533 case PIPE_FORMAT_R8G8B8_UNORM:
534 case PIPE_FORMAT_R8G8B8A8_SSCALED:
535 case PIPE_FORMAT_R8G8B8A8_USCALED:
536 case PIPE_FORMAT_R8G8B8A8_SINT:
537 case PIPE_FORMAT_R8G8B8A8_UINT:
538 return V_028C70_COLOR_8_8_8_8;
539
540 case PIPE_FORMAT_R10G10B10A2_UNORM:
541 case PIPE_FORMAT_R10G10B10X2_SNORM:
542 case PIPE_FORMAT_B10G10R10A2_UNORM:
543 case PIPE_FORMAT_B10G10R10A2_UINT:
544 case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
545 return V_028C70_COLOR_2_10_10_10;
546
547 case PIPE_FORMAT_Z24X8_UNORM:
548 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
549 return V_028C70_COLOR_8_24;
550
551 case PIPE_FORMAT_X8Z24_UNORM:
552 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
553 return V_028C70_COLOR_24_8;
554
555 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
556 return V_028C70_COLOR_X24_8_32_FLOAT;
557
558 case PIPE_FORMAT_R32_FLOAT:
559 case PIPE_FORMAT_Z32_FLOAT:
560 return V_028C70_COLOR_32;
561
562 case PIPE_FORMAT_R16G16_SSCALED:
563 case PIPE_FORMAT_R16G16_UNORM:
564 case PIPE_FORMAT_R16G16_UINT:
565 case PIPE_FORMAT_R16G16_SINT:
566 return V_028C70_COLOR_16_16;
567
568 case PIPE_FORMAT_R11G11B10_FLOAT:
569 return V_028C70_COLOR_10_11_11;
570
571 /* 64-bit buffers. */
572 case PIPE_FORMAT_R16G16B16_USCALED:
573 case PIPE_FORMAT_R16G16B16_SSCALED:
574 case PIPE_FORMAT_R16G16B16A16_UINT:
575 case PIPE_FORMAT_R16G16B16A16_SINT:
576 case PIPE_FORMAT_R16G16B16A16_USCALED:
577 case PIPE_FORMAT_R16G16B16A16_SSCALED:
578 case PIPE_FORMAT_R16G16B16A16_UNORM:
579 case PIPE_FORMAT_R16G16B16A16_SNORM:
580 case PIPE_FORMAT_R16G16B16_FLOAT:
581 case PIPE_FORMAT_R16G16B16A16_FLOAT:
582 return V_028C70_COLOR_16_16_16_16;
583
584 case PIPE_FORMAT_R32G32_FLOAT:
585 case PIPE_FORMAT_R32G32_USCALED:
586 case PIPE_FORMAT_R32G32_SSCALED:
587 case PIPE_FORMAT_R32G32_SINT:
588 case PIPE_FORMAT_R32G32_UINT:
589 return V_028C70_COLOR_32_32;
590
591 /* 128-bit buffers. */
592 case PIPE_FORMAT_R32G32B32A32_SNORM:
593 case PIPE_FORMAT_R32G32B32A32_UNORM:
594 case PIPE_FORMAT_R32G32B32A32_SSCALED:
595 case PIPE_FORMAT_R32G32B32A32_USCALED:
596 case PIPE_FORMAT_R32G32B32A32_SINT:
597 case PIPE_FORMAT_R32G32B32A32_UINT:
598 case PIPE_FORMAT_R32G32B32A32_FLOAT:
599 return V_028C70_COLOR_32_32_32_32;
600
601 /* YUV buffers. */
602 case PIPE_FORMAT_UYVY:
603 case PIPE_FORMAT_YUYV:
604 /* 96-bit buffers. */
605 case PIPE_FORMAT_R32G32B32_FLOAT:
606 /* 8-bit buffers. */
607 case PIPE_FORMAT_L4A4_UNORM:
608 case PIPE_FORMAT_R4A4_UNORM:
609 case PIPE_FORMAT_A4R4_UNORM:
610 default:
611 return ~0U; /* Unsupported. */
612 }
613 }
614
615 static uint32_t si_translate_colorswap(enum pipe_format format)
616 {
617 switch (format) {
618 /* 8-bit buffers. */
619 case PIPE_FORMAT_L4A4_UNORM:
620 case PIPE_FORMAT_A4R4_UNORM:
621 return V_028C70_SWAP_ALT;
622
623 case PIPE_FORMAT_A8_UNORM:
624 case PIPE_FORMAT_A8_UINT:
625 case PIPE_FORMAT_A8_SINT:
626 case PIPE_FORMAT_R4A4_UNORM:
627 return V_028C70_SWAP_ALT_REV;
628 case PIPE_FORMAT_I8_UNORM:
629 case PIPE_FORMAT_L8_UNORM:
630 case PIPE_FORMAT_I8_UINT:
631 case PIPE_FORMAT_I8_SINT:
632 case PIPE_FORMAT_L8_UINT:
633 case PIPE_FORMAT_L8_SINT:
634 case PIPE_FORMAT_L8_SRGB:
635 case PIPE_FORMAT_R8_UNORM:
636 case PIPE_FORMAT_R8_SNORM:
637 case PIPE_FORMAT_R8_UINT:
638 case PIPE_FORMAT_R8_SINT:
639 return V_028C70_SWAP_STD;
640
641 /* 16-bit buffers. */
642 case PIPE_FORMAT_B5G6R5_UNORM:
643 return V_028C70_SWAP_STD_REV;
644
645 case PIPE_FORMAT_B5G5R5A1_UNORM:
646 case PIPE_FORMAT_B5G5R5X1_UNORM:
647 return V_028C70_SWAP_ALT;
648
649 case PIPE_FORMAT_B4G4R4A4_UNORM:
650 case PIPE_FORMAT_B4G4R4X4_UNORM:
651 return V_028C70_SWAP_ALT;
652
653 case PIPE_FORMAT_Z16_UNORM:
654 return V_028C70_SWAP_STD;
655
656 case PIPE_FORMAT_L8A8_UNORM:
657 case PIPE_FORMAT_L8A8_UINT:
658 case PIPE_FORMAT_L8A8_SINT:
659 case PIPE_FORMAT_L8A8_SRGB:
660 return V_028C70_SWAP_ALT;
661 case PIPE_FORMAT_R8G8_UNORM:
662 case PIPE_FORMAT_R8G8_UINT:
663 case PIPE_FORMAT_R8G8_SINT:
664 return V_028C70_SWAP_STD;
665
666 case PIPE_FORMAT_R16_UNORM:
667 case PIPE_FORMAT_R16_UINT:
668 case PIPE_FORMAT_R16_SINT:
669 case PIPE_FORMAT_R16_FLOAT:
670 return V_028C70_SWAP_STD;
671
672 /* 32-bit buffers. */
673 case PIPE_FORMAT_A8B8G8R8_SRGB:
674 return V_028C70_SWAP_STD_REV;
675 case PIPE_FORMAT_B8G8R8A8_SRGB:
676 return V_028C70_SWAP_ALT;
677
678 case PIPE_FORMAT_B8G8R8A8_UNORM:
679 case PIPE_FORMAT_B8G8R8X8_UNORM:
680 return V_028C70_SWAP_ALT;
681
682 case PIPE_FORMAT_A8R8G8B8_UNORM:
683 case PIPE_FORMAT_X8R8G8B8_UNORM:
684 return V_028C70_SWAP_ALT_REV;
685 case PIPE_FORMAT_R8G8B8A8_SNORM:
686 case PIPE_FORMAT_R8G8B8A8_UNORM:
687 case PIPE_FORMAT_R8G8B8A8_SSCALED:
688 case PIPE_FORMAT_R8G8B8A8_USCALED:
689 case PIPE_FORMAT_R8G8B8A8_SINT:
690 case PIPE_FORMAT_R8G8B8A8_UINT:
691 case PIPE_FORMAT_R8G8B8X8_UNORM:
692 return V_028C70_SWAP_STD;
693
694 case PIPE_FORMAT_A8B8G8R8_UNORM:
695 case PIPE_FORMAT_X8B8G8R8_UNORM:
696 /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */
697 return V_028C70_SWAP_STD_REV;
698
699 case PIPE_FORMAT_Z24X8_UNORM:
700 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
701 return V_028C70_SWAP_STD;
702
703 case PIPE_FORMAT_X8Z24_UNORM:
704 case PIPE_FORMAT_S8_UINT_Z24_UNORM:
705 return V_028C70_SWAP_STD;
706
707 case PIPE_FORMAT_R10G10B10A2_UNORM:
708 case PIPE_FORMAT_R10G10B10X2_SNORM:
709 case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
710 return V_028C70_SWAP_STD;
711
712 case PIPE_FORMAT_B10G10R10A2_UNORM:
713 case PIPE_FORMAT_B10G10R10A2_UINT:
714 return V_028C70_SWAP_ALT;
715
716 case PIPE_FORMAT_R11G11B10_FLOAT:
717 case PIPE_FORMAT_R32_FLOAT:
718 case PIPE_FORMAT_R32_UINT:
719 case PIPE_FORMAT_R32_SINT:
720 case PIPE_FORMAT_Z32_FLOAT:
721 case PIPE_FORMAT_R16G16_FLOAT:
722 case PIPE_FORMAT_R16G16_UNORM:
723 case PIPE_FORMAT_R16G16_UINT:
724 case PIPE_FORMAT_R16G16_SINT:
725 return V_028C70_SWAP_STD;
726
727 /* 64-bit buffers. */
728 case PIPE_FORMAT_R32G32_FLOAT:
729 case PIPE_FORMAT_R32G32_UINT:
730 case PIPE_FORMAT_R32G32_SINT:
731 case PIPE_FORMAT_R16G16B16A16_UNORM:
732 case PIPE_FORMAT_R16G16B16A16_SNORM:
733 case PIPE_FORMAT_R16G16B16A16_USCALED:
734 case PIPE_FORMAT_R16G16B16A16_SSCALED:
735 case PIPE_FORMAT_R16G16B16A16_UINT:
736 case PIPE_FORMAT_R16G16B16A16_SINT:
737 case PIPE_FORMAT_R16G16B16A16_FLOAT:
738 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
739
740 /* 128-bit buffers. */
741 case PIPE_FORMAT_R32G32B32A32_FLOAT:
742 case PIPE_FORMAT_R32G32B32A32_SNORM:
743 case PIPE_FORMAT_R32G32B32A32_UNORM:
744 case PIPE_FORMAT_R32G32B32A32_SSCALED:
745 case PIPE_FORMAT_R32G32B32A32_USCALED:
746 case PIPE_FORMAT_R32G32B32A32_SINT:
747 case PIPE_FORMAT_R32G32B32A32_UINT:
748 return V_028C70_SWAP_STD;
749 default:
750 R600_ERR("unsupported colorswap format %d\n", format);
751 return ~0U;
752 }
753 return ~0U;
754 }
755
756 static uint32_t si_colorformat_endian_swap(uint32_t colorformat)
757 {
758 if (R600_BIG_ENDIAN) {
759 switch(colorformat) {
760 /* 8-bit buffers. */
761 case V_028C70_COLOR_8:
762 return V_028C70_ENDIAN_NONE;
763
764 /* 16-bit buffers. */
765 case V_028C70_COLOR_5_6_5:
766 case V_028C70_COLOR_1_5_5_5:
767 case V_028C70_COLOR_4_4_4_4:
768 case V_028C70_COLOR_16:
769 case V_028C70_COLOR_8_8:
770 return V_028C70_ENDIAN_8IN16;
771
772 /* 32-bit buffers. */
773 case V_028C70_COLOR_8_8_8_8:
774 case V_028C70_COLOR_2_10_10_10:
775 case V_028C70_COLOR_8_24:
776 case V_028C70_COLOR_24_8:
777 case V_028C70_COLOR_16_16:
778 return V_028C70_ENDIAN_8IN32;
779
780 /* 64-bit buffers. */
781 case V_028C70_COLOR_16_16_16_16:
782 return V_028C70_ENDIAN_8IN16;
783
784 case V_028C70_COLOR_32_32:
785 return V_028C70_ENDIAN_8IN32;
786
787 /* 128-bit buffers. */
788 case V_028C70_COLOR_32_32_32_32:
789 return V_028C70_ENDIAN_8IN32;
790 default:
791 return V_028C70_ENDIAN_NONE; /* Unsupported. */
792 }
793 } else {
794 return V_028C70_ENDIAN_NONE;
795 }
796 }
797
798 static uint32_t si_translate_dbformat(enum pipe_format format)
799 {
800 switch (format) {
801 case PIPE_FORMAT_Z16_UNORM:
802 return V_028040_Z_16;
803 case PIPE_FORMAT_Z24X8_UNORM:
804 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
805 return V_028040_Z_24; /* XXX no longer supported on SI */
806 case PIPE_FORMAT_Z32_FLOAT:
807 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
808 return V_028040_Z_32_FLOAT;
809 default:
810 return ~0U;
811 }
812 }
813
814 /*
815 * framebuffer handling
816 */
817
818 static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
819 const struct pipe_framebuffer_state *state, int cb)
820 {
821 struct r600_resource_texture *rtex;
822 struct r600_surface *surf;
823 unsigned level = state->cbufs[cb]->u.tex.level;
824 unsigned pitch, slice;
825 unsigned color_info, color_attrib;
826 unsigned format, swap, ntype, endian;
827 uint64_t offset;
828 unsigned blocksize;
829 const struct util_format_description *desc;
830 int i;
831 unsigned blend_clamp = 0, blend_bypass = 0;
832
833 surf = (struct r600_surface *)state->cbufs[cb];
834 rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
835 blocksize = util_format_get_blocksize(rtex->real_format);
836
837 if (rtex->depth)
838 rctx->have_depth_fb = TRUE;
839
840 if (rtex->depth && !rtex->is_flushing_texture) {
841 r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE);
842 rtex = rtex->flushed_depth_texture;
843 }
844
845 offset = rtex->surface.level[level].offset;
846 if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
847 offset += rtex->surface.level[level].slice_size *
848 state->cbufs[cb]->u.tex.first_layer;
849 }
850 pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
851 slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
852 if (slice) {
853 slice = slice - 1;
854 }
855
856 color_attrib = S_028C74_TILE_MODE_INDEX(8);
857 switch (rtex->surface.level[level].mode) {
858 case RADEON_SURF_MODE_LINEAR_ALIGNED:
859 color_attrib = S_028C74_TILE_MODE_INDEX(8);
860 break;
861 case RADEON_SURF_MODE_1D:
862 color_attrib = S_028C74_TILE_MODE_INDEX(9);
863 break;
864 case RADEON_SURF_MODE_2D:
865 if (rtex->resource.b.b.bind & PIPE_BIND_SCANOUT) {
866 switch (blocksize) {
867 case 1:
868 color_attrib = S_028C74_TILE_MODE_INDEX(10);
869 break;
870 case 2:
871 color_attrib = S_028C74_TILE_MODE_INDEX(11);
872 break;
873 case 4:
874 color_attrib = S_028C74_TILE_MODE_INDEX(12);
875 break;
876 }
877 break;
878 } else switch (blocksize) {
879 case 1:
880 color_attrib = S_028C74_TILE_MODE_INDEX(14);
881 break;
882 case 2:
883 color_attrib = S_028C74_TILE_MODE_INDEX(15);
884 break;
885 case 4:
886 color_attrib = S_028C74_TILE_MODE_INDEX(16);
887 break;
888 case 8:
889 color_attrib = S_028C74_TILE_MODE_INDEX(17);
890 break;
891 default:
892 color_attrib = S_028C74_TILE_MODE_INDEX(13);
893 }
894 break;
895 }
896
897 desc = util_format_description(surf->base.format);
898 for (i = 0; i < 4; i++) {
899 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
900 break;
901 }
902 }
903 if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
904 ntype = V_028C70_NUMBER_FLOAT;
905 } else {
906 ntype = V_028C70_NUMBER_UNORM;
907 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
908 ntype = V_028C70_NUMBER_SRGB;
909 else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
910 if (desc->channel[i].normalized)
911 ntype = V_028C70_NUMBER_SNORM;
912 else if (desc->channel[i].pure_integer)
913 ntype = V_028C70_NUMBER_SINT;
914 } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
915 if (desc->channel[i].normalized)
916 ntype = V_028C70_NUMBER_UNORM;
917 else if (desc->channel[i].pure_integer)
918 ntype = V_028C70_NUMBER_UINT;
919 }
920 }
921
922 format = si_translate_colorformat(surf->base.format);
923 swap = si_translate_colorswap(surf->base.format);
924 if (rtex->resource.b.b.usage == PIPE_USAGE_STAGING) {
925 endian = V_028C70_ENDIAN_NONE;
926 } else {
927 endian = si_colorformat_endian_swap(format);
928 }
929
930 /* blend clamp should be set for all NORM/SRGB types */
931 if (ntype == V_028C70_NUMBER_UNORM ||
932 ntype == V_028C70_NUMBER_SNORM ||
933 ntype == V_028C70_NUMBER_SRGB)
934 blend_clamp = 1;
935
936 /* set blend bypass according to docs if SINT/UINT or
937 8/24 COLOR variants */
938 if (ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT ||
939 format == V_028C70_COLOR_8_24 || format == V_028C70_COLOR_24_8 ||
940 format == V_028C70_COLOR_X24_8_32_FLOAT) {
941 blend_clamp = 0;
942 blend_bypass = 1;
943 }
944
945 color_info = S_028C70_FORMAT(format) |
946 S_028C70_COMP_SWAP(swap) |
947 S_028C70_BLEND_CLAMP(blend_clamp) |
948 S_028C70_BLEND_BYPASS(blend_bypass) |
949 S_028C70_NUMBER_TYPE(ntype) |
950 S_028C70_ENDIAN(endian);
951
952 rctx->alpha_ref_dirty = true;
953
954 offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
955 offset >>= 8;
956
957 /* FIXME handle enabling of CB beyond BASE8 which has different offset */
958 si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
959 si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset);
960 si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, S_028C64_TILE_MAX(pitch));
961 si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice));
962
963 if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
964 si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 0x00000000);
965 } else {
966 si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C,
967 S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) |
968 S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer));
969 }
970 si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info);
971 si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib);
972 }
973
974 static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
975 const struct pipe_framebuffer_state *state)
976 {
977 struct r600_resource_texture *rtex;
978 struct r600_surface *surf;
979 unsigned level, first_layer, pitch, slice, format;
980 uint32_t db_z_info, stencil_info;
981 uint64_t offset;
982
983 if (state->zsbuf == NULL) {
984 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
985 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
986 return;
987 }
988
989 surf = (struct r600_surface *)state->zsbuf;
990 level = surf->base.u.tex.level;
991 rtex = (struct r600_resource_texture*)surf->base.texture;
992
993 first_layer = surf->base.u.tex.first_layer;
994 format = si_translate_dbformat(rtex->real_format);
995
996 offset = r600_resource_va(rctx->context.screen, surf->base.texture);
997 offset += rtex->surface.level[level].offset;
998 pitch = (rtex->surface.level[level].nblk_x / 8) - 1;
999 slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
1000 if (slice) {
1001 slice = slice - 1;
1002 }
1003 offset >>= 8;
1004
1005 si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
1006 si_pm4_set_reg(pm4, R_028048_DB_Z_READ_BASE, offset);
1007 si_pm4_set_reg(pm4, R_028050_DB_Z_WRITE_BASE, offset);
1008 si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW,
1009 S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
1010 S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer));
1011
1012 db_z_info = S_028040_FORMAT(format);
1013 stencil_info = S_028044_FORMAT(rtex->stencil != 0);
1014
1015 switch (format) {
1016 case V_028040_Z_16:
1017 db_z_info |= S_028040_TILE_MODE_INDEX(5);
1018 stencil_info |= S_028044_TILE_MODE_INDEX(5);
1019 break;
1020 case V_028040_Z_24:
1021 case V_028040_Z_32_FLOAT:
1022 db_z_info |= S_028040_TILE_MODE_INDEX(6);
1023 stencil_info |= S_028044_TILE_MODE_INDEX(6);
1024 break;
1025 default:
1026 db_z_info |= S_028040_TILE_MODE_INDEX(7);
1027 stencil_info |= S_028044_TILE_MODE_INDEX(7);
1028 }
1029
1030 if (rtex->stencil) {
1031 uint64_t stencil_offset =
1032 r600_texture_get_offset(rtex->stencil, level, first_layer);
1033
1034 stencil_offset += r600_resource_va(rctx->context.screen, (void*)rtex->stencil);
1035 stencil_offset >>= 8;
1036
1037 si_pm4_add_bo(pm4, &rtex->stencil->resource, RADEON_USAGE_READWRITE);
1038 si_pm4_set_reg(pm4, R_02804C_DB_STENCIL_READ_BASE, stencil_offset);
1039 si_pm4_set_reg(pm4, R_028054_DB_STENCIL_WRITE_BASE, stencil_offset);
1040 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, stencil_info);
1041 } else {
1042 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
1043 }
1044
1045 if (format != ~0U) {
1046 si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, 0x1);
1047 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, db_z_info);
1048 si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch));
1049 si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice));
1050
1051 } else {
1052 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
1053 }
1054 }
1055
1056 static void si_set_framebuffer_state(struct pipe_context *ctx,
1057 const struct pipe_framebuffer_state *state)
1058 {
1059 struct r600_context *rctx = (struct r600_context *)ctx;
1060 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
1061 uint32_t shader_mask, tl, br;
1062 int tl_x, tl_y, br_x, br_y;
1063
1064 if (pm4 == NULL)
1065 return;
1066
1067 si_pm4_inval_fb_cache(pm4, state->nr_cbufs);
1068
1069 if (state->zsbuf)
1070 si_pm4_inval_zsbuf_cache(pm4);
1071
1072 util_copy_framebuffer_state(&rctx->framebuffer, state);
1073
1074 /* build states */
1075 rctx->have_depth_fb = 0;
1076 for (int i = 0; i < state->nr_cbufs; i++) {
1077 si_cb(rctx, pm4, state, i);
1078 }
1079 si_db(rctx, pm4, state);
1080
1081 shader_mask = 0;
1082 for (int i = 0; i < state->nr_cbufs; i++) {
1083 shader_mask |= 0xf << (i * 4);
1084 }
1085 tl_x = 0;
1086 tl_y = 0;
1087 br_x = state->width;
1088 br_y = state->height;
1089 #if 0 /* These shouldn't be necessary on SI, see PA_SC_ENHANCE register */
1090 /* EG hw workaround */
1091 if (br_x == 0)
1092 tl_x = 1;
1093 if (br_y == 0)
1094 tl_y = 1;
1095 /* cayman hw workaround */
1096 if (rctx->chip_class == CAYMAN) {
1097 if (br_x == 1 && br_y == 1)
1098 br_x = 2;
1099 }
1100 #endif
1101 tl = S_028240_TL_X(tl_x) | S_028240_TL_Y(tl_y);
1102 br = S_028244_BR_X(br_x) | S_028244_BR_Y(br_y);
1103
1104 si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, tl);
1105 si_pm4_set_reg(pm4, R_028244_PA_SC_GENERIC_SCISSOR_BR, br);
1106 si_pm4_set_reg(pm4, R_028250_PA_SC_VPORT_SCISSOR_0_TL, tl);
1107 si_pm4_set_reg(pm4, R_028254_PA_SC_VPORT_SCISSOR_0_BR, br);
1108 si_pm4_set_reg(pm4, R_028030_PA_SC_SCREEN_SCISSOR_TL, tl);
1109 si_pm4_set_reg(pm4, R_028034_PA_SC_SCREEN_SCISSOR_BR, br);
1110 si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, tl);
1111 si_pm4_set_reg(pm4, R_028208_PA_SC_WINDOW_SCISSOR_BR, br);
1112 si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000);
1113 si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA);
1114 si_pm4_set_reg(pm4, R_02823C_CB_SHADER_MASK, shader_mask);
1115 si_pm4_set_reg(pm4, R_028BE0_PA_SC_AA_CONFIG, 0x00000000);
1116
1117 si_pm4_set_state(rctx, framebuffer, pm4);
1118 si_update_fb_rs_state(rctx);
1119 }
1120
1121 void si_init_state_functions(struct r600_context *rctx)
1122 {
1123 rctx->context.create_blend_state = si_create_blend_state;
1124 rctx->context.bind_blend_state = si_bind_blend_state;
1125 rctx->context.delete_blend_state = si_delete_blend_state;
1126 rctx->context.set_blend_color = si_set_blend_color;
1127
1128 rctx->context.create_rasterizer_state = si_create_rs_state;
1129 rctx->context.bind_rasterizer_state = si_bind_rs_state;
1130 rctx->context.delete_rasterizer_state = si_delete_rs_state;
1131
1132 rctx->context.set_clip_state = si_set_clip_state;
1133 rctx->context.set_scissor_state = si_set_scissor_state;
1134 rctx->context.set_viewport_state = si_set_viewport_state;
1135
1136 rctx->context.set_framebuffer_state = si_set_framebuffer_state;
1137 }