si_state.c revision 708337e62e86cfb2df893f0733bb7c5a4938fab6
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 "util/u_blitter.h" 30#include "util/u_pack_color.h" 31#include "tgsi/tgsi_parse.h" 32#include "radeonsi_pipe.h" 33#include "radeonsi_shader.h" 34#include "si_state.h" 35#include "sid.h" 36 37/* 38 * inferred framebuffer and blender state 39 */ 40static void si_update_fb_blend_state(struct r600_context *rctx) 41{ 42 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 43 struct si_state_blend *blend = rctx->queued.named.blend; 44 uint32_t mask; 45 46 if (pm4 == NULL || blend == NULL) 47 return; 48 49 mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1; 50 mask &= blend->cb_target_mask; 51 si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask); 52 53 si_pm4_set_state(rctx, fb_blend, pm4); 54} 55 56/* 57 * Blender functions 58 */ 59 60static uint32_t si_translate_blend_function(int blend_func) 61{ 62 switch (blend_func) { 63 case PIPE_BLEND_ADD: 64 return V_028780_COMB_DST_PLUS_SRC; 65 case PIPE_BLEND_SUBTRACT: 66 return V_028780_COMB_SRC_MINUS_DST; 67 case PIPE_BLEND_REVERSE_SUBTRACT: 68 return V_028780_COMB_DST_MINUS_SRC; 69 case PIPE_BLEND_MIN: 70 return V_028780_COMB_MIN_DST_SRC; 71 case PIPE_BLEND_MAX: 72 return V_028780_COMB_MAX_DST_SRC; 73 default: 74 R600_ERR("Unknown blend function %d\n", blend_func); 75 assert(0); 76 break; 77 } 78 return 0; 79} 80 81static uint32_t si_translate_blend_factor(int blend_fact) 82{ 83 switch (blend_fact) { 84 case PIPE_BLENDFACTOR_ONE: 85 return V_028780_BLEND_ONE; 86 case PIPE_BLENDFACTOR_SRC_COLOR: 87 return V_028780_BLEND_SRC_COLOR; 88 case PIPE_BLENDFACTOR_SRC_ALPHA: 89 return V_028780_BLEND_SRC_ALPHA; 90 case PIPE_BLENDFACTOR_DST_ALPHA: 91 return V_028780_BLEND_DST_ALPHA; 92 case PIPE_BLENDFACTOR_DST_COLOR: 93 return V_028780_BLEND_DST_COLOR; 94 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 95 return V_028780_BLEND_SRC_ALPHA_SATURATE; 96 case PIPE_BLENDFACTOR_CONST_COLOR: 97 return V_028780_BLEND_CONSTANT_COLOR; 98 case PIPE_BLENDFACTOR_CONST_ALPHA: 99 return V_028780_BLEND_CONSTANT_ALPHA; 100 case PIPE_BLENDFACTOR_ZERO: 101 return V_028780_BLEND_ZERO; 102 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 103 return V_028780_BLEND_ONE_MINUS_SRC_COLOR; 104 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 105 return V_028780_BLEND_ONE_MINUS_SRC_ALPHA; 106 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 107 return V_028780_BLEND_ONE_MINUS_DST_ALPHA; 108 case PIPE_BLENDFACTOR_INV_DST_COLOR: 109 return V_028780_BLEND_ONE_MINUS_DST_COLOR; 110 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 111 return V_028780_BLEND_ONE_MINUS_CONSTANT_COLOR; 112 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 113 return V_028780_BLEND_ONE_MINUS_CONSTANT_ALPHA; 114 case PIPE_BLENDFACTOR_SRC1_COLOR: 115 return V_028780_BLEND_SRC1_COLOR; 116 case PIPE_BLENDFACTOR_SRC1_ALPHA: 117 return V_028780_BLEND_SRC1_ALPHA; 118 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 119 return V_028780_BLEND_INV_SRC1_COLOR; 120 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: 121 return V_028780_BLEND_INV_SRC1_ALPHA; 122 default: 123 R600_ERR("Bad blend factor %d not supported!\n", blend_fact); 124 assert(0); 125 break; 126 } 127 return 0; 128} 129 130static void *si_create_blend_state(struct pipe_context *ctx, 131 const struct pipe_blend_state *state) 132{ 133 struct si_state_blend *blend = CALLOC_STRUCT(si_state_blend); 134 struct si_pm4_state *pm4 = &blend->pm4; 135 136 uint32_t color_control; 137 138 if (blend == NULL) 139 return NULL; 140 141 color_control = S_028808_MODE(V_028808_CB_NORMAL); 142 if (state->logicop_enable) { 143 color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4)); 144 } else { 145 color_control |= S_028808_ROP3(0xcc); 146 } 147 si_pm4_set_reg(pm4, R_028808_CB_COLOR_CONTROL, color_control); 148 149 si_pm4_set_reg(pm4, R_028C38_PA_SC_AA_MASK_X0Y0_X1Y0, ~0); 150 si_pm4_set_reg(pm4, R_028C3C_PA_SC_AA_MASK_X0Y1_X1Y1, ~0); 151 152 blend->cb_target_mask = 0; 153 for (int i = 0; i < 8; i++) { 154 /* state->rt entries > 0 only written if independent blending */ 155 const int j = state->independent_blend_enable ? i : 0; 156 157 unsigned eqRGB = state->rt[j].rgb_func; 158 unsigned srcRGB = state->rt[j].rgb_src_factor; 159 unsigned dstRGB = state->rt[j].rgb_dst_factor; 160 unsigned eqA = state->rt[j].alpha_func; 161 unsigned srcA = state->rt[j].alpha_src_factor; 162 unsigned dstA = state->rt[j].alpha_dst_factor; 163 164 unsigned blend_cntl = 0; 165 166 /* we pretend 8 buffer are used, CB_SHADER_MASK will disable unused one */ 167 blend->cb_target_mask |= state->rt[j].colormask << (4 * i); 168 169 if (!state->rt[j].blend_enable) { 170 si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl); 171 continue; 172 } 173 174 blend_cntl |= S_028780_ENABLE(1); 175 blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB)); 176 blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(srcRGB)); 177 blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(dstRGB)); 178 179 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { 180 blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1); 181 blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA)); 182 blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(srcA)); 183 blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(dstA)); 184 } 185 si_pm4_set_reg(pm4, R_028780_CB_BLEND0_CONTROL + i * 4, blend_cntl); 186 } 187 188 return blend; 189} 190 191static void si_bind_blend_state(struct pipe_context *ctx, void *state) 192{ 193 struct r600_context *rctx = (struct r600_context *)ctx; 194 si_pm4_bind_state(rctx, blend, (struct si_state_blend *)state); 195 si_update_fb_blend_state(rctx); 196} 197 198static void si_delete_blend_state(struct pipe_context *ctx, void *state) 199{ 200 struct r600_context *rctx = (struct r600_context *)ctx; 201 si_pm4_delete_state(rctx, blend, (struct si_state_blend *)state); 202} 203 204static void si_set_blend_color(struct pipe_context *ctx, 205 const struct pipe_blend_color *state) 206{ 207 struct r600_context *rctx = (struct r600_context *)ctx; 208 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 209 210 if (pm4 == NULL) 211 return; 212 213 si_pm4_set_reg(pm4, R_028414_CB_BLEND_RED, fui(state->color[0])); 214 si_pm4_set_reg(pm4, R_028418_CB_BLEND_GREEN, fui(state->color[1])); 215 si_pm4_set_reg(pm4, R_02841C_CB_BLEND_BLUE, fui(state->color[2])); 216 si_pm4_set_reg(pm4, R_028420_CB_BLEND_ALPHA, fui(state->color[3])); 217 218 si_pm4_set_state(rctx, blend_color, pm4); 219} 220 221/* 222 * Clipping, scissors and viewport 223 */ 224 225static void si_set_clip_state(struct pipe_context *ctx, 226 const struct pipe_clip_state *state) 227{ 228 struct r600_context *rctx = (struct r600_context *)ctx; 229 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 230 231 if (pm4 == NULL) 232 return; 233 234 for (int i = 0; i < 6; i++) { 235 si_pm4_set_reg(pm4, R_0285BC_PA_CL_UCP_0_X + i * 16, 236 fui(state->ucp[i][0])); 237 si_pm4_set_reg(pm4, R_0285C0_PA_CL_UCP_0_Y + i * 16, 238 fui(state->ucp[i][1])); 239 si_pm4_set_reg(pm4, R_0285C4_PA_CL_UCP_0_Z + i * 16, 240 fui(state->ucp[i][2])); 241 si_pm4_set_reg(pm4, R_0285C8_PA_CL_UCP_0_W + i * 16, 242 fui(state->ucp[i][3])); 243 } 244 245 si_pm4_set_state(rctx, clip, pm4); 246} 247 248static void si_set_scissor_state(struct pipe_context *ctx, 249 const struct pipe_scissor_state *state) 250{ 251 struct r600_context *rctx = (struct r600_context *)ctx; 252 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 253 uint32_t tl, br; 254 255 if (pm4 == NULL) 256 return; 257 258 tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny); 259 br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy); 260 si_pm4_set_reg(pm4, R_028210_PA_SC_CLIPRECT_0_TL, tl); 261 si_pm4_set_reg(pm4, R_028214_PA_SC_CLIPRECT_0_BR, br); 262 si_pm4_set_reg(pm4, R_028218_PA_SC_CLIPRECT_1_TL, tl); 263 si_pm4_set_reg(pm4, R_02821C_PA_SC_CLIPRECT_1_BR, br); 264 si_pm4_set_reg(pm4, R_028220_PA_SC_CLIPRECT_2_TL, tl); 265 si_pm4_set_reg(pm4, R_028224_PA_SC_CLIPRECT_2_BR, br); 266 si_pm4_set_reg(pm4, R_028228_PA_SC_CLIPRECT_3_TL, tl); 267 si_pm4_set_reg(pm4, R_02822C_PA_SC_CLIPRECT_3_BR, br); 268 269 si_pm4_set_state(rctx, scissor, pm4); 270} 271 272static void si_set_viewport_state(struct pipe_context *ctx, 273 const struct pipe_viewport_state *state) 274{ 275 struct r600_context *rctx = (struct r600_context *)ctx; 276 struct si_state_viewport *viewport = CALLOC_STRUCT(si_state_viewport); 277 struct si_pm4_state *pm4 = &viewport->pm4; 278 279 if (viewport == NULL) 280 return; 281 282 viewport->viewport = *state; 283 si_pm4_set_reg(pm4, R_0282D0_PA_SC_VPORT_ZMIN_0, 0x00000000); 284 si_pm4_set_reg(pm4, R_0282D4_PA_SC_VPORT_ZMAX_0, 0x3F800000); 285 si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000); 286 si_pm4_set_reg(pm4, R_02843C_PA_CL_VPORT_XSCALE_0, fui(state->scale[0])); 287 si_pm4_set_reg(pm4, R_028440_PA_CL_VPORT_XOFFSET_0, fui(state->translate[0])); 288 si_pm4_set_reg(pm4, R_028444_PA_CL_VPORT_YSCALE_0, fui(state->scale[1])); 289 si_pm4_set_reg(pm4, R_028448_PA_CL_VPORT_YOFFSET_0, fui(state->translate[1])); 290 si_pm4_set_reg(pm4, R_02844C_PA_CL_VPORT_ZSCALE_0, fui(state->scale[2])); 291 si_pm4_set_reg(pm4, R_028450_PA_CL_VPORT_ZOFFSET_0, fui(state->translate[2])); 292 si_pm4_set_reg(pm4, R_028818_PA_CL_VTE_CNTL, 0x0000043F); 293 294 si_pm4_set_state(rctx, viewport, viewport); 295} 296 297/* 298 * inferred state between framebuffer and rasterizer 299 */ 300static void si_update_fb_rs_state(struct r600_context *rctx) 301{ 302 struct si_state_rasterizer *rs = rctx->queued.named.rasterizer; 303 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 304 unsigned offset_db_fmt_cntl = 0, depth; 305 float offset_units; 306 307 if (!rs || !rctx->framebuffer.zsbuf) { 308 FREE(pm4); 309 return; 310 } 311 312 offset_units = rctx->queued.named.rasterizer->offset_units; 313 switch (rctx->framebuffer.zsbuf->texture->format) { 314 case PIPE_FORMAT_Z24X8_UNORM: 315 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 316 depth = -24; 317 offset_units *= 2.0f; 318 break; 319 case PIPE_FORMAT_Z32_FLOAT: 320 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 321 depth = -23; 322 offset_units *= 1.0f; 323 offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1); 324 break; 325 case PIPE_FORMAT_Z16_UNORM: 326 depth = -16; 327 offset_units *= 4.0f; 328 break; 329 default: 330 return; 331 } 332 333 /* FIXME some of those reg can be computed with cso */ 334 offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth); 335 si_pm4_set_reg(pm4, R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, 336 fui(rctx->queued.named.rasterizer->offset_scale)); 337 si_pm4_set_reg(pm4, R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, fui(offset_units)); 338 si_pm4_set_reg(pm4, R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, 339 fui(rctx->queued.named.rasterizer->offset_scale)); 340 si_pm4_set_reg(pm4, R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, fui(offset_units)); 341 si_pm4_set_reg(pm4, R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, offset_db_fmt_cntl); 342 343 si_pm4_set_state(rctx, fb_rs, pm4); 344} 345 346/* 347 * Rasterizer 348 */ 349 350static uint32_t si_translate_fill(uint32_t func) 351{ 352 switch(func) { 353 case PIPE_POLYGON_MODE_FILL: 354 return V_028814_X_DRAW_TRIANGLES; 355 case PIPE_POLYGON_MODE_LINE: 356 return V_028814_X_DRAW_LINES; 357 case PIPE_POLYGON_MODE_POINT: 358 return V_028814_X_DRAW_POINTS; 359 default: 360 assert(0); 361 return V_028814_X_DRAW_POINTS; 362 } 363} 364 365static void *si_create_rs_state(struct pipe_context *ctx, 366 const struct pipe_rasterizer_state *state) 367{ 368 struct si_state_rasterizer *rs = CALLOC_STRUCT(si_state_rasterizer); 369 struct si_pm4_state *pm4 = &rs->pm4; 370 unsigned tmp; 371 unsigned prov_vtx = 1, polygon_dual_mode; 372 unsigned clip_rule; 373 float psize_min, psize_max; 374 375 if (rs == NULL) { 376 return NULL; 377 } 378 379 polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL || 380 state->fill_back != PIPE_POLYGON_MODE_FILL); 381 382 if (state->flatshade_first) 383 prov_vtx = 0; 384 385 rs->flatshade = state->flatshade; 386 rs->sprite_coord_enable = state->sprite_coord_enable; 387 rs->pa_sc_line_stipple = state->line_stipple_enable ? 388 S_028A0C_LINE_PATTERN(state->line_stipple_pattern) | 389 S_028A0C_REPEAT_COUNT(state->line_stipple_factor) : 0; 390 rs->pa_su_sc_mode_cntl = 391 S_028814_PROVOKING_VTX_LAST(prov_vtx) | 392 S_028814_CULL_FRONT(state->rasterizer_discard || (state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) | 393 S_028814_CULL_BACK(state->rasterizer_discard || (state->cull_face & PIPE_FACE_BACK) ? 1 : 0) | 394 S_028814_FACE(!state->front_ccw) | 395 S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) | 396 S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) | 397 S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri) | 398 S_028814_POLY_MODE(polygon_dual_mode) | 399 S_028814_POLYMODE_FRONT_PTYPE(si_translate_fill(state->fill_front)) | 400 S_028814_POLYMODE_BACK_PTYPE(si_translate_fill(state->fill_back)); 401 rs->pa_cl_clip_cntl = 402 S_028810_PS_UCP_MODE(3) | 403 S_028810_ZCLIP_NEAR_DISABLE(!state->depth_clip) | 404 S_028810_ZCLIP_FAR_DISABLE(!state->depth_clip) | 405 S_028810_DX_LINEAR_ATTR_CLIP_ENA(1); 406 rs->pa_cl_vs_out_cntl = 407 S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) | 408 S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex); 409 410 clip_rule = state->scissor ? 0xAAAA : 0xFFFF; 411 412 /* offset */ 413 rs->offset_units = state->offset_units; 414 rs->offset_scale = state->offset_scale * 12.0f; 415 416 /* XXX: Flat shading hangs the GPU */ 417 tmp = S_0286D4_FLAT_SHADE_ENA(0); 418 if (state->sprite_coord_enable) { 419 tmp |= S_0286D4_PNT_SPRITE_ENA(1) | 420 S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) | 421 S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) | 422 S_0286D4_PNT_SPRITE_OVRD_Z(V_0286D4_SPI_PNT_SPRITE_SEL_0) | 423 S_0286D4_PNT_SPRITE_OVRD_W(V_0286D4_SPI_PNT_SPRITE_SEL_1); 424 if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) { 425 tmp |= S_0286D4_PNT_SPRITE_TOP_1(1); 426 } 427 } 428 si_pm4_set_reg(pm4, R_0286D4_SPI_INTERP_CONTROL_0, tmp); 429 430 si_pm4_set_reg(pm4, R_028820_PA_CL_NANINF_CNTL, 0x00000000); 431 /* point size 12.4 fixed point */ 432 tmp = (unsigned)(state->point_size * 8.0); 433 si_pm4_set_reg(pm4, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp)); 434 435 if (state->point_size_per_vertex) { 436 psize_min = util_get_min_point_size(state); 437 psize_max = 8192; 438 } else { 439 /* Force the point size to be as if the vertex output was disabled. */ 440 psize_min = state->point_size; 441 psize_max = state->point_size; 442 } 443 /* Divide by two, because 0.5 = 1 pixel. */ 444 si_pm4_set_reg(pm4, R_028A04_PA_SU_POINT_MINMAX, 445 S_028A04_MIN_SIZE(r600_pack_float_12p4(psize_min/2)) | 446 S_028A04_MAX_SIZE(r600_pack_float_12p4(psize_max/2))); 447 448 tmp = (unsigned)state->line_width * 8; 449 si_pm4_set_reg(pm4, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp)); 450 si_pm4_set_reg(pm4, R_028A48_PA_SC_MODE_CNTL_0, 451 S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable)); 452 453 si_pm4_set_reg(pm4, R_028BDC_PA_SC_LINE_CNTL, 0x00000400); 454 si_pm4_set_reg(pm4, R_028BE4_PA_SU_VTX_CNTL, 455 S_028BE4_PIX_CENTER(state->gl_rasterization_rules)); 456 si_pm4_set_reg(pm4, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000); 457 si_pm4_set_reg(pm4, R_028BEC_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000); 458 si_pm4_set_reg(pm4, R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000); 459 si_pm4_set_reg(pm4, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000); 460 461 si_pm4_set_reg(pm4, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, fui(state->offset_clamp)); 462 si_pm4_set_reg(pm4, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule); 463 464 return rs; 465} 466 467static void si_bind_rs_state(struct pipe_context *ctx, void *state) 468{ 469 struct r600_context *rctx = (struct r600_context *)ctx; 470 struct si_state_rasterizer *rs = (struct si_state_rasterizer *)state; 471 472 if (state == NULL) 473 return; 474 475 // TODO 476 rctx->sprite_coord_enable = rs->sprite_coord_enable; 477 rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple; 478 rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl; 479 rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl; 480 rctx->pa_cl_vs_out_cntl = rs->pa_cl_vs_out_cntl; 481 482 si_pm4_bind_state(rctx, rasterizer, rs); 483 si_update_fb_rs_state(rctx); 484} 485 486static void si_delete_rs_state(struct pipe_context *ctx, void *state) 487{ 488 struct r600_context *rctx = (struct r600_context *)ctx; 489 si_pm4_delete_state(rctx, rasterizer, (struct si_state_rasterizer *)state); 490} 491 492/* 493 * infeered state between dsa and stencil ref 494 */ 495static void si_update_dsa_stencil_ref(struct r600_context *rctx) 496{ 497 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 498 struct pipe_stencil_ref *ref = &rctx->stencil_ref; 499 struct si_state_dsa *dsa = rctx->queued.named.dsa; 500 501 if (pm4 == NULL) 502 return; 503 504 si_pm4_set_reg(pm4, R_028430_DB_STENCILREFMASK, 505 S_028430_STENCILTESTVAL(ref->ref_value[0]) | 506 S_028430_STENCILMASK(dsa->valuemask[0]) | 507 S_028430_STENCILWRITEMASK(dsa->writemask[0])); 508 si_pm4_set_reg(pm4, R_028434_DB_STENCILREFMASK_BF, 509 S_028434_STENCILTESTVAL_BF(ref->ref_value[1]) | 510 S_028434_STENCILMASK_BF(dsa->valuemask[1]) | 511 S_028434_STENCILWRITEMASK_BF(dsa->writemask[1])); 512 513 si_pm4_set_state(rctx, dsa_stencil_ref, pm4); 514} 515 516static void si_set_pipe_stencil_ref(struct pipe_context *ctx, 517 const struct pipe_stencil_ref *state) 518{ 519 struct r600_context *rctx = (struct r600_context *)ctx; 520 rctx->stencil_ref = *state; 521 si_update_dsa_stencil_ref(rctx); 522} 523 524 525/* 526 * DSA 527 */ 528 529static uint32_t si_translate_stencil_op(int s_op) 530{ 531 switch (s_op) { 532 case PIPE_STENCIL_OP_KEEP: 533 return V_02842C_STENCIL_KEEP; 534 case PIPE_STENCIL_OP_ZERO: 535 return V_02842C_STENCIL_ZERO; 536 case PIPE_STENCIL_OP_REPLACE: 537 return V_02842C_STENCIL_REPLACE_TEST; 538 case PIPE_STENCIL_OP_INCR: 539 return V_02842C_STENCIL_ADD_CLAMP; 540 case PIPE_STENCIL_OP_DECR: 541 return V_02842C_STENCIL_SUB_CLAMP; 542 case PIPE_STENCIL_OP_INCR_WRAP: 543 return V_02842C_STENCIL_ADD_WRAP; 544 case PIPE_STENCIL_OP_DECR_WRAP: 545 return V_02842C_STENCIL_SUB_WRAP; 546 case PIPE_STENCIL_OP_INVERT: 547 return V_02842C_STENCIL_INVERT; 548 default: 549 R600_ERR("Unknown stencil op %d", s_op); 550 assert(0); 551 break; 552 } 553 return 0; 554} 555 556static void *si_create_dsa_state(struct pipe_context *ctx, 557 const struct pipe_depth_stencil_alpha_state *state) 558{ 559 struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa); 560 struct si_pm4_state *pm4 = &dsa->pm4; 561 unsigned db_depth_control, /* alpha_test_control, */ alpha_ref; 562 unsigned db_render_override, db_render_control; 563 uint32_t db_stencil_control = 0; 564 565 if (dsa == NULL) { 566 return NULL; 567 } 568 569 dsa->valuemask[0] = state->stencil[0].valuemask; 570 dsa->valuemask[1] = state->stencil[1].valuemask; 571 dsa->writemask[0] = state->stencil[0].writemask; 572 dsa->writemask[1] = state->stencil[1].writemask; 573 574 db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | 575 S_028800_Z_WRITE_ENABLE(state->depth.writemask) | 576 S_028800_ZFUNC(state->depth.func); 577 578 /* stencil */ 579 if (state->stencil[0].enabled) { 580 db_depth_control |= S_028800_STENCIL_ENABLE(1); 581 db_depth_control |= S_028800_STENCILFUNC(state->stencil[0].func); 582 db_stencil_control |= S_02842C_STENCILFAIL(si_translate_stencil_op(state->stencil[0].fail_op)); 583 db_stencil_control |= S_02842C_STENCILZPASS(si_translate_stencil_op(state->stencil[0].zpass_op)); 584 db_stencil_control |= S_02842C_STENCILZFAIL(si_translate_stencil_op(state->stencil[0].zfail_op)); 585 586 if (state->stencil[1].enabled) { 587 db_depth_control |= S_028800_BACKFACE_ENABLE(1); 588 db_depth_control |= S_028800_STENCILFUNC_BF(state->stencil[1].func); 589 db_stencil_control |= S_02842C_STENCILFAIL_BF(si_translate_stencil_op(state->stencil[1].fail_op)); 590 db_stencil_control |= S_02842C_STENCILZPASS_BF(si_translate_stencil_op(state->stencil[1].zpass_op)); 591 db_stencil_control |= S_02842C_STENCILZFAIL_BF(si_translate_stencil_op(state->stencil[1].zfail_op)); 592 } 593 } 594 595 /* alpha */ 596 //alpha_test_control = 0; 597 alpha_ref = 0; 598 if (state->alpha.enabled) { 599 //alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func); 600 //alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); 601 alpha_ref = fui(state->alpha.ref_value); 602 } 603 dsa->alpha_ref = alpha_ref; 604 605 /* misc */ 606 db_render_control = 0; 607 db_render_override = S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) | 608 S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) | 609 S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE); 610 /* TODO db_render_override depends on query */ 611 si_pm4_set_reg(pm4, R_028020_DB_DEPTH_BOUNDS_MIN, 0x00000000); 612 si_pm4_set_reg(pm4, R_028024_DB_DEPTH_BOUNDS_MAX, 0x00000000); 613 si_pm4_set_reg(pm4, R_028028_DB_STENCIL_CLEAR, 0x00000000); 614 si_pm4_set_reg(pm4, R_02802C_DB_DEPTH_CLEAR, 0x3F800000); 615 //si_pm4_set_reg(pm4, R_028410_SX_ALPHA_TEST_CONTROL, alpha_test_control); 616 si_pm4_set_reg(pm4, R_028800_DB_DEPTH_CONTROL, db_depth_control); 617 si_pm4_set_reg(pm4, R_028000_DB_RENDER_CONTROL, db_render_control); 618 si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE, db_render_override); 619 si_pm4_set_reg(pm4, R_02842C_DB_STENCIL_CONTROL, db_stencil_control); 620 si_pm4_set_reg(pm4, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0); 621 si_pm4_set_reg(pm4, R_028AC4_DB_SRESULTS_COMPARE_STATE1, 0x0); 622 si_pm4_set_reg(pm4, R_028AC8_DB_PRELOAD_CONTROL, 0x0); 623 si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK, 0x0000AA00); 624 dsa->db_render_override = db_render_override; 625 626 return dsa; 627} 628 629static void si_bind_dsa_state(struct pipe_context *ctx, void *state) 630{ 631 struct r600_context *rctx = (struct r600_context *)ctx; 632 struct si_state_dsa *dsa = state; 633 634 if (state == NULL) 635 return; 636 637 si_pm4_bind_state(rctx, dsa, dsa); 638 si_update_dsa_stencil_ref(rctx); 639 640 // TODO 641 rctx->alpha_ref = dsa->alpha_ref; 642 rctx->alpha_ref_dirty = true; 643} 644 645static void si_delete_dsa_state(struct pipe_context *ctx, void *state) 646{ 647 struct r600_context *rctx = (struct r600_context *)ctx; 648 si_pm4_delete_state(rctx, dsa, (struct si_state_dsa *)state); 649} 650 651static void *si_create_db_flush_dsa(struct r600_context *rctx) 652{ 653 struct pipe_depth_stencil_alpha_state dsa; 654 struct si_state_dsa *state; 655 656 memset(&dsa, 0, sizeof(dsa)); 657 658 state = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa); 659 si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL, 660 S_028000_DEPTH_COPY(1) | 661 S_028000_STENCIL_COPY(1) | 662 S_028000_COPY_CENTROID(1)); 663 return state; 664} 665 666/* 667 * format translation 668 */ 669static uint32_t si_translate_colorformat(enum pipe_format format) 670{ 671 switch (format) { 672 /* 8-bit buffers. */ 673 case PIPE_FORMAT_A8_UNORM: 674 case PIPE_FORMAT_A8_UINT: 675 case PIPE_FORMAT_A8_SINT: 676 case PIPE_FORMAT_I8_UNORM: 677 case PIPE_FORMAT_I8_UINT: 678 case PIPE_FORMAT_I8_SINT: 679 case PIPE_FORMAT_L8_UNORM: 680 case PIPE_FORMAT_L8_UINT: 681 case PIPE_FORMAT_L8_SINT: 682 case PIPE_FORMAT_L8_SRGB: 683 case PIPE_FORMAT_R8_UNORM: 684 case PIPE_FORMAT_R8_SNORM: 685 case PIPE_FORMAT_R8_UINT: 686 case PIPE_FORMAT_R8_SINT: 687 return V_028C70_COLOR_8; 688 689 /* 16-bit buffers. */ 690 case PIPE_FORMAT_B5G6R5_UNORM: 691 return V_028C70_COLOR_5_6_5; 692 693 case PIPE_FORMAT_B5G5R5A1_UNORM: 694 case PIPE_FORMAT_B5G5R5X1_UNORM: 695 return V_028C70_COLOR_1_5_5_5; 696 697 case PIPE_FORMAT_B4G4R4A4_UNORM: 698 case PIPE_FORMAT_B4G4R4X4_UNORM: 699 return V_028C70_COLOR_4_4_4_4; 700 701 case PIPE_FORMAT_L8A8_UNORM: 702 case PIPE_FORMAT_L8A8_UINT: 703 case PIPE_FORMAT_L8A8_SINT: 704 case PIPE_FORMAT_L8A8_SRGB: 705 case PIPE_FORMAT_R8G8_UNORM: 706 case PIPE_FORMAT_R8G8_UINT: 707 case PIPE_FORMAT_R8G8_SINT: 708 return V_028C70_COLOR_8_8; 709 710 case PIPE_FORMAT_Z16_UNORM: 711 case PIPE_FORMAT_R16_UNORM: 712 case PIPE_FORMAT_R16_UINT: 713 case PIPE_FORMAT_R16_SINT: 714 case PIPE_FORMAT_R16_FLOAT: 715 case PIPE_FORMAT_R16G16_FLOAT: 716 return V_028C70_COLOR_16; 717 718 /* 32-bit buffers. */ 719 case PIPE_FORMAT_A8B8G8R8_SRGB: 720 case PIPE_FORMAT_A8B8G8R8_UNORM: 721 case PIPE_FORMAT_A8R8G8B8_UNORM: 722 case PIPE_FORMAT_B8G8R8A8_SRGB: 723 case PIPE_FORMAT_B8G8R8A8_UNORM: 724 case PIPE_FORMAT_B8G8R8X8_UNORM: 725 case PIPE_FORMAT_R8G8B8A8_SNORM: 726 case PIPE_FORMAT_R8G8B8A8_UNORM: 727 case PIPE_FORMAT_R8G8B8X8_UNORM: 728 case PIPE_FORMAT_R8SG8SB8UX8U_NORM: 729 case PIPE_FORMAT_X8B8G8R8_UNORM: 730 case PIPE_FORMAT_X8R8G8B8_UNORM: 731 case PIPE_FORMAT_R8G8B8_UNORM: 732 case PIPE_FORMAT_R8G8B8A8_SSCALED: 733 case PIPE_FORMAT_R8G8B8A8_USCALED: 734 case PIPE_FORMAT_R8G8B8A8_SINT: 735 case PIPE_FORMAT_R8G8B8A8_UINT: 736 return V_028C70_COLOR_8_8_8_8; 737 738 case PIPE_FORMAT_R10G10B10A2_UNORM: 739 case PIPE_FORMAT_R10G10B10X2_SNORM: 740 case PIPE_FORMAT_B10G10R10A2_UNORM: 741 case PIPE_FORMAT_B10G10R10A2_UINT: 742 case PIPE_FORMAT_R10SG10SB10SA2U_NORM: 743 return V_028C70_COLOR_2_10_10_10; 744 745 case PIPE_FORMAT_Z24X8_UNORM: 746 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 747 return V_028C70_COLOR_8_24; 748 749 case PIPE_FORMAT_X8Z24_UNORM: 750 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 751 return V_028C70_COLOR_24_8; 752 753 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 754 return V_028C70_COLOR_X24_8_32_FLOAT; 755 756 case PIPE_FORMAT_R32_FLOAT: 757 case PIPE_FORMAT_Z32_FLOAT: 758 return V_028C70_COLOR_32; 759 760 case PIPE_FORMAT_R16G16_SSCALED: 761 case PIPE_FORMAT_R16G16_UNORM: 762 case PIPE_FORMAT_R16G16_UINT: 763 case PIPE_FORMAT_R16G16_SINT: 764 return V_028C70_COLOR_16_16; 765 766 case PIPE_FORMAT_R11G11B10_FLOAT: 767 return V_028C70_COLOR_10_11_11; 768 769 /* 64-bit buffers. */ 770 case PIPE_FORMAT_R16G16B16_USCALED: 771 case PIPE_FORMAT_R16G16B16_SSCALED: 772 case PIPE_FORMAT_R16G16B16A16_UINT: 773 case PIPE_FORMAT_R16G16B16A16_SINT: 774 case PIPE_FORMAT_R16G16B16A16_USCALED: 775 case PIPE_FORMAT_R16G16B16A16_SSCALED: 776 case PIPE_FORMAT_R16G16B16A16_UNORM: 777 case PIPE_FORMAT_R16G16B16A16_SNORM: 778 case PIPE_FORMAT_R16G16B16_FLOAT: 779 case PIPE_FORMAT_R16G16B16A16_FLOAT: 780 return V_028C70_COLOR_16_16_16_16; 781 782 case PIPE_FORMAT_R32G32_FLOAT: 783 case PIPE_FORMAT_R32G32_USCALED: 784 case PIPE_FORMAT_R32G32_SSCALED: 785 case PIPE_FORMAT_R32G32_SINT: 786 case PIPE_FORMAT_R32G32_UINT: 787 return V_028C70_COLOR_32_32; 788 789 /* 128-bit buffers. */ 790 case PIPE_FORMAT_R32G32B32A32_SNORM: 791 case PIPE_FORMAT_R32G32B32A32_UNORM: 792 case PIPE_FORMAT_R32G32B32A32_SSCALED: 793 case PIPE_FORMAT_R32G32B32A32_USCALED: 794 case PIPE_FORMAT_R32G32B32A32_SINT: 795 case PIPE_FORMAT_R32G32B32A32_UINT: 796 case PIPE_FORMAT_R32G32B32A32_FLOAT: 797 return V_028C70_COLOR_32_32_32_32; 798 799 /* YUV buffers. */ 800 case PIPE_FORMAT_UYVY: 801 case PIPE_FORMAT_YUYV: 802 /* 96-bit buffers. */ 803 case PIPE_FORMAT_R32G32B32_FLOAT: 804 /* 8-bit buffers. */ 805 case PIPE_FORMAT_L4A4_UNORM: 806 case PIPE_FORMAT_R4A4_UNORM: 807 case PIPE_FORMAT_A4R4_UNORM: 808 default: 809 return ~0U; /* Unsupported. */ 810 } 811} 812 813static uint32_t si_translate_colorswap(enum pipe_format format) 814{ 815 switch (format) { 816 /* 8-bit buffers. */ 817 case PIPE_FORMAT_L4A4_UNORM: 818 case PIPE_FORMAT_A4R4_UNORM: 819 return V_028C70_SWAP_ALT; 820 821 case PIPE_FORMAT_A8_UNORM: 822 case PIPE_FORMAT_A8_UINT: 823 case PIPE_FORMAT_A8_SINT: 824 case PIPE_FORMAT_R4A4_UNORM: 825 return V_028C70_SWAP_ALT_REV; 826 case PIPE_FORMAT_I8_UNORM: 827 case PIPE_FORMAT_L8_UNORM: 828 case PIPE_FORMAT_I8_UINT: 829 case PIPE_FORMAT_I8_SINT: 830 case PIPE_FORMAT_L8_UINT: 831 case PIPE_FORMAT_L8_SINT: 832 case PIPE_FORMAT_L8_SRGB: 833 case PIPE_FORMAT_R8_UNORM: 834 case PIPE_FORMAT_R8_SNORM: 835 case PIPE_FORMAT_R8_UINT: 836 case PIPE_FORMAT_R8_SINT: 837 return V_028C70_SWAP_STD; 838 839 /* 16-bit buffers. */ 840 case PIPE_FORMAT_B5G6R5_UNORM: 841 return V_028C70_SWAP_STD_REV; 842 843 case PIPE_FORMAT_B5G5R5A1_UNORM: 844 case PIPE_FORMAT_B5G5R5X1_UNORM: 845 return V_028C70_SWAP_ALT; 846 847 case PIPE_FORMAT_B4G4R4A4_UNORM: 848 case PIPE_FORMAT_B4G4R4X4_UNORM: 849 return V_028C70_SWAP_ALT; 850 851 case PIPE_FORMAT_Z16_UNORM: 852 return V_028C70_SWAP_STD; 853 854 case PIPE_FORMAT_L8A8_UNORM: 855 case PIPE_FORMAT_L8A8_UINT: 856 case PIPE_FORMAT_L8A8_SINT: 857 case PIPE_FORMAT_L8A8_SRGB: 858 return V_028C70_SWAP_ALT; 859 case PIPE_FORMAT_R8G8_UNORM: 860 case PIPE_FORMAT_R8G8_UINT: 861 case PIPE_FORMAT_R8G8_SINT: 862 return V_028C70_SWAP_STD; 863 864 case PIPE_FORMAT_R16_UNORM: 865 case PIPE_FORMAT_R16_UINT: 866 case PIPE_FORMAT_R16_SINT: 867 case PIPE_FORMAT_R16_FLOAT: 868 return V_028C70_SWAP_STD; 869 870 /* 32-bit buffers. */ 871 case PIPE_FORMAT_A8B8G8R8_SRGB: 872 return V_028C70_SWAP_STD_REV; 873 case PIPE_FORMAT_B8G8R8A8_SRGB: 874 return V_028C70_SWAP_ALT; 875 876 case PIPE_FORMAT_B8G8R8A8_UNORM: 877 case PIPE_FORMAT_B8G8R8X8_UNORM: 878 return V_028C70_SWAP_ALT; 879 880 case PIPE_FORMAT_A8R8G8B8_UNORM: 881 case PIPE_FORMAT_X8R8G8B8_UNORM: 882 return V_028C70_SWAP_ALT_REV; 883 case PIPE_FORMAT_R8G8B8A8_SNORM: 884 case PIPE_FORMAT_R8G8B8A8_UNORM: 885 case PIPE_FORMAT_R8G8B8A8_SSCALED: 886 case PIPE_FORMAT_R8G8B8A8_USCALED: 887 case PIPE_FORMAT_R8G8B8A8_SINT: 888 case PIPE_FORMAT_R8G8B8A8_UINT: 889 case PIPE_FORMAT_R8G8B8X8_UNORM: 890 return V_028C70_SWAP_STD; 891 892 case PIPE_FORMAT_A8B8G8R8_UNORM: 893 case PIPE_FORMAT_X8B8G8R8_UNORM: 894 /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ 895 return V_028C70_SWAP_STD_REV; 896 897 case PIPE_FORMAT_Z24X8_UNORM: 898 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 899 return V_028C70_SWAP_STD; 900 901 case PIPE_FORMAT_X8Z24_UNORM: 902 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 903 return V_028C70_SWAP_STD; 904 905 case PIPE_FORMAT_R10G10B10A2_UNORM: 906 case PIPE_FORMAT_R10G10B10X2_SNORM: 907 case PIPE_FORMAT_R10SG10SB10SA2U_NORM: 908 return V_028C70_SWAP_STD; 909 910 case PIPE_FORMAT_B10G10R10A2_UNORM: 911 case PIPE_FORMAT_B10G10R10A2_UINT: 912 return V_028C70_SWAP_ALT; 913 914 case PIPE_FORMAT_R11G11B10_FLOAT: 915 case PIPE_FORMAT_R32_FLOAT: 916 case PIPE_FORMAT_R32_UINT: 917 case PIPE_FORMAT_R32_SINT: 918 case PIPE_FORMAT_Z32_FLOAT: 919 case PIPE_FORMAT_R16G16_FLOAT: 920 case PIPE_FORMAT_R16G16_UNORM: 921 case PIPE_FORMAT_R16G16_UINT: 922 case PIPE_FORMAT_R16G16_SINT: 923 return V_028C70_SWAP_STD; 924 925 /* 64-bit buffers. */ 926 case PIPE_FORMAT_R32G32_FLOAT: 927 case PIPE_FORMAT_R32G32_UINT: 928 case PIPE_FORMAT_R32G32_SINT: 929 case PIPE_FORMAT_R16G16B16A16_UNORM: 930 case PIPE_FORMAT_R16G16B16A16_SNORM: 931 case PIPE_FORMAT_R16G16B16A16_USCALED: 932 case PIPE_FORMAT_R16G16B16A16_SSCALED: 933 case PIPE_FORMAT_R16G16B16A16_UINT: 934 case PIPE_FORMAT_R16G16B16A16_SINT: 935 case PIPE_FORMAT_R16G16B16A16_FLOAT: 936 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 937 938 /* 128-bit buffers. */ 939 case PIPE_FORMAT_R32G32B32A32_FLOAT: 940 case PIPE_FORMAT_R32G32B32A32_SNORM: 941 case PIPE_FORMAT_R32G32B32A32_UNORM: 942 case PIPE_FORMAT_R32G32B32A32_SSCALED: 943 case PIPE_FORMAT_R32G32B32A32_USCALED: 944 case PIPE_FORMAT_R32G32B32A32_SINT: 945 case PIPE_FORMAT_R32G32B32A32_UINT: 946 return V_028C70_SWAP_STD; 947 default: 948 R600_ERR("unsupported colorswap format %d\n", format); 949 return ~0U; 950 } 951 return ~0U; 952} 953 954static uint32_t si_colorformat_endian_swap(uint32_t colorformat) 955{ 956 if (R600_BIG_ENDIAN) { 957 switch(colorformat) { 958 /* 8-bit buffers. */ 959 case V_028C70_COLOR_8: 960 return V_028C70_ENDIAN_NONE; 961 962 /* 16-bit buffers. */ 963 case V_028C70_COLOR_5_6_5: 964 case V_028C70_COLOR_1_5_5_5: 965 case V_028C70_COLOR_4_4_4_4: 966 case V_028C70_COLOR_16: 967 case V_028C70_COLOR_8_8: 968 return V_028C70_ENDIAN_8IN16; 969 970 /* 32-bit buffers. */ 971 case V_028C70_COLOR_8_8_8_8: 972 case V_028C70_COLOR_2_10_10_10: 973 case V_028C70_COLOR_8_24: 974 case V_028C70_COLOR_24_8: 975 case V_028C70_COLOR_16_16: 976 return V_028C70_ENDIAN_8IN32; 977 978 /* 64-bit buffers. */ 979 case V_028C70_COLOR_16_16_16_16: 980 return V_028C70_ENDIAN_8IN16; 981 982 case V_028C70_COLOR_32_32: 983 return V_028C70_ENDIAN_8IN32; 984 985 /* 128-bit buffers. */ 986 case V_028C70_COLOR_32_32_32_32: 987 return V_028C70_ENDIAN_8IN32; 988 default: 989 return V_028C70_ENDIAN_NONE; /* Unsupported. */ 990 } 991 } else { 992 return V_028C70_ENDIAN_NONE; 993 } 994} 995 996static uint32_t si_translate_dbformat(enum pipe_format format) 997{ 998 switch (format) { 999 case PIPE_FORMAT_Z16_UNORM: 1000 return V_028040_Z_16; 1001 case PIPE_FORMAT_Z24X8_UNORM: 1002 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1003 return V_028040_Z_24; /* XXX no longer supported on SI */ 1004 case PIPE_FORMAT_Z32_FLOAT: 1005 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 1006 return V_028040_Z_32_FLOAT; 1007 default: 1008 return ~0U; 1009 } 1010} 1011 1012/* 1013 * Texture translation 1014 */ 1015 1016static uint32_t si_translate_texformat(struct pipe_screen *screen, 1017 enum pipe_format format, 1018 const struct util_format_description *desc, 1019 int first_non_void) 1020{ 1021 boolean uniform = TRUE; 1022 int i; 1023 1024 /* Colorspace (return non-RGB formats directly). */ 1025 switch (desc->colorspace) { 1026 /* Depth stencil formats */ 1027 case UTIL_FORMAT_COLORSPACE_ZS: 1028 switch (format) { 1029 case PIPE_FORMAT_Z16_UNORM: 1030 return V_008F14_IMG_DATA_FORMAT_16; 1031 case PIPE_FORMAT_X24S8_UINT: 1032 case PIPE_FORMAT_Z24X8_UNORM: 1033 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1034 return V_008F14_IMG_DATA_FORMAT_24_8; 1035 case PIPE_FORMAT_S8X24_UINT: 1036 case PIPE_FORMAT_X8Z24_UNORM: 1037 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 1038 return V_008F14_IMG_DATA_FORMAT_8_24; 1039 case PIPE_FORMAT_S8_UINT: 1040 return V_008F14_IMG_DATA_FORMAT_8; 1041 case PIPE_FORMAT_Z32_FLOAT: 1042 return V_008F14_IMG_DATA_FORMAT_32; 1043 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 1044 return V_008F14_IMG_DATA_FORMAT_X24_8_32; 1045 default: 1046 goto out_unknown; 1047 } 1048 1049 case UTIL_FORMAT_COLORSPACE_YUV: 1050 goto out_unknown; /* TODO */ 1051 1052 case UTIL_FORMAT_COLORSPACE_SRGB: 1053 break; 1054 1055 default: 1056 break; 1057 } 1058 1059 /* TODO compressed formats */ 1060 1061 if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { 1062 return V_008F14_IMG_DATA_FORMAT_5_9_9_9; 1063 } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { 1064 return V_008F14_IMG_DATA_FORMAT_10_11_11; 1065 } 1066 1067 /* R8G8Bx_SNORM - TODO CxV8U8 */ 1068 1069 /* See whether the components are of the same size. */ 1070 for (i = 1; i < desc->nr_channels; i++) { 1071 uniform = uniform && desc->channel[0].size == desc->channel[i].size; 1072 } 1073 1074 /* Non-uniform formats. */ 1075 if (!uniform) { 1076 switch(desc->nr_channels) { 1077 case 3: 1078 if (desc->channel[0].size == 5 && 1079 desc->channel[1].size == 6 && 1080 desc->channel[2].size == 5) { 1081 return V_008F14_IMG_DATA_FORMAT_5_6_5; 1082 } 1083 goto out_unknown; 1084 case 4: 1085 if (desc->channel[0].size == 5 && 1086 desc->channel[1].size == 5 && 1087 desc->channel[2].size == 5 && 1088 desc->channel[3].size == 1) { 1089 return V_008F14_IMG_DATA_FORMAT_1_5_5_5; 1090 } 1091 if (desc->channel[0].size == 10 && 1092 desc->channel[1].size == 10 && 1093 desc->channel[2].size == 10 && 1094 desc->channel[3].size == 2) { 1095 return V_008F14_IMG_DATA_FORMAT_2_10_10_10; 1096 } 1097 goto out_unknown; 1098 } 1099 goto out_unknown; 1100 } 1101 1102 if (first_non_void < 0 || first_non_void > 3) 1103 goto out_unknown; 1104 1105 /* uniform formats */ 1106 switch (desc->channel[first_non_void].size) { 1107 case 4: 1108 switch (desc->nr_channels) { 1109 case 2: 1110 return V_008F14_IMG_DATA_FORMAT_4_4; 1111 case 4: 1112 return V_008F14_IMG_DATA_FORMAT_4_4_4_4; 1113 } 1114 break; 1115 case 8: 1116 switch (desc->nr_channels) { 1117 case 1: 1118 return V_008F14_IMG_DATA_FORMAT_8; 1119 case 2: 1120 return V_008F14_IMG_DATA_FORMAT_8_8; 1121 case 4: 1122 return V_008F14_IMG_DATA_FORMAT_8_8_8_8; 1123 } 1124 break; 1125 case 16: 1126 switch (desc->nr_channels) { 1127 case 1: 1128 return V_008F14_IMG_DATA_FORMAT_16; 1129 case 2: 1130 return V_008F14_IMG_DATA_FORMAT_16_16; 1131 case 4: 1132 return V_008F14_IMG_DATA_FORMAT_16_16_16_16; 1133 } 1134 break; 1135 case 32: 1136 switch (desc->nr_channels) { 1137 case 1: 1138 return V_008F14_IMG_DATA_FORMAT_32; 1139 case 2: 1140 return V_008F14_IMG_DATA_FORMAT_32_32; 1141 case 3: 1142 return V_008F14_IMG_DATA_FORMAT_32_32_32; 1143 case 4: 1144 return V_008F14_IMG_DATA_FORMAT_32_32_32_32; 1145 } 1146 } 1147 1148out_unknown: 1149 /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ 1150 return ~0; 1151} 1152 1153static unsigned si_tex_wrap(unsigned wrap) 1154{ 1155 switch (wrap) { 1156 default: 1157 case PIPE_TEX_WRAP_REPEAT: 1158 return V_008F30_SQ_TEX_WRAP; 1159 case PIPE_TEX_WRAP_CLAMP: 1160 return V_008F30_SQ_TEX_CLAMP_HALF_BORDER; 1161 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 1162 return V_008F30_SQ_TEX_CLAMP_LAST_TEXEL; 1163 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 1164 return V_008F30_SQ_TEX_CLAMP_BORDER; 1165 case PIPE_TEX_WRAP_MIRROR_REPEAT: 1166 return V_008F30_SQ_TEX_MIRROR; 1167 case PIPE_TEX_WRAP_MIRROR_CLAMP: 1168 return V_008F30_SQ_TEX_MIRROR_ONCE_HALF_BORDER; 1169 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 1170 return V_008F30_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; 1171 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 1172 return V_008F30_SQ_TEX_MIRROR_ONCE_BORDER; 1173 } 1174} 1175 1176static unsigned si_tex_filter(unsigned filter) 1177{ 1178 switch (filter) { 1179 default: 1180 case PIPE_TEX_FILTER_NEAREST: 1181 return V_008F38_SQ_TEX_XY_FILTER_POINT; 1182 case PIPE_TEX_FILTER_LINEAR: 1183 return V_008F38_SQ_TEX_XY_FILTER_BILINEAR; 1184 } 1185} 1186 1187static unsigned si_tex_mipfilter(unsigned filter) 1188{ 1189 switch (filter) { 1190 case PIPE_TEX_MIPFILTER_NEAREST: 1191 return V_008F38_SQ_TEX_Z_FILTER_POINT; 1192 case PIPE_TEX_MIPFILTER_LINEAR: 1193 return V_008F38_SQ_TEX_Z_FILTER_LINEAR; 1194 default: 1195 case PIPE_TEX_MIPFILTER_NONE: 1196 return V_008F38_SQ_TEX_Z_FILTER_NONE; 1197 } 1198} 1199 1200static unsigned si_tex_compare(unsigned compare) 1201{ 1202 switch (compare) { 1203 default: 1204 case PIPE_FUNC_NEVER: 1205 return V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER; 1206 case PIPE_FUNC_LESS: 1207 return V_008F30_SQ_TEX_DEPTH_COMPARE_LESS; 1208 case PIPE_FUNC_EQUAL: 1209 return V_008F30_SQ_TEX_DEPTH_COMPARE_EQUAL; 1210 case PIPE_FUNC_LEQUAL: 1211 return V_008F30_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; 1212 case PIPE_FUNC_GREATER: 1213 return V_008F30_SQ_TEX_DEPTH_COMPARE_GREATER; 1214 case PIPE_FUNC_NOTEQUAL: 1215 return V_008F30_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; 1216 case PIPE_FUNC_GEQUAL: 1217 return V_008F30_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; 1218 case PIPE_FUNC_ALWAYS: 1219 return V_008F30_SQ_TEX_DEPTH_COMPARE_ALWAYS; 1220 } 1221} 1222 1223static unsigned si_tex_dim(unsigned dim) 1224{ 1225 switch (dim) { 1226 default: 1227 case PIPE_TEXTURE_1D: 1228 return V_008F1C_SQ_RSRC_IMG_1D; 1229 case PIPE_TEXTURE_1D_ARRAY: 1230 return V_008F1C_SQ_RSRC_IMG_1D_ARRAY; 1231 case PIPE_TEXTURE_2D: 1232 case PIPE_TEXTURE_RECT: 1233 return V_008F1C_SQ_RSRC_IMG_2D; 1234 case PIPE_TEXTURE_2D_ARRAY: 1235 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY; 1236 case PIPE_TEXTURE_3D: 1237 return V_008F1C_SQ_RSRC_IMG_3D; 1238 case PIPE_TEXTURE_CUBE: 1239 return V_008F1C_SQ_RSRC_IMG_CUBE; 1240 } 1241} 1242 1243/* 1244 * Format support testing 1245 */ 1246 1247static bool si_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) 1248{ 1249 return si_translate_texformat(screen, format, util_format_description(format), 1250 util_format_get_first_non_void_channel(format)) != ~0U; 1251} 1252 1253static uint32_t si_translate_vertexformat(struct pipe_screen *screen, 1254 enum pipe_format format, 1255 const struct util_format_description *desc, 1256 int first_non_void) 1257{ 1258 uint32_t result; 1259 1260 if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FIXED) 1261 return ~0; 1262 1263 result = si_translate_texformat(screen, format, desc, first_non_void); 1264 if (result == V_008F0C_BUF_DATA_FORMAT_INVALID || 1265 result > V_008F0C_BUF_DATA_FORMAT_32_32_32_32) 1266 result = ~0; 1267 1268 return result; 1269} 1270 1271static bool si_is_vertex_format_supported(struct pipe_screen *screen, enum pipe_format format) 1272{ 1273 return si_translate_vertexformat(screen, format, util_format_description(format), 1274 util_format_get_first_non_void_channel(format)) != ~0U; 1275} 1276 1277static bool si_is_colorbuffer_format_supported(enum pipe_format format) 1278{ 1279 return si_translate_colorformat(format) != ~0U && 1280 si_translate_colorswap(format) != ~0U; 1281} 1282 1283static bool si_is_zs_format_supported(enum pipe_format format) 1284{ 1285 return si_translate_dbformat(format) != ~0U; 1286} 1287 1288bool si_is_format_supported(struct pipe_screen *screen, 1289 enum pipe_format format, 1290 enum pipe_texture_target target, 1291 unsigned sample_count, 1292 unsigned usage) 1293{ 1294 unsigned retval = 0; 1295 1296 if (target >= PIPE_MAX_TEXTURE_TYPES) { 1297 R600_ERR("r600: unsupported texture type %d\n", target); 1298 return FALSE; 1299 } 1300 1301 if (!util_format_is_supported(format, usage)) 1302 return FALSE; 1303 1304 /* Multisample */ 1305 if (sample_count > 1) 1306 return FALSE; 1307 1308 if ((usage & PIPE_BIND_SAMPLER_VIEW) && 1309 si_is_sampler_format_supported(screen, format)) { 1310 retval |= PIPE_BIND_SAMPLER_VIEW; 1311 } 1312 1313 if ((usage & (PIPE_BIND_RENDER_TARGET | 1314 PIPE_BIND_DISPLAY_TARGET | 1315 PIPE_BIND_SCANOUT | 1316 PIPE_BIND_SHARED)) && 1317 si_is_colorbuffer_format_supported(format)) { 1318 retval |= usage & 1319 (PIPE_BIND_RENDER_TARGET | 1320 PIPE_BIND_DISPLAY_TARGET | 1321 PIPE_BIND_SCANOUT | 1322 PIPE_BIND_SHARED); 1323 } 1324 1325 if ((usage & PIPE_BIND_DEPTH_STENCIL) && 1326 si_is_zs_format_supported(format)) { 1327 retval |= PIPE_BIND_DEPTH_STENCIL; 1328 } 1329 1330 if ((usage & PIPE_BIND_VERTEX_BUFFER) && 1331 si_is_vertex_format_supported(screen, format)) { 1332 retval |= PIPE_BIND_VERTEX_BUFFER; 1333 } 1334 1335 if (usage & PIPE_BIND_TRANSFER_READ) 1336 retval |= PIPE_BIND_TRANSFER_READ; 1337 if (usage & PIPE_BIND_TRANSFER_WRITE) 1338 retval |= PIPE_BIND_TRANSFER_WRITE; 1339 1340 return retval == usage; 1341} 1342 1343/* 1344 * framebuffer handling 1345 */ 1346 1347static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4, 1348 const struct pipe_framebuffer_state *state, int cb) 1349{ 1350 struct r600_resource_texture *rtex; 1351 struct r600_surface *surf; 1352 unsigned level = state->cbufs[cb]->u.tex.level; 1353 unsigned pitch, slice; 1354 unsigned color_info, color_attrib; 1355 unsigned format, swap, ntype, endian; 1356 uint64_t offset; 1357 unsigned blocksize; 1358 const struct util_format_description *desc; 1359 int i; 1360 unsigned blend_clamp = 0, blend_bypass = 0; 1361 1362 surf = (struct r600_surface *)state->cbufs[cb]; 1363 rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; 1364 blocksize = util_format_get_blocksize(rtex->real_format); 1365 1366 if (rtex->depth) 1367 rctx->have_depth_fb = TRUE; 1368 1369 if (rtex->depth && !rtex->is_flushing_texture) { 1370 r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE); 1371 rtex = rtex->flushed_depth_texture; 1372 } 1373 1374 offset = rtex->surface.level[level].offset; 1375 if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) { 1376 offset += rtex->surface.level[level].slice_size * 1377 state->cbufs[cb]->u.tex.first_layer; 1378 } 1379 pitch = (rtex->surface.level[level].nblk_x) / 8 - 1; 1380 slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64; 1381 if (slice) { 1382 slice = slice - 1; 1383 } 1384 1385 color_attrib = S_028C74_TILE_MODE_INDEX(8); 1386 switch (rtex->surface.level[level].mode) { 1387 case RADEON_SURF_MODE_LINEAR_ALIGNED: 1388 color_attrib = S_028C74_TILE_MODE_INDEX(8); 1389 break; 1390 case RADEON_SURF_MODE_1D: 1391 color_attrib = S_028C74_TILE_MODE_INDEX(9); 1392 break; 1393 case RADEON_SURF_MODE_2D: 1394 if (rtex->resource.b.b.bind & PIPE_BIND_SCANOUT) { 1395 switch (blocksize) { 1396 case 1: 1397 color_attrib = S_028C74_TILE_MODE_INDEX(10); 1398 break; 1399 case 2: 1400 color_attrib = S_028C74_TILE_MODE_INDEX(11); 1401 break; 1402 case 4: 1403 color_attrib = S_028C74_TILE_MODE_INDEX(12); 1404 break; 1405 } 1406 break; 1407 } else switch (blocksize) { 1408 case 1: 1409 color_attrib = S_028C74_TILE_MODE_INDEX(14); 1410 break; 1411 case 2: 1412 color_attrib = S_028C74_TILE_MODE_INDEX(15); 1413 break; 1414 case 4: 1415 color_attrib = S_028C74_TILE_MODE_INDEX(16); 1416 break; 1417 case 8: 1418 color_attrib = S_028C74_TILE_MODE_INDEX(17); 1419 break; 1420 default: 1421 color_attrib = S_028C74_TILE_MODE_INDEX(13); 1422 } 1423 break; 1424 } 1425 1426 desc = util_format_description(surf->base.format); 1427 for (i = 0; i < 4; i++) { 1428 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 1429 break; 1430 } 1431 } 1432 if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) { 1433 ntype = V_028C70_NUMBER_FLOAT; 1434 } else { 1435 ntype = V_028C70_NUMBER_UNORM; 1436 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) 1437 ntype = V_028C70_NUMBER_SRGB; 1438 else if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { 1439 if (desc->channel[i].normalized) 1440 ntype = V_028C70_NUMBER_SNORM; 1441 else if (desc->channel[i].pure_integer) 1442 ntype = V_028C70_NUMBER_SINT; 1443 } else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) { 1444 if (desc->channel[i].normalized) 1445 ntype = V_028C70_NUMBER_UNORM; 1446 else if (desc->channel[i].pure_integer) 1447 ntype = V_028C70_NUMBER_UINT; 1448 } 1449 } 1450 1451 format = si_translate_colorformat(surf->base.format); 1452 swap = si_translate_colorswap(surf->base.format); 1453 if (rtex->resource.b.b.usage == PIPE_USAGE_STAGING) { 1454 endian = V_028C70_ENDIAN_NONE; 1455 } else { 1456 endian = si_colorformat_endian_swap(format); 1457 } 1458 1459 /* blend clamp should be set for all NORM/SRGB types */ 1460 if (ntype == V_028C70_NUMBER_UNORM || 1461 ntype == V_028C70_NUMBER_SNORM || 1462 ntype == V_028C70_NUMBER_SRGB) 1463 blend_clamp = 1; 1464 1465 /* set blend bypass according to docs if SINT/UINT or 1466 8/24 COLOR variants */ 1467 if (ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT || 1468 format == V_028C70_COLOR_8_24 || format == V_028C70_COLOR_24_8 || 1469 format == V_028C70_COLOR_X24_8_32_FLOAT) { 1470 blend_clamp = 0; 1471 blend_bypass = 1; 1472 } 1473 1474 color_info = S_028C70_FORMAT(format) | 1475 S_028C70_COMP_SWAP(swap) | 1476 S_028C70_BLEND_CLAMP(blend_clamp) | 1477 S_028C70_BLEND_BYPASS(blend_bypass) | 1478 S_028C70_NUMBER_TYPE(ntype) | 1479 S_028C70_ENDIAN(endian); 1480 1481 rctx->alpha_ref_dirty = true; 1482 1483 offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture); 1484 offset >>= 8; 1485 1486 /* FIXME handle enabling of CB beyond BASE8 which has different offset */ 1487 si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE); 1488 si_pm4_set_reg(pm4, R_028C60_CB_COLOR0_BASE + cb * 0x3C, offset); 1489 si_pm4_set_reg(pm4, R_028C64_CB_COLOR0_PITCH + cb * 0x3C, S_028C64_TILE_MAX(pitch)); 1490 si_pm4_set_reg(pm4, R_028C68_CB_COLOR0_SLICE + cb * 0x3C, S_028C68_TILE_MAX(slice)); 1491 1492 if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) { 1493 si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 0x00000000); 1494 } else { 1495 si_pm4_set_reg(pm4, R_028C6C_CB_COLOR0_VIEW + cb * 0x3C, 1496 S_028C6C_SLICE_START(state->cbufs[cb]->u.tex.first_layer) | 1497 S_028C6C_SLICE_MAX(state->cbufs[cb]->u.tex.last_layer)); 1498 } 1499 si_pm4_set_reg(pm4, R_028C70_CB_COLOR0_INFO + cb * 0x3C, color_info); 1500 si_pm4_set_reg(pm4, R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C, color_attrib); 1501} 1502 1503static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4, 1504 const struct pipe_framebuffer_state *state) 1505{ 1506 struct r600_resource_texture *rtex; 1507 struct r600_surface *surf; 1508 unsigned level, pitch, slice, format; 1509 uint32_t z_info, s_info; 1510 uint64_t z_offs, s_offs; 1511 1512 if (state->zsbuf == NULL) { 1513 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0); 1514 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0); 1515 return; 1516 } 1517 1518 surf = (struct r600_surface *)state->zsbuf; 1519 level = surf->base.u.tex.level; 1520 rtex = (struct r600_resource_texture*)surf->base.texture; 1521 1522 format = si_translate_dbformat(rtex->real_format); 1523 1524 z_offs = r600_resource_va(rctx->context.screen, surf->base.texture); 1525 z_offs += rtex->surface.level[level].offset; 1526 1527 s_offs = r600_resource_va(rctx->context.screen, surf->base.texture); 1528 s_offs += rtex->surface.stencil_offset; 1529 z_offs += rtex->surface.level[level].offset / 4; 1530 1531 z_offs >>= 8; 1532 s_offs >>= 8; 1533 1534 pitch = (rtex->surface.level[level].nblk_x / 8) - 1; 1535 slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64; 1536 if (slice) { 1537 slice = slice - 1; 1538 } 1539 1540 z_info = S_028040_FORMAT(format); 1541 s_info = S_028044_FORMAT(1); 1542 1543 if (rtex->surface.level[level].mode == RADEON_SURF_MODE_1D) { 1544 z_info |= S_028040_TILE_MODE_INDEX(4); 1545 s_info |= S_028044_TILE_MODE_INDEX(4); 1546 1547 } else if (rtex->surface.level[level].mode == RADEON_SURF_MODE_2D) { 1548 switch (format) { 1549 case V_028040_Z_16: 1550 z_info |= S_028040_TILE_MODE_INDEX(5); 1551 s_info |= S_028044_TILE_MODE_INDEX(5); 1552 break; 1553 case V_028040_Z_24: 1554 case V_028040_Z_32_FLOAT: 1555 z_info |= S_028040_TILE_MODE_INDEX(6); 1556 s_info |= S_028044_TILE_MODE_INDEX(6); 1557 break; 1558 default: 1559 z_info |= S_028040_TILE_MODE_INDEX(7); 1560 s_info |= S_028044_TILE_MODE_INDEX(7); 1561 } 1562 1563 } else { 1564 R600_ERR("Invalid DB tiling mode %d!\n", 1565 rtex->surface.level[level].mode); 1566 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0); 1567 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0); 1568 return; 1569 } 1570 1571 si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW, 1572 S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) | 1573 S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer)); 1574 1575 si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, 0x1); 1576 if (format != ~0U) { 1577 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, z_info); 1578 1579 } else { 1580 si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0); 1581 } 1582 1583 if (rtex->surface.flags & RADEON_SURF_SBUFFER) { 1584 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, s_info); 1585 } else { 1586 si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0); 1587 } 1588 1589 si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE); 1590 si_pm4_set_reg(pm4, R_028048_DB_Z_READ_BASE, z_offs); 1591 si_pm4_set_reg(pm4, R_02804C_DB_STENCIL_READ_BASE, s_offs); 1592 si_pm4_set_reg(pm4, R_028050_DB_Z_WRITE_BASE, z_offs); 1593 si_pm4_set_reg(pm4, R_028054_DB_STENCIL_WRITE_BASE, s_offs); 1594 1595 si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch)); 1596 si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice)); 1597} 1598 1599static void si_set_framebuffer_state(struct pipe_context *ctx, 1600 const struct pipe_framebuffer_state *state) 1601{ 1602 struct r600_context *rctx = (struct r600_context *)ctx; 1603 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 1604 uint32_t shader_mask, tl, br; 1605 int tl_x, tl_y, br_x, br_y; 1606 1607 if (pm4 == NULL) 1608 return; 1609 1610 si_pm4_inval_fb_cache(pm4, state->nr_cbufs); 1611 1612 if (state->zsbuf) 1613 si_pm4_inval_zsbuf_cache(pm4); 1614 1615 util_copy_framebuffer_state(&rctx->framebuffer, state); 1616 1617 /* build states */ 1618 rctx->have_depth_fb = 0; 1619 for (int i = 0; i < state->nr_cbufs; i++) { 1620 si_cb(rctx, pm4, state, i); 1621 } 1622 si_db(rctx, pm4, state); 1623 1624 shader_mask = 0; 1625 for (int i = 0; i < state->nr_cbufs; i++) { 1626 shader_mask |= 0xf << (i * 4); 1627 } 1628 tl_x = 0; 1629 tl_y = 0; 1630 br_x = state->width; 1631 br_y = state->height; 1632#if 0 /* These shouldn't be necessary on SI, see PA_SC_ENHANCE register */ 1633 /* EG hw workaround */ 1634 if (br_x == 0) 1635 tl_x = 1; 1636 if (br_y == 0) 1637 tl_y = 1; 1638 /* cayman hw workaround */ 1639 if (rctx->chip_class == CAYMAN) { 1640 if (br_x == 1 && br_y == 1) 1641 br_x = 2; 1642 } 1643#endif 1644 tl = S_028240_TL_X(tl_x) | S_028240_TL_Y(tl_y); 1645 br = S_028244_BR_X(br_x) | S_028244_BR_Y(br_y); 1646 1647 si_pm4_set_reg(pm4, R_028240_PA_SC_GENERIC_SCISSOR_TL, tl); 1648 si_pm4_set_reg(pm4, R_028244_PA_SC_GENERIC_SCISSOR_BR, br); 1649 si_pm4_set_reg(pm4, R_028250_PA_SC_VPORT_SCISSOR_0_TL, tl); 1650 si_pm4_set_reg(pm4, R_028254_PA_SC_VPORT_SCISSOR_0_BR, br); 1651 si_pm4_set_reg(pm4, R_028030_PA_SC_SCREEN_SCISSOR_TL, tl); 1652 si_pm4_set_reg(pm4, R_028034_PA_SC_SCREEN_SCISSOR_BR, br); 1653 si_pm4_set_reg(pm4, R_028204_PA_SC_WINDOW_SCISSOR_TL, tl); 1654 si_pm4_set_reg(pm4, R_028208_PA_SC_WINDOW_SCISSOR_BR, br); 1655 si_pm4_set_reg(pm4, R_028200_PA_SC_WINDOW_OFFSET, 0x00000000); 1656 si_pm4_set_reg(pm4, R_028230_PA_SC_EDGERULE, 0xAAAAAAAA); 1657 si_pm4_set_reg(pm4, R_02823C_CB_SHADER_MASK, shader_mask); 1658 si_pm4_set_reg(pm4, R_028BE0_PA_SC_AA_CONFIG, 0x00000000); 1659 1660 si_pm4_set_state(rctx, framebuffer, pm4); 1661 si_update_fb_rs_state(rctx); 1662 si_update_fb_blend_state(rctx); 1663} 1664 1665/* 1666 * shaders 1667 */ 1668 1669static void *si_create_shader_state(struct pipe_context *ctx, 1670 const struct pipe_shader_state *state) 1671{ 1672 struct si_pipe_shader *shader = CALLOC_STRUCT(si_pipe_shader); 1673 1674 shader->tokens = tgsi_dup_tokens(state->tokens); 1675 shader->so = state->stream_output; 1676 1677 return shader; 1678} 1679 1680static void si_bind_vs_shader(struct pipe_context *ctx, void *state) 1681{ 1682 struct r600_context *rctx = (struct r600_context *)ctx; 1683 struct si_pipe_shader *shader = state; 1684 1685 if (rctx->vs_shader == state) 1686 return; 1687 1688 rctx->shader_dirty = true; 1689 rctx->vs_shader = shader; 1690 1691 if (shader) { 1692 si_pm4_bind_state(rctx, vs, shader->pm4); 1693 } 1694} 1695 1696static void si_bind_ps_shader(struct pipe_context *ctx, void *state) 1697{ 1698 struct r600_context *rctx = (struct r600_context *)ctx; 1699 struct si_pipe_shader *shader = state; 1700 1701 if (rctx->ps_shader == state) 1702 return; 1703 1704 rctx->shader_dirty = true; 1705 rctx->ps_shader = shader; 1706 1707 if (shader) { 1708 si_pm4_bind_state(rctx, ps, shader->pm4); 1709 } 1710} 1711 1712static void si_delete_vs_shader(struct pipe_context *ctx, void *state) 1713{ 1714 struct r600_context *rctx = (struct r600_context *)ctx; 1715 struct si_pipe_shader *shader = (struct si_pipe_shader *)state; 1716 1717 if (rctx->vs_shader == shader) { 1718 rctx->vs_shader = NULL; 1719 } 1720 1721 si_pm4_delete_state(rctx, vs, shader->pm4); 1722 free(shader->tokens); 1723 si_pipe_shader_destroy(ctx, shader); 1724 free(shader); 1725} 1726 1727static void si_delete_ps_shader(struct pipe_context *ctx, void *state) 1728{ 1729 struct r600_context *rctx = (struct r600_context *)ctx; 1730 struct si_pipe_shader *shader = (struct si_pipe_shader *)state; 1731 1732 if (rctx->ps_shader == shader) { 1733 rctx->ps_shader = NULL; 1734 } 1735 1736 si_pm4_delete_state(rctx, ps, shader->pm4); 1737 free(shader->tokens); 1738 si_pipe_shader_destroy(ctx, shader); 1739 free(shader); 1740} 1741 1742/* 1743 * Samplers 1744 */ 1745 1746static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx, 1747 struct pipe_resource *texture, 1748 const struct pipe_sampler_view *state) 1749{ 1750 struct si_pipe_sampler_view *view = CALLOC_STRUCT(si_pipe_sampler_view); 1751 struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture; 1752 const struct util_format_description *desc = util_format_description(state->format); 1753 unsigned blocksize = util_format_get_blocksize(tmp->real_format); 1754 unsigned format, num_format, /*endian,*/ tiling_index; 1755 uint32_t pitch = 0; 1756 unsigned char state_swizzle[4], swizzle[4]; 1757 unsigned height, depth, width; 1758 int first_non_void; 1759 uint64_t va; 1760 1761 if (view == NULL) 1762 return NULL; 1763 1764 /* initialize base object */ 1765 view->base = *state; 1766 view->base.texture = NULL; 1767 pipe_reference(NULL, &texture->reference); 1768 view->base.texture = texture; 1769 view->base.reference.count = 1; 1770 view->base.context = ctx; 1771 1772 state_swizzle[0] = state->swizzle_r; 1773 state_swizzle[1] = state->swizzle_g; 1774 state_swizzle[2] = state->swizzle_b; 1775 state_swizzle[3] = state->swizzle_a; 1776 util_format_compose_swizzles(desc->swizzle, state_swizzle, swizzle); 1777 1778 first_non_void = util_format_get_first_non_void_channel(state->format); 1779 switch (desc->channel[first_non_void].type) { 1780 case UTIL_FORMAT_TYPE_FLOAT: 1781 num_format = V_008F14_IMG_NUM_FORMAT_FLOAT; 1782 break; 1783 case UTIL_FORMAT_TYPE_SIGNED: 1784 num_format = V_008F14_IMG_NUM_FORMAT_SNORM; 1785 break; 1786 case UTIL_FORMAT_TYPE_UNSIGNED: 1787 default: 1788 num_format = V_008F14_IMG_NUM_FORMAT_UNORM; 1789 } 1790 1791 format = si_translate_texformat(ctx->screen, state->format, desc, first_non_void); 1792 if (format == ~0) { 1793 format = 0; 1794 } 1795 1796 if (tmp->depth && !tmp->is_flushing_texture) { 1797 r600_texture_depth_flush(ctx, texture, TRUE); 1798 tmp = tmp->flushed_depth_texture; 1799 } 1800 1801 /* not supported any more */ 1802 //endian = si_colorformat_endian_swap(format); 1803 1804 height = texture->height0; 1805 depth = texture->depth0; 1806 width = texture->width0; 1807 pitch = align(tmp->pitch_in_blocks[0] * 1808 util_format_get_blockwidth(state->format), 8); 1809 1810 if (texture->target == PIPE_TEXTURE_1D_ARRAY) { 1811 height = 1; 1812 depth = texture->array_size; 1813 } else if (texture->target == PIPE_TEXTURE_2D_ARRAY) { 1814 depth = texture->array_size; 1815 } 1816 1817 tiling_index = 8; 1818 switch (tmp->surface.level[state->u.tex.first_level].mode) { 1819 case RADEON_SURF_MODE_LINEAR_ALIGNED: 1820 tiling_index = 8; 1821 break; 1822 case RADEON_SURF_MODE_1D: 1823 tiling_index = 9; 1824 break; 1825 case RADEON_SURF_MODE_2D: 1826 if (tmp->resource.b.b.bind & PIPE_BIND_SCANOUT) { 1827 switch (blocksize) { 1828 case 1: 1829 tiling_index = 10; 1830 break; 1831 case 2: 1832 tiling_index = 11; 1833 break; 1834 case 4: 1835 tiling_index = 12; 1836 break; 1837 } 1838 break; 1839 } else switch (blocksize) { 1840 case 1: 1841 tiling_index = 14; 1842 break; 1843 case 2: 1844 tiling_index = 15; 1845 break; 1846 case 4: 1847 tiling_index = 16; 1848 break; 1849 case 8: 1850 tiling_index = 17; 1851 break; 1852 default: 1853 tiling_index = 13; 1854 } 1855 break; 1856 } 1857 1858 va = r600_resource_va(ctx->screen, texture); 1859 if (state->u.tex.last_level) { 1860 view->state[0] = (va + tmp->offset[1]) >> 8; 1861 } else { 1862 view->state[0] = (va + tmp->offset[0]) >> 8; 1863 } 1864 view->state[1] = (S_008F14_BASE_ADDRESS_HI((va + tmp->offset[0]) >> 40) | 1865 S_008F14_DATA_FORMAT(format) | 1866 S_008F14_NUM_FORMAT(num_format)); 1867 view->state[2] = (S_008F18_WIDTH(width - 1) | 1868 S_008F18_HEIGHT(height - 1)); 1869 view->state[3] = (S_008F1C_DST_SEL_X(si_map_swizzle(swizzle[0])) | 1870 S_008F1C_DST_SEL_Y(si_map_swizzle(swizzle[1])) | 1871 S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) | 1872 S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) | 1873 S_008F1C_BASE_LEVEL(state->u.tex.first_level) | 1874 S_008F1C_LAST_LEVEL(state->u.tex.last_level) | 1875 S_008F1C_TILING_INDEX(tiling_index) | 1876 S_008F1C_TYPE(si_tex_dim(texture->target))); 1877 view->state[4] = (S_008F20_DEPTH(depth - 1) | S_008F20_PITCH(pitch - 1)); 1878 view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) | 1879 S_008F24_LAST_ARRAY(state->u.tex.last_layer)); 1880 view->state[6] = 0; 1881 view->state[7] = 0; 1882 1883 return &view->base; 1884} 1885 1886static void si_sampler_view_destroy(struct pipe_context *ctx, 1887 struct pipe_sampler_view *state) 1888{ 1889 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 1890 1891 pipe_resource_reference(&state->texture, NULL); 1892 FREE(resource); 1893} 1894 1895static void *si_create_sampler_state(struct pipe_context *ctx, 1896 const struct pipe_sampler_state *state) 1897{ 1898 struct si_pipe_sampler_state *rstate = CALLOC_STRUCT(si_pipe_sampler_state); 1899 union util_color uc; 1900 unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 2 : 0; 1901 unsigned border_color_type; 1902 1903 if (rstate == NULL) { 1904 return NULL; 1905 } 1906 1907 util_pack_color(state->border_color.f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); 1908 switch (uc.ui) { 1909 case 0x000000FF: 1910 border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK; 1911 break; 1912 case 0x00000000: 1913 border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK; 1914 break; 1915 case 0xFFFFFFFF: 1916 border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE; 1917 break; 1918 default: /* Use border color pointer */ 1919 border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER; 1920 } 1921 1922 rstate->val[0] = (S_008F30_CLAMP_X(si_tex_wrap(state->wrap_s)) | 1923 S_008F30_CLAMP_Y(si_tex_wrap(state->wrap_t)) | 1924 S_008F30_CLAMP_Z(si_tex_wrap(state->wrap_r)) | 1925 (state->max_anisotropy & 0x7) << 9 | /* XXX */ 1926 S_008F30_DEPTH_COMPARE_FUNC(si_tex_compare(state->compare_func)) | 1927 S_008F30_FORCE_UNNORMALIZED(!state->normalized_coords) | 1928 aniso_flag_offset << 16 | /* XXX */ 1929 S_008F30_DISABLE_CUBE_WRAP(!state->seamless_cube_map)); 1930 rstate->val[1] = (S_008F34_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | 1931 S_008F34_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8))); 1932 rstate->val[2] = (S_008F38_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | 1933 S_008F38_XY_MAG_FILTER(si_tex_filter(state->mag_img_filter)) | 1934 S_008F38_XY_MIN_FILTER(si_tex_filter(state->min_img_filter)) | 1935 S_008F38_MIP_FILTER(si_tex_mipfilter(state->min_mip_filter))); 1936 rstate->val[3] = S_008F3C_BORDER_COLOR_TYPE(border_color_type); 1937 1938#if 0 1939 if (border_color_type == 3) { 1940 si_pm4_set_reg(pm4, R_00A404_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color.f[0])); 1941 si_pm4_set_reg(pm4, R_00A408_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color.f[1])); 1942 si_pm4_set_reg(pm4, R_00A40C_TD_PS_SAMPLER0_BORDER_BLUE, fui(state->border_color.f[2])); 1943 si_pm4_set_reg(pm4, R_00A410_TD_PS_SAMPLER0_BORDER_ALPHA, fui(state->border_color.f[3])); 1944 } 1945#endif 1946 return rstate; 1947} 1948 1949static void si_set_vs_sampler_view(struct pipe_context *ctx, unsigned count, 1950 struct pipe_sampler_view **views) 1951{ 1952 assert(count == 0); 1953} 1954 1955static void si_set_ps_sampler_view(struct pipe_context *ctx, unsigned count, 1956 struct pipe_sampler_view **views) 1957{ 1958 struct r600_context *rctx = (struct r600_context *)ctx; 1959 struct si_pipe_sampler_view **resource = (struct si_pipe_sampler_view **)views; 1960 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 1961 struct si_resource *bo; 1962 int i; 1963 int has_depth = 0; 1964 uint64_t va; 1965 char *ptr; 1966 1967 if (!count) 1968 goto out; 1969 1970 si_pm4_inval_texture_cache(pm4); 1971 1972 bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE, 1973 count * sizeof(resource[0]->state)); 1974 ptr = rctx->ws->buffer_map(bo->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 1975 1976 for (i = 0; i < count; i++, ptr += sizeof(resource[0]->state)) { 1977 struct r600_resource_texture *tex = (void *)resource[i]->base.texture; 1978 1979 pipe_sampler_view_reference( 1980 (struct pipe_sampler_view **)&rctx->ps_samplers.views[i], 1981 views[i]); 1982 1983 si_pm4_add_bo(pm4, &tex->resource, RADEON_USAGE_READ); 1984 1985 if (resource[i]) { 1986 if (tex->depth) 1987 has_depth = 1; 1988 1989 memcpy(ptr, resource[i]->state, sizeof(resource[0]->state)); 1990 } else 1991 memset(ptr, 0, sizeof(resource[0]->state)); 1992 } 1993 1994 rctx->ws->buffer_unmap(bo->cs_buf); 1995 1996 for (i = count; i < NUM_TEX_UNITS; i++) { 1997 if (rctx->ps_samplers.views[i]) 1998 pipe_sampler_view_reference((struct pipe_sampler_view **)&rctx->ps_samplers.views[i], NULL); 1999 } 2000 2001 va = r600_resource_va(ctx->screen, (void *)bo); 2002 si_pm4_add_bo(pm4, bo, RADEON_USAGE_READ); 2003 si_pm4_set_reg(pm4, R_00B040_SPI_SHADER_USER_DATA_PS_4, va); 2004 si_pm4_set_reg(pm4, R_00B044_SPI_SHADER_USER_DATA_PS_5, va >> 32); 2005 2006out: 2007 si_pm4_set_state(rctx, ps_sampler_views, pm4); 2008 rctx->have_depth_texture = has_depth; 2009 rctx->ps_samplers.n_views = count; 2010} 2011 2012static void si_bind_vs_sampler(struct pipe_context *ctx, unsigned count, void **states) 2013{ 2014 assert(count == 0); 2015} 2016 2017static void si_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states) 2018{ 2019 struct r600_context *rctx = (struct r600_context *)ctx; 2020 struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state **)states; 2021 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 2022 struct si_resource *bo; 2023 uint64_t va; 2024 char *ptr; 2025 int i; 2026 2027 if (!count) 2028 goto out; 2029 2030 si_pm4_inval_texture_cache(pm4); 2031 2032 bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE, 2033 count * sizeof(rstates[0]->val)); 2034 ptr = rctx->ws->buffer_map(bo->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 2035 2036 for (i = 0; i < count; i++, ptr += sizeof(rstates[0]->val)) { 2037 memcpy(ptr, rstates[i]->val, sizeof(rstates[0]->val)); 2038 } 2039 2040 rctx->ws->buffer_unmap(bo->cs_buf); 2041 2042 memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count); 2043 2044 va = r600_resource_va(ctx->screen, (void *)bo); 2045 si_pm4_add_bo(pm4, bo, RADEON_USAGE_READ); 2046 si_pm4_set_reg(pm4, R_00B038_SPI_SHADER_USER_DATA_PS_2, va); 2047 si_pm4_set_reg(pm4, R_00B03C_SPI_SHADER_USER_DATA_PS_3, va >> 32); 2048 2049out: 2050 si_pm4_set_state(rctx, ps_sampler, pm4); 2051 rctx->ps_samplers.n_samplers = count; 2052} 2053 2054static void si_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 2055{ 2056} 2057 2058static void si_delete_sampler_state(struct pipe_context *ctx, void *state) 2059{ 2060 free(state); 2061} 2062 2063/* 2064 * Constants 2065 */ 2066static void si_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 2067 struct pipe_constant_buffer *cb) 2068{ 2069 struct r600_context *rctx = (struct r600_context *)ctx; 2070 struct si_resource *rbuffer = cb ? si_resource(cb->buffer) : NULL; 2071 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 2072 uint64_t va_offset; 2073 uint32_t offset; 2074 2075 /* Note that the state tracker can unbind constant buffers by 2076 * passing NULL here. 2077 */ 2078 if (cb == NULL) { 2079 FREE(pm4); 2080 return; 2081 } 2082 2083 si_pm4_inval_shader_cache(pm4); 2084 2085 if (cb->user_buffer) 2086 r600_upload_const_buffer(rctx, &rbuffer, cb->user_buffer, cb->buffer_size, &offset); 2087 else 2088 offset = 0; 2089 va_offset = r600_resource_va(ctx->screen, (void*)rbuffer); 2090 va_offset += offset; 2091 2092 si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ); 2093 2094 switch (shader) { 2095 case PIPE_SHADER_VERTEX: 2096 si_pm4_set_reg(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0, va_offset); 2097 si_pm4_set_reg(pm4, R_00B134_SPI_SHADER_USER_DATA_VS_1, va_offset >> 32); 2098 si_pm4_set_state(rctx, vs_const, pm4); 2099 break; 2100 2101 case PIPE_SHADER_FRAGMENT: 2102 si_pm4_set_reg(pm4, R_00B030_SPI_SHADER_USER_DATA_PS_0, va_offset); 2103 si_pm4_set_reg(pm4, R_00B034_SPI_SHADER_USER_DATA_PS_1, va_offset >> 32); 2104 si_pm4_set_state(rctx, ps_const, pm4); 2105 break; 2106 2107 default: 2108 R600_ERR("unsupported %d\n", shader); 2109 return; 2110 } 2111 2112 if (cb->buffer != &rbuffer->b.b) 2113 si_resource_reference(&rbuffer, NULL); 2114} 2115 2116/* 2117 * Vertex elements & buffers 2118 */ 2119 2120static void *si_create_vertex_elements(struct pipe_context *ctx, 2121 unsigned count, 2122 const struct pipe_vertex_element *elements) 2123{ 2124 struct si_vertex_element *v = CALLOC_STRUCT(si_vertex_element); 2125 int i; 2126 2127 assert(count < PIPE_MAX_ATTRIBS); 2128 if (!v) 2129 return NULL; 2130 2131 v->count = count; 2132 for (i = 0; i < count; ++i) { 2133 const struct util_format_description *desc; 2134 unsigned data_format, num_format; 2135 int first_non_void; 2136 2137 desc = util_format_description(elements[i].src_format); 2138 first_non_void = util_format_get_first_non_void_channel(elements[i].src_format); 2139 data_format = si_translate_vertexformat(ctx->screen, elements[i].src_format, 2140 desc, first_non_void); 2141 2142 switch (desc->channel[first_non_void].type) { 2143 case UTIL_FORMAT_TYPE_FIXED: 2144 num_format = V_008F0C_BUF_NUM_FORMAT_USCALED; /* XXX */ 2145 break; 2146 case UTIL_FORMAT_TYPE_SIGNED: 2147 num_format = V_008F0C_BUF_NUM_FORMAT_SNORM; 2148 break; 2149 case UTIL_FORMAT_TYPE_UNSIGNED: 2150 num_format = V_008F0C_BUF_NUM_FORMAT_UNORM; 2151 break; 2152 case UTIL_FORMAT_TYPE_FLOAT: 2153 default: 2154 num_format = V_008F14_IMG_NUM_FORMAT_FLOAT; 2155 } 2156 2157 v->rsrc_word3[i] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) | 2158 S_008F0C_DST_SEL_Y(si_map_swizzle(desc->swizzle[1])) | 2159 S_008F0C_DST_SEL_Z(si_map_swizzle(desc->swizzle[2])) | 2160 S_008F0C_DST_SEL_W(si_map_swizzle(desc->swizzle[3])) | 2161 S_008F0C_NUM_FORMAT(num_format) | 2162 S_008F0C_DATA_FORMAT(data_format); 2163 } 2164 memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count); 2165 2166 return v; 2167} 2168 2169static void si_bind_vertex_elements(struct pipe_context *ctx, void *state) 2170{ 2171 struct r600_context *rctx = (struct r600_context *)ctx; 2172 struct si_vertex_element *v = (struct si_vertex_element*)state; 2173 2174 rctx->vertex_elements = v; 2175} 2176 2177static void si_delete_vertex_element(struct pipe_context *ctx, void *state) 2178{ 2179 struct r600_context *rctx = (struct r600_context *)ctx; 2180 2181 if (rctx->vertex_elements == state) 2182 rctx->vertex_elements = NULL; 2183 FREE(state); 2184} 2185 2186static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 2187 const struct pipe_vertex_buffer *buffers) 2188{ 2189 struct r600_context *rctx = (struct r600_context *)ctx; 2190 2191 util_copy_vertex_buffers(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, count); 2192} 2193 2194static void si_set_index_buffer(struct pipe_context *ctx, 2195 const struct pipe_index_buffer *ib) 2196{ 2197 struct r600_context *rctx = (struct r600_context *)ctx; 2198 2199 if (ib) { 2200 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 2201 memcpy(&rctx->index_buffer, ib, sizeof(*ib)); 2202 } else { 2203 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 2204 } 2205} 2206 2207/* 2208 * Stream out 2209 */ 2210 2211static struct pipe_stream_output_target * 2212si_create_so_target(struct pipe_context *ctx, 2213 struct pipe_resource *buffer, 2214 unsigned buffer_offset, 2215 unsigned buffer_size) 2216{ 2217 struct r600_context *rctx = (struct r600_context *)ctx; 2218 struct r600_so_target *t; 2219 void *ptr; 2220 2221 t = CALLOC_STRUCT(r600_so_target); 2222 if (!t) { 2223 return NULL; 2224 } 2225 2226 t->b.reference.count = 1; 2227 t->b.context = ctx; 2228 pipe_resource_reference(&t->b.buffer, buffer); 2229 t->b.buffer_offset = buffer_offset; 2230 t->b.buffer_size = buffer_size; 2231 2232 t->filled_size = si_resource_create_custom(ctx->screen, PIPE_USAGE_STATIC, 4); 2233 ptr = rctx->ws->buffer_map(t->filled_size->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 2234 memset(ptr, 0, t->filled_size->buf->size); 2235 rctx->ws->buffer_unmap(t->filled_size->cs_buf); 2236 2237 return &t->b; 2238} 2239 2240static void si_so_target_destroy(struct pipe_context *ctx, 2241 struct pipe_stream_output_target *target) 2242{ 2243 struct r600_so_target *t = (struct r600_so_target*)target; 2244 pipe_resource_reference(&t->b.buffer, NULL); 2245 si_resource_reference(&t->filled_size, NULL); 2246 FREE(t); 2247} 2248 2249static void si_set_so_targets(struct pipe_context *ctx, 2250 unsigned num_targets, 2251 struct pipe_stream_output_target **targets, 2252 unsigned append_bitmask) 2253{ 2254 struct r600_context *rctx = (struct r600_context *)ctx; 2255 unsigned i; 2256 2257 /* Stop streamout. */ 2258 if (rctx->num_so_targets) { 2259 r600_context_streamout_end(rctx); 2260 } 2261 2262 /* Set the new targets. */ 2263 for (i = 0; i < num_targets; i++) { 2264 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); 2265 } 2266 for (; i < rctx->num_so_targets; i++) { 2267 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); 2268 } 2269 2270 rctx->num_so_targets = num_targets; 2271 rctx->streamout_start = num_targets != 0; 2272 rctx->streamout_append_bitmask = append_bitmask; 2273} 2274 2275/* 2276 * Misc 2277 */ 2278static void si_set_polygon_stipple(struct pipe_context *ctx, 2279 const struct pipe_poly_stipple *state) 2280{ 2281} 2282 2283static void si_texture_barrier(struct pipe_context *ctx) 2284{ 2285 struct r600_context *rctx = (struct r600_context *)ctx; 2286 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 2287 2288 si_pm4_inval_texture_cache(pm4); 2289 si_pm4_inval_fb_cache(pm4, rctx->framebuffer.nr_cbufs); 2290 si_pm4_set_state(rctx, texture_barrier, pm4); 2291} 2292 2293void si_init_state_functions(struct r600_context *rctx) 2294{ 2295 rctx->context.create_blend_state = si_create_blend_state; 2296 rctx->context.bind_blend_state = si_bind_blend_state; 2297 rctx->context.delete_blend_state = si_delete_blend_state; 2298 rctx->context.set_blend_color = si_set_blend_color; 2299 2300 rctx->context.create_rasterizer_state = si_create_rs_state; 2301 rctx->context.bind_rasterizer_state = si_bind_rs_state; 2302 rctx->context.delete_rasterizer_state = si_delete_rs_state; 2303 2304 rctx->context.create_depth_stencil_alpha_state = si_create_dsa_state; 2305 rctx->context.bind_depth_stencil_alpha_state = si_bind_dsa_state; 2306 rctx->context.delete_depth_stencil_alpha_state = si_delete_dsa_state; 2307 rctx->custom_dsa_flush = si_create_db_flush_dsa(rctx); 2308 2309 rctx->context.set_clip_state = si_set_clip_state; 2310 rctx->context.set_scissor_state = si_set_scissor_state; 2311 rctx->context.set_viewport_state = si_set_viewport_state; 2312 rctx->context.set_stencil_ref = si_set_pipe_stencil_ref; 2313 2314 rctx->context.set_framebuffer_state = si_set_framebuffer_state; 2315 2316 rctx->context.create_vs_state = si_create_shader_state; 2317 rctx->context.create_fs_state = si_create_shader_state; 2318 rctx->context.bind_vs_state = si_bind_vs_shader; 2319 rctx->context.bind_fs_state = si_bind_ps_shader; 2320 rctx->context.delete_vs_state = si_delete_vs_shader; 2321 rctx->context.delete_fs_state = si_delete_ps_shader; 2322 2323 rctx->context.create_sampler_state = si_create_sampler_state; 2324 rctx->context.bind_vertex_sampler_states = si_bind_vs_sampler; 2325 rctx->context.bind_fragment_sampler_states = si_bind_ps_sampler; 2326 rctx->context.delete_sampler_state = si_delete_sampler_state; 2327 2328 rctx->context.create_sampler_view = si_create_sampler_view; 2329 rctx->context.set_vertex_sampler_views = si_set_vs_sampler_view; 2330 rctx->context.set_fragment_sampler_views = si_set_ps_sampler_view; 2331 rctx->context.sampler_view_destroy = si_sampler_view_destroy; 2332 2333 rctx->context.set_sample_mask = si_set_sample_mask; 2334 2335 rctx->context.set_constant_buffer = si_set_constant_buffer; 2336 2337 rctx->context.create_vertex_elements_state = si_create_vertex_elements; 2338 rctx->context.bind_vertex_elements_state = si_bind_vertex_elements; 2339 rctx->context.delete_vertex_elements_state = si_delete_vertex_element; 2340 rctx->context.set_vertex_buffers = si_set_vertex_buffers; 2341 rctx->context.set_index_buffer = si_set_index_buffer; 2342 2343 rctx->context.create_stream_output_target = si_create_so_target; 2344 rctx->context.stream_output_target_destroy = si_so_target_destroy; 2345 rctx->context.set_stream_output_targets = si_set_so_targets; 2346 2347 rctx->context.texture_barrier = si_texture_barrier; 2348 rctx->context.set_polygon_stipple = si_set_polygon_stipple; 2349 2350 rctx->context.draw_vbo = si_draw_vbo; 2351} 2352 2353void si_init_config(struct r600_context *rctx) 2354{ 2355 struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state); 2356 2357 si_pm4_cmd_begin(pm4, PKT3_CONTEXT_CONTROL); 2358 si_pm4_cmd_add(pm4, 0x80000000); 2359 si_pm4_cmd_add(pm4, 0x80000000); 2360 si_pm4_cmd_end(pm4, false); 2361 2362 si_pm4_set_reg(pm4, R_028A4C_PA_SC_MODE_CNTL_1, 0x0); 2363 2364 si_pm4_set_reg(pm4, R_028A10_VGT_OUTPUT_PATH_CNTL, 0x0); 2365 si_pm4_set_reg(pm4, R_028A14_VGT_HOS_CNTL, 0x0); 2366 si_pm4_set_reg(pm4, R_028A18_VGT_HOS_MAX_TESS_LEVEL, 0x0); 2367 si_pm4_set_reg(pm4, R_028A1C_VGT_HOS_MIN_TESS_LEVEL, 0x0); 2368 si_pm4_set_reg(pm4, R_028A20_VGT_HOS_REUSE_DEPTH, 0x0); 2369 si_pm4_set_reg(pm4, R_028A24_VGT_GROUP_PRIM_TYPE, 0x0); 2370 si_pm4_set_reg(pm4, R_028A28_VGT_GROUP_FIRST_DECR, 0x0); 2371 si_pm4_set_reg(pm4, R_028A2C_VGT_GROUP_DECR, 0x0); 2372 si_pm4_set_reg(pm4, R_028A30_VGT_GROUP_VECT_0_CNTL, 0x0); 2373 si_pm4_set_reg(pm4, R_028A34_VGT_GROUP_VECT_1_CNTL, 0x0); 2374 si_pm4_set_reg(pm4, R_028A38_VGT_GROUP_VECT_0_FMT_CNTL, 0x0); 2375 si_pm4_set_reg(pm4, R_028A3C_VGT_GROUP_VECT_1_FMT_CNTL, 0x0); 2376 si_pm4_set_reg(pm4, R_028A40_VGT_GS_MODE, 0x0); 2377 si_pm4_set_reg(pm4, R_028A84_VGT_PRIMITIVEID_EN, 0x0); 2378 si_pm4_set_reg(pm4, R_028A8C_VGT_PRIMITIVEID_RESET, 0x0); 2379 si_pm4_set_reg(pm4, R_028B94_VGT_STRMOUT_CONFIG, 0x0); 2380 si_pm4_set_reg(pm4, R_028B98_VGT_STRMOUT_BUFFER_CONFIG, 0x0); 2381 si_pm4_set_reg(pm4, R_028AA8_IA_MULTI_VGT_PARAM, 2382 S_028AA8_SWITCH_ON_EOP(1) | 2383 S_028AA8_PARTIAL_VS_WAVE_ON(1) | 2384 S_028AA8_PRIMGROUP_SIZE(63)); 2385 si_pm4_set_reg(pm4, R_028AB4_VGT_REUSE_OFF, 0x00000000); 2386 si_pm4_set_reg(pm4, R_028AB8_VGT_VTX_CNT_EN, 0x0); 2387 si_pm4_set_reg(pm4, R_008A14_PA_CL_ENHANCE, (3 << 1) | 1); 2388 2389 si_pm4_set_reg(pm4, R_028B54_VGT_SHADER_STAGES_EN, 0); 2390 si_pm4_set_reg(pm4, R_028BD4_PA_SC_CENTROID_PRIORITY_0, 0x76543210); 2391 si_pm4_set_reg(pm4, R_028BD8_PA_SC_CENTROID_PRIORITY_1, 0xfedcba98); 2392 2393 si_pm4_set_reg(pm4, R_028804_DB_EQAA, 0x110000); 2394 2395 si_pm4_set_state(rctx, init, pm4); 2396} 2397