1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2 3 /* 4 * Copyright (C) 2012-2013 Rob Clark <robclark (at) freedesktop.org> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Authors: 26 * Rob Clark <robclark (at) freedesktop.org> 27 */ 28 29 #include "pipe/p_state.h" 30 #include "util/u_string.h" 31 #include "util/u_memory.h" 32 #include "util/u_helpers.h" 33 34 #include "freedreno_resource.h" 35 36 #include "fd2_emit.h" 37 #include "fd2_blend.h" 38 #include "fd2_context.h" 39 #include "fd2_program.h" 40 #include "fd2_rasterizer.h" 41 #include "fd2_texture.h" 42 #include "fd2_util.h" 43 #include "fd2_zsa.h" 44 45 /* NOTE: just define the position for const regs statically.. the blob 46 * driver doesn't seem to change these dynamically, and I can't really 47 * think of a good reason to so.. 48 */ 49 #define VS_CONST_BASE 0x20 50 #define PS_CONST_BASE 0x120 51 52 static void 53 emit_constants(struct fd_ringbuffer *ring, uint32_t base, 54 struct fd_constbuf_stateobj *constbuf, 55 struct fd2_shader_stateobj *shader) 56 { 57 uint32_t enabled_mask = constbuf->enabled_mask; 58 uint32_t start_base = base; 59 unsigned i; 60 61 // XXX TODO only emit dirty consts.. but we need to keep track if 62 // they are clobbered by a clear, gmem2mem, or mem2gmem.. 63 constbuf->dirty_mask = enabled_mask; 64 65 /* emit user constants: */ 66 while (enabled_mask) { 67 unsigned index = ffs(enabled_mask) - 1; 68 struct pipe_constant_buffer *cb = &constbuf->cb[index]; 69 unsigned size = align(cb->buffer_size, 4) / 4; /* size in dwords */ 70 71 // I expect that size should be a multiple of vec4's: 72 assert(size == align(size, 4)); 73 74 /* hmm, sometimes we still seem to end up with consts bound, 75 * even if shader isn't using them, which ends up overwriting 76 * const reg's used for immediates.. this is a hack to work 77 * around that: 78 */ 79 if (shader && ((base - start_base) >= (shader->first_immediate * 4))) 80 break; 81 82 if (constbuf->dirty_mask & (1 << index)) { 83 const uint32_t *dwords; 84 85 if (cb->user_buffer) { 86 dwords = cb->user_buffer; 87 } else { 88 struct fd_resource *rsc = fd_resource(cb->buffer); 89 dwords = fd_bo_map(rsc->bo); 90 } 91 92 dwords = (uint32_t *)(((uint8_t *)dwords) + cb->buffer_offset); 93 94 OUT_PKT3(ring, CP_SET_CONSTANT, size + 1); 95 OUT_RING(ring, base); 96 for (i = 0; i < size; i++) 97 OUT_RING(ring, *(dwords++)); 98 99 constbuf->dirty_mask &= ~(1 << index); 100 } 101 102 base += size; 103 enabled_mask &= ~(1 << index); 104 } 105 106 /* emit shader immediates: */ 107 if (shader) { 108 for (i = 0; i < shader->num_immediates; i++) { 109 OUT_PKT3(ring, CP_SET_CONSTANT, 5); 110 OUT_RING(ring, start_base + (4 * (shader->first_immediate + i))); 111 OUT_RING(ring, shader->immediates[i].val[0]); 112 OUT_RING(ring, shader->immediates[i].val[1]); 113 OUT_RING(ring, shader->immediates[i].val[2]); 114 OUT_RING(ring, shader->immediates[i].val[3]); 115 base += 4; 116 } 117 } 118 } 119 120 typedef uint32_t texmask; 121 122 static texmask 123 emit_texture(struct fd_ringbuffer *ring, struct fd_context *ctx, 124 struct fd_texture_stateobj *tex, unsigned samp_id, texmask emitted) 125 { 126 unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id); 127 static const struct fd2_sampler_stateobj dummy_sampler = {}; 128 const struct fd2_sampler_stateobj *sampler; 129 struct fd2_pipe_sampler_view *view; 130 131 if (emitted & (1 << const_idx)) 132 return 0; 133 134 sampler = tex->samplers[samp_id] ? 135 fd2_sampler_stateobj(tex->samplers[samp_id]) : 136 &dummy_sampler; 137 view = fd2_pipe_sampler_view(tex->textures[samp_id]); 138 139 OUT_PKT3(ring, CP_SET_CONSTANT, 7); 140 OUT_RING(ring, 0x00010000 + (0x6 * const_idx)); 141 142 OUT_RING(ring, sampler->tex0 | view->tex0); 143 OUT_RELOC(ring, fd_resource(view->base.texture)->bo, 0, view->fmt, 0); 144 OUT_RING(ring, view->tex2); 145 OUT_RING(ring, sampler->tex3 | view->tex3); 146 OUT_RING(ring, sampler->tex4); 147 OUT_RING(ring, sampler->tex5); 148 149 return (1 << const_idx); 150 } 151 152 static void 153 emit_textures(struct fd_ringbuffer *ring, struct fd_context *ctx) 154 { 155 texmask emitted = 0; 156 unsigned i; 157 158 for (i = 0; i < ctx->verttex.num_samplers; i++) 159 if (ctx->verttex.samplers[i]) 160 emitted |= emit_texture(ring, ctx, &ctx->verttex, i, emitted); 161 162 for (i = 0; i < ctx->fragtex.num_samplers; i++) 163 if (ctx->fragtex.samplers[i]) 164 emitted |= emit_texture(ring, ctx, &ctx->fragtex, i, emitted); 165 } 166 167 void 168 fd2_emit_vertex_bufs(struct fd_ringbuffer *ring, uint32_t val, 169 struct fd2_vertex_buf *vbufs, uint32_t n) 170 { 171 unsigned i; 172 173 OUT_PKT3(ring, CP_SET_CONSTANT, 1 + (2 * n)); 174 OUT_RING(ring, (0x1 << 16) | (val & 0xffff)); 175 for (i = 0; i < n; i++) { 176 struct fd_resource *rsc = fd_resource(vbufs[i].prsc); 177 OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 3, 0); 178 OUT_RING (ring, vbufs[i].size); 179 } 180 } 181 182 void 183 fd2_emit_state(struct fd_context *ctx, uint32_t dirty) 184 { 185 struct fd2_blend_stateobj *blend = fd2_blend_stateobj(ctx->blend); 186 struct fd2_zsa_stateobj *zsa = fd2_zsa_stateobj(ctx->zsa); 187 struct fd_ringbuffer *ring = ctx->batch->draw; 188 189 /* NOTE: we probably want to eventually refactor this so each state 190 * object handles emitting it's own state.. although the mapping of 191 * state to registers is not always orthogonal, sometimes a single 192 * register contains bitfields coming from multiple state objects, 193 * so not sure the best way to deal with that yet. 194 */ 195 196 if (dirty & FD_DIRTY_SAMPLE_MASK) { 197 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 198 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK)); 199 OUT_RING(ring, ctx->sample_mask); 200 } 201 202 if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) { 203 struct pipe_stencil_ref *sr = &ctx->stencil_ref; 204 205 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 206 OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL)); 207 OUT_RING(ring, zsa->rb_depthcontrol); 208 209 OUT_PKT3(ring, CP_SET_CONSTANT, 4); 210 OUT_RING(ring, CP_REG(REG_A2XX_RB_STENCILREFMASK_BF)); 211 OUT_RING(ring, zsa->rb_stencilrefmask_bf | 212 A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[1])); 213 OUT_RING(ring, zsa->rb_stencilrefmask | 214 A2XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0])); 215 OUT_RING(ring, zsa->rb_alpha_ref); 216 } 217 218 if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) { 219 struct fd2_rasterizer_stateobj *rasterizer = 220 fd2_rasterizer_stateobj(ctx->rasterizer); 221 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 222 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL)); 223 OUT_RING(ring, rasterizer->pa_cl_clip_cntl); 224 OUT_RING(ring, rasterizer->pa_su_sc_mode_cntl | 225 A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE); 226 227 OUT_PKT3(ring, CP_SET_CONSTANT, 5); 228 OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_POINT_SIZE)); 229 OUT_RING(ring, rasterizer->pa_su_point_size); 230 OUT_RING(ring, rasterizer->pa_su_point_minmax); 231 OUT_RING(ring, rasterizer->pa_su_line_cntl); 232 OUT_RING(ring, rasterizer->pa_sc_line_stipple); 233 234 OUT_PKT3(ring, CP_SET_CONSTANT, 6); 235 OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_VTX_CNTL)); 236 OUT_RING(ring, rasterizer->pa_su_vtx_cntl); 237 OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_CLIP_ADJ */ 238 OUT_RING(ring, fui(1.0)); /* PA_CL_GB_VERT_DISC_ADJ */ 239 OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_CLIP_ADJ */ 240 OUT_RING(ring, fui(1.0)); /* PA_CL_GB_HORZ_DISC_ADJ */ 241 } 242 243 if (dirty & FD_DIRTY_SCISSOR) { 244 struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx); 245 246 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 247 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL)); 248 OUT_RING(ring, xy2d(scissor->minx, /* PA_SC_WINDOW_SCISSOR_TL */ 249 scissor->miny)); 250 OUT_RING(ring, xy2d(scissor->maxx, /* PA_SC_WINDOW_SCISSOR_BR */ 251 scissor->maxy)); 252 253 ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx); 254 ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny); 255 ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx); 256 ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy); 257 } 258 259 if (dirty & FD_DIRTY_VIEWPORT) { 260 OUT_PKT3(ring, CP_SET_CONSTANT, 7); 261 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE)); 262 OUT_RING(ring, fui(ctx->viewport.scale[0])); /* PA_CL_VPORT_XSCALE */ 263 OUT_RING(ring, fui(ctx->viewport.translate[0])); /* PA_CL_VPORT_XOFFSET */ 264 OUT_RING(ring, fui(ctx->viewport.scale[1])); /* PA_CL_VPORT_YSCALE */ 265 OUT_RING(ring, fui(ctx->viewport.translate[1])); /* PA_CL_VPORT_YOFFSET */ 266 OUT_RING(ring, fui(ctx->viewport.scale[2])); /* PA_CL_VPORT_ZSCALE */ 267 OUT_RING(ring, fui(ctx->viewport.translate[2])); /* PA_CL_VPORT_ZOFFSET */ 268 269 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 270 OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL)); 271 OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT | 272 A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA | 273 A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA | 274 A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA | 275 A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA | 276 A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA | 277 A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA); 278 } 279 280 if (dirty & (FD_DIRTY_PROG | FD_DIRTY_VTXSTATE | FD_DIRTY_TEXSTATE)) { 281 fd2_program_validate(ctx); 282 fd2_program_emit(ring, &ctx->prog); 283 } 284 285 if (dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) { 286 emit_constants(ring, VS_CONST_BASE * 4, 287 &ctx->constbuf[PIPE_SHADER_VERTEX], 288 (dirty & FD_DIRTY_PROG) ? ctx->prog.vp : NULL); 289 emit_constants(ring, PS_CONST_BASE * 4, 290 &ctx->constbuf[PIPE_SHADER_FRAGMENT], 291 (dirty & FD_DIRTY_PROG) ? ctx->prog.fp : NULL); 292 } 293 294 if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_ZSA)) { 295 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 296 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL)); 297 OUT_RING(ring, zsa->rb_colorcontrol | blend->rb_colorcontrol); 298 } 299 300 if (dirty & FD_DIRTY_BLEND) { 301 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 302 OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL)); 303 OUT_RING(ring, blend->rb_blendcontrol); 304 305 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 306 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK)); 307 OUT_RING(ring, blend->rb_colormask); 308 } 309 310 if (dirty & (FD_DIRTY_VERTTEX | FD_DIRTY_FRAGTEX | FD_DIRTY_PROG)) 311 emit_textures(ring, ctx); 312 313 ctx->dirty &= ~dirty; 314 } 315 316 /* emit per-context initialization: 317 */ 318 void 319 fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring) 320 { 321 OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1); 322 OUT_RING(ring, 0x00000002); 323 324 OUT_PKT3(ring, CP_INVALIDATE_STATE, 1); 325 OUT_RING(ring, 0x00007fff); 326 327 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 328 OUT_RING(ring, CP_REG(REG_A2XX_SQ_VS_CONST)); 329 OUT_RING(ring, A2XX_SQ_VS_CONST_BASE(VS_CONST_BASE) | 330 A2XX_SQ_VS_CONST_SIZE(0x100)); 331 332 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 333 OUT_RING(ring, CP_REG(REG_A2XX_SQ_PS_CONST)); 334 OUT_RING(ring, A2XX_SQ_PS_CONST_BASE(PS_CONST_BASE) | 335 A2XX_SQ_PS_CONST_SIZE(0xe0)); 336 337 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 338 OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); 339 OUT_RING(ring, 0xffffffff); /* VGT_MAX_VTX_INDX */ 340 OUT_RING(ring, 0x00000000); /* VGT_MIN_VTX_INDX */ 341 342 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 343 OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); 344 OUT_RING(ring, 0x00000000); 345 346 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 347 OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); 348 OUT_RING(ring, 0x0000003b); 349 350 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 351 OUT_RING(ring, CP_REG(REG_A2XX_SQ_CONTEXT_MISC)); 352 OUT_RING(ring, A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(CENTERS_ONLY)); 353 354 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 355 OUT_RING(ring, CP_REG(REG_A2XX_SQ_INTERPOLATOR_CNTL)); 356 OUT_RING(ring, 0xffffffff); 357 358 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 359 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_CONFIG)); 360 OUT_RING(ring, 0x00000000); 361 362 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 363 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_LINE_CNTL)); 364 OUT_RING(ring, 0x00000000); 365 366 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 367 OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET)); 368 OUT_RING(ring, 0x00000000); 369 370 // XXX we change this dynamically for draw/clear.. vs gmem<->mem.. 371 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 372 OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL)); 373 OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH)); 374 375 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 376 OUT_RING(ring, CP_REG(REG_A2XX_RB_SAMPLE_POS)); 377 OUT_RING(ring, 0x88888888); 378 379 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 380 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_DEST_MASK)); 381 OUT_RING(ring, 0xffffffff); 382 383 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 384 OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_INFO)); 385 OUT_RING(ring, A2XX_RB_COPY_DEST_INFO_FORMAT(COLORX_4_4_4_4) | 386 A2XX_RB_COPY_DEST_INFO_WRITE_RED | 387 A2XX_RB_COPY_DEST_INFO_WRITE_GREEN | 388 A2XX_RB_COPY_DEST_INFO_WRITE_BLUE | 389 A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA); 390 391 OUT_PKT3(ring, CP_SET_CONSTANT, 3); 392 OUT_RING(ring, CP_REG(REG_A2XX_SQ_WRAPPING_0)); 393 OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_0 */ 394 OUT_RING(ring, 0x00000000); /* SQ_WRAPPING_1 */ 395 396 OUT_PKT3(ring, CP_SET_DRAW_INIT_FLAGS, 1); 397 OUT_RING(ring, 0x00000000); 398 399 OUT_PKT3(ring, CP_WAIT_REG_EQ, 4); 400 OUT_RING(ring, 0x000005d0); 401 OUT_RING(ring, 0x00000000); 402 OUT_RING(ring, 0x5f601000); 403 OUT_RING(ring, 0x00000001); 404 405 OUT_PKT0(ring, REG_A2XX_SQ_INST_STORE_MANAGMENT, 1); 406 OUT_RING(ring, 0x00000180); 407 408 OUT_PKT3(ring, CP_INVALIDATE_STATE, 1); 409 OUT_RING(ring, 0x00000300); 410 411 OUT_PKT3(ring, CP_SET_SHADER_BASES, 1); 412 OUT_RING(ring, 0x80000180); 413 414 /* not sure what this form of CP_SET_CONSTANT is.. */ 415 OUT_PKT3(ring, CP_SET_CONSTANT, 13); 416 OUT_RING(ring, 0x00000000); 417 OUT_RING(ring, 0x00000000); 418 OUT_RING(ring, 0x00000000); 419 OUT_RING(ring, 0x00000000); 420 OUT_RING(ring, 0x00000000); 421 OUT_RING(ring, 0x469c4000); 422 OUT_RING(ring, 0x3f800000); 423 OUT_RING(ring, 0x3f000000); 424 OUT_RING(ring, 0x00000000); 425 OUT_RING(ring, 0x40000000); 426 OUT_RING(ring, 0x3f400000); 427 OUT_RING(ring, 0x3ec00000); 428 OUT_RING(ring, 0x3e800000); 429 430 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 431 OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_MASK)); 432 OUT_RING(ring, A2XX_RB_COLOR_MASK_WRITE_RED | 433 A2XX_RB_COLOR_MASK_WRITE_GREEN | 434 A2XX_RB_COLOR_MASK_WRITE_BLUE | 435 A2XX_RB_COLOR_MASK_WRITE_ALPHA); 436 437 OUT_PKT3(ring, CP_SET_CONSTANT, 5); 438 OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_RED)); 439 OUT_RING(ring, 0x00000000); /* RB_BLEND_RED */ 440 OUT_RING(ring, 0x00000000); /* RB_BLEND_GREEN */ 441 OUT_RING(ring, 0x00000000); /* RB_BLEND_BLUE */ 442 OUT_RING(ring, 0x000000ff); /* RB_BLEND_ALPHA */ 443 } 444 445 static void 446 fd2_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target) 447 { 448 __OUT_IB(ring, false, target); 449 } 450 451 void 452 fd2_emit_init(struct pipe_context *pctx) 453 { 454 struct fd_context *ctx = fd_context(pctx); 455 ctx->emit_ib = fd2_emit_ib; 456 } 457