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