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