1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "pipe/p_state.h" 28bf215546Sopenharmony_ci#include "util/format/u_format.h" 29bf215546Sopenharmony_ci#include "util/u_helpers.h" 30bf215546Sopenharmony_ci#include "util/u_memory.h" 31bf215546Sopenharmony_ci#include "util/u_string.h" 32bf215546Sopenharmony_ci#include "util/u_viewport.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "freedreno_query_hw.h" 35bf215546Sopenharmony_ci#include "freedreno_resource.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "fd3_blend.h" 38bf215546Sopenharmony_ci#include "fd3_context.h" 39bf215546Sopenharmony_ci#include "fd3_emit.h" 40bf215546Sopenharmony_ci#include "fd3_format.h" 41bf215546Sopenharmony_ci#include "fd3_program.h" 42bf215546Sopenharmony_ci#include "fd3_rasterizer.h" 43bf215546Sopenharmony_ci#include "fd3_texture.h" 44bf215546Sopenharmony_ci#include "fd3_zsa.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#define emit_const_user fd3_emit_const_user 47bf215546Sopenharmony_ci#define emit_const_bo fd3_emit_const_bo 48bf215546Sopenharmony_ci#include "ir3_const.h" 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic const enum adreno_state_block sb[] = { 51bf215546Sopenharmony_ci [MESA_SHADER_VERTEX] = SB_VERT_SHADER, 52bf215546Sopenharmony_ci [MESA_SHADER_FRAGMENT] = SB_FRAG_SHADER, 53bf215546Sopenharmony_ci}; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci/* regid: base const register 56bf215546Sopenharmony_ci * prsc or dwords: buffer containing constant values 57bf215546Sopenharmony_ci * sizedwords: size of const value buffer 58bf215546Sopenharmony_ci */ 59bf215546Sopenharmony_cistatic void 60bf215546Sopenharmony_cifd3_emit_const_user(struct fd_ringbuffer *ring, 61bf215546Sopenharmony_ci const struct ir3_shader_variant *v, uint32_t regid, 62bf215546Sopenharmony_ci uint32_t sizedwords, const uint32_t *dwords) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci emit_const_asserts(ring, v, regid, sizedwords); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + sizedwords); 67bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid / 2) | 68bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 69bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) | 70bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(sizedwords / 2)); 71bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) | 72bf215546Sopenharmony_ci CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS)); 73bf215546Sopenharmony_ci for (int i = 0; i < sizedwords; i++) 74bf215546Sopenharmony_ci OUT_RING(ring, dwords[i]); 75bf215546Sopenharmony_ci} 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_cistatic void 78bf215546Sopenharmony_cifd3_emit_const_bo(struct fd_ringbuffer *ring, 79bf215546Sopenharmony_ci const struct ir3_shader_variant *v, uint32_t regid, 80bf215546Sopenharmony_ci uint32_t offset, uint32_t sizedwords, struct fd_bo *bo) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci uint32_t dst_off = regid / 2; 83bf215546Sopenharmony_ci /* The blob driver aligns all const uploads dst_off to 64. We've been 84bf215546Sopenharmony_ci * successfully aligning to 8 vec4s as const_upload_unit so far with no 85bf215546Sopenharmony_ci * ill effects. 86bf215546Sopenharmony_ci */ 87bf215546Sopenharmony_ci assert(dst_off % 16 == 0); 88bf215546Sopenharmony_ci uint32_t num_unit = sizedwords / 2; 89bf215546Sopenharmony_ci assert(num_unit % 2 == 0); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci emit_const_asserts(ring, v, regid, sizedwords); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2); 94bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(dst_off) | 95bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_INDIRECT) | 96bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) | 97bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(num_unit)); 98bf215546Sopenharmony_ci OUT_RELOC(ring, bo, offset, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0); 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_cistatic void 102bf215546Sopenharmony_cifd3_emit_const_ptrs(struct fd_ringbuffer *ring, gl_shader_stage type, 103bf215546Sopenharmony_ci uint32_t regid, uint32_t num, struct fd_bo **bos, 104bf215546Sopenharmony_ci uint32_t *offsets) 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci uint32_t anum = align(num, 4); 107bf215546Sopenharmony_ci uint32_t i; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci assert((regid % 4) == 0); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + anum); 112bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid / 2) | 113bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 114bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(sb[type]) | 115bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(anum / 2)); 116bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) | 117bf215546Sopenharmony_ci CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS)); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci for (i = 0; i < num; i++) { 120bf215546Sopenharmony_ci if (bos[i]) { 121bf215546Sopenharmony_ci OUT_RELOC(ring, bos[i], offsets[i], 0, 0); 122bf215546Sopenharmony_ci } else { 123bf215546Sopenharmony_ci OUT_RING(ring, 0xbad00000 | (i << 16)); 124bf215546Sopenharmony_ci } 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci for (; i < anum; i++) 128bf215546Sopenharmony_ci OUT_RING(ring, 0xffffffff); 129bf215546Sopenharmony_ci} 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cistatic bool 132bf215546Sopenharmony_ciis_stateobj(struct fd_ringbuffer *ring) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci return false; 135bf215546Sopenharmony_ci} 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_cistatic void 138bf215546Sopenharmony_ciemit_const_ptrs(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v, 139bf215546Sopenharmony_ci uint32_t dst_offset, uint32_t num, struct fd_bo **bos, 140bf215546Sopenharmony_ci uint32_t *offsets) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci /* TODO inline this */ 143bf215546Sopenharmony_ci assert(dst_offset + num <= v->constlen * 4); 144bf215546Sopenharmony_ci fd3_emit_const_ptrs(ring, v->type, dst_offset, num, bos, offsets); 145bf215546Sopenharmony_ci} 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci#define VERT_TEX_OFF 0 148bf215546Sopenharmony_ci#define FRAG_TEX_OFF 16 149bf215546Sopenharmony_ci#define BASETABLE_SZ A3XX_MAX_MIP_LEVELS 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_cistatic void 152bf215546Sopenharmony_ciemit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring, 153bf215546Sopenharmony_ci enum adreno_state_block sb, struct fd_texture_stateobj *tex) 154bf215546Sopenharmony_ci{ 155bf215546Sopenharmony_ci static const unsigned tex_off[] = { 156bf215546Sopenharmony_ci [SB_VERT_TEX] = VERT_TEX_OFF, 157bf215546Sopenharmony_ci [SB_FRAG_TEX] = FRAG_TEX_OFF, 158bf215546Sopenharmony_ci }; 159bf215546Sopenharmony_ci static const enum adreno_state_block mipaddr[] = { 160bf215546Sopenharmony_ci [SB_VERT_TEX] = SB_VERT_MIPADDR, 161bf215546Sopenharmony_ci [SB_FRAG_TEX] = SB_FRAG_MIPADDR, 162bf215546Sopenharmony_ci }; 163bf215546Sopenharmony_ci static const uint32_t bcolor_reg[] = { 164bf215546Sopenharmony_ci [SB_VERT_TEX] = REG_A3XX_TPL1_TP_VS_BORDER_COLOR_BASE_ADDR, 165bf215546Sopenharmony_ci [SB_FRAG_TEX] = REG_A3XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR, 166bf215546Sopenharmony_ci }; 167bf215546Sopenharmony_ci struct fd3_context *fd3_ctx = fd3_context(ctx); 168bf215546Sopenharmony_ci bool needs_border = false; 169bf215546Sopenharmony_ci unsigned i, j; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if (tex->num_samplers > 0) { 172bf215546Sopenharmony_ci /* output sampler state: */ 173bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers)); 174bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(tex_off[sb]) | 175bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 176bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(sb) | 177bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(tex->num_samplers)); 178bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) | 179bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 180bf215546Sopenharmony_ci for (i = 0; i < tex->num_samplers; i++) { 181bf215546Sopenharmony_ci static const struct fd3_sampler_stateobj dummy_sampler = {}; 182bf215546Sopenharmony_ci const struct fd3_sampler_stateobj *sampler = 183bf215546Sopenharmony_ci tex->samplers[i] ? fd3_sampler_stateobj(tex->samplers[i]) 184bf215546Sopenharmony_ci : &dummy_sampler; 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci OUT_RING(ring, sampler->texsamp0); 187bf215546Sopenharmony_ci OUT_RING(ring, sampler->texsamp1); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci needs_border |= sampler->needs_border; 190bf215546Sopenharmony_ci } 191bf215546Sopenharmony_ci } 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci if (tex->num_textures > 0) { 194bf215546Sopenharmony_ci /* emit texture state: */ 195bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + (4 * tex->num_textures)); 196bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(tex_off[sb]) | 197bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 198bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(sb) | 199bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(tex->num_textures)); 200bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) | 201bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 202bf215546Sopenharmony_ci for (i = 0; i < tex->num_textures; i++) { 203bf215546Sopenharmony_ci static const struct fd3_pipe_sampler_view dummy_view = {}; 204bf215546Sopenharmony_ci const struct fd3_pipe_sampler_view *view = 205bf215546Sopenharmony_ci tex->textures[i] ? fd3_pipe_sampler_view(tex->textures[i]) 206bf215546Sopenharmony_ci : &dummy_view; 207bf215546Sopenharmony_ci OUT_RING(ring, view->texconst0); 208bf215546Sopenharmony_ci OUT_RING(ring, view->texconst1); 209bf215546Sopenharmony_ci OUT_RING(ring, 210bf215546Sopenharmony_ci view->texconst2 | A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i)); 211bf215546Sopenharmony_ci OUT_RING(ring, view->texconst3); 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci /* emit mipaddrs: */ 215bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + (BASETABLE_SZ * tex->num_textures)); 216bf215546Sopenharmony_ci OUT_RING(ring, 217bf215546Sopenharmony_ci CP_LOAD_STATE_0_DST_OFF(BASETABLE_SZ * tex_off[sb]) | 218bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 219bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(mipaddr[sb]) | 220bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(BASETABLE_SZ * tex->num_textures)); 221bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) | 222bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 223bf215546Sopenharmony_ci for (i = 0; i < tex->num_textures; i++) { 224bf215546Sopenharmony_ci static const struct fd3_pipe_sampler_view dummy_view = { 225bf215546Sopenharmony_ci .base.target = PIPE_TEXTURE_1D, /* anything !PIPE_BUFFER */ 226bf215546Sopenharmony_ci .base.u.tex.first_level = 1, 227bf215546Sopenharmony_ci }; 228bf215546Sopenharmony_ci const struct fd3_pipe_sampler_view *view = 229bf215546Sopenharmony_ci tex->textures[i] ? fd3_pipe_sampler_view(tex->textures[i]) 230bf215546Sopenharmony_ci : &dummy_view; 231bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(view->base.texture); 232bf215546Sopenharmony_ci if (rsc && rsc->b.b.target == PIPE_BUFFER) { 233bf215546Sopenharmony_ci OUT_RELOC(ring, rsc->bo, view->base.u.buf.offset, 0, 0); 234bf215546Sopenharmony_ci j = 1; 235bf215546Sopenharmony_ci } else { 236bf215546Sopenharmony_ci unsigned start = fd_sampler_first_level(&view->base); 237bf215546Sopenharmony_ci unsigned end = fd_sampler_last_level(&view->base); 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci for (j = 0; j < (end - start + 1); j++) { 240bf215546Sopenharmony_ci struct fdl_slice *slice = fd_resource_slice(rsc, j + start); 241bf215546Sopenharmony_ci OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0); 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci /* pad the remaining entries w/ null: */ 246bf215546Sopenharmony_ci for (; j < BASETABLE_SZ; j++) { 247bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci if (needs_border) { 253bf215546Sopenharmony_ci unsigned off; 254bf215546Sopenharmony_ci void *ptr; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci u_upload_alloc(fd3_ctx->border_color_uploader, 0, 257bf215546Sopenharmony_ci BORDER_COLOR_UPLOAD_SIZE, BORDER_COLOR_UPLOAD_SIZE, &off, 258bf215546Sopenharmony_ci &fd3_ctx->border_color_buf, &ptr); 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci fd_setup_border_colors(tex, ptr, tex_off[sb]); 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci OUT_PKT0(ring, bcolor_reg[sb], 1); 263bf215546Sopenharmony_ci OUT_RELOC(ring, fd_resource(fd3_ctx->border_color_buf)->bo, off, 0, 0); 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci u_upload_unmap(fd3_ctx->border_color_uploader); 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci} 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci/* emit texture state for mem->gmem restore operation.. eventually it would 270bf215546Sopenharmony_ci * be good to get rid of this and use normal CSO/etc state for more of these 271bf215546Sopenharmony_ci * special cases, but for now the compiler is not sufficient.. 272bf215546Sopenharmony_ci * 273bf215546Sopenharmony_ci * Also, for using normal state, not quite sure how to handle the special 274bf215546Sopenharmony_ci * case format (fd3_gmem_restore_format()) stuff for restoring depth/stencil. 275bf215546Sopenharmony_ci */ 276bf215546Sopenharmony_civoid 277bf215546Sopenharmony_cifd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, 278bf215546Sopenharmony_ci struct pipe_surface **psurf, int bufs) 279bf215546Sopenharmony_ci{ 280bf215546Sopenharmony_ci int i, j; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci /* output sampler state: */ 283bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + 2 * bufs); 284bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(FRAG_TEX_OFF) | 285bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 286bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(SB_FRAG_TEX) | 287bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(bufs)); 288bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) | 289bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 290bf215546Sopenharmony_ci for (i = 0; i < bufs; i++) { 291bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_SAMP_0_XY_MAG(A3XX_TEX_NEAREST) | 292bf215546Sopenharmony_ci A3XX_TEX_SAMP_0_XY_MIN(A3XX_TEX_NEAREST) | 293bf215546Sopenharmony_ci A3XX_TEX_SAMP_0_WRAP_S(A3XX_TEX_CLAMP_TO_EDGE) | 294bf215546Sopenharmony_ci A3XX_TEX_SAMP_0_WRAP_T(A3XX_TEX_CLAMP_TO_EDGE) | 295bf215546Sopenharmony_ci A3XX_TEX_SAMP_0_WRAP_R(A3XX_TEX_REPEAT)); 296bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 297bf215546Sopenharmony_ci } 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci /* emit texture state: */ 300bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + 4 * bufs); 301bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(FRAG_TEX_OFF) | 302bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 303bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(SB_FRAG_TEX) | 304bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(bufs)); 305bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) | 306bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 307bf215546Sopenharmony_ci for (i = 0; i < bufs; i++) { 308bf215546Sopenharmony_ci if (!psurf[i]) { 309bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) | 310bf215546Sopenharmony_ci A3XX_TEX_CONST_0_SWIZ_X(A3XX_TEX_ONE) | 311bf215546Sopenharmony_ci A3XX_TEX_CONST_0_SWIZ_Y(A3XX_TEX_ONE) | 312bf215546Sopenharmony_ci A3XX_TEX_CONST_0_SWIZ_Z(A3XX_TEX_ONE) | 313bf215546Sopenharmony_ci A3XX_TEX_CONST_0_SWIZ_W(A3XX_TEX_ONE)); 314bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 315bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i)); 316bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 317bf215546Sopenharmony_ci continue; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(psurf[i]->texture); 321bf215546Sopenharmony_ci enum pipe_format format = fd_gmem_restore_format(psurf[i]->format); 322bf215546Sopenharmony_ci /* The restore blit_zs shader expects stencil in sampler 0, and depth 323bf215546Sopenharmony_ci * in sampler 1 324bf215546Sopenharmony_ci */ 325bf215546Sopenharmony_ci if (rsc->stencil && i == 0) { 326bf215546Sopenharmony_ci rsc = rsc->stencil; 327bf215546Sopenharmony_ci format = fd_gmem_restore_format(rsc->b.b.format); 328bf215546Sopenharmony_ci } 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci /* note: PIPE_BUFFER disallowed for surfaces */ 331bf215546Sopenharmony_ci unsigned lvl = psurf[i]->u.tex.level; 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci assert(psurf[i]->u.tex.first_layer == psurf[i]->u.tex.last_layer); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_CONST_0_TILE_MODE(rsc->layout.tile_mode) | 336bf215546Sopenharmony_ci A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(format)) | 337bf215546Sopenharmony_ci A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) | 338bf215546Sopenharmony_ci fd3_tex_swiz(format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, 339bf215546Sopenharmony_ci PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W)); 340bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_CONST_1_WIDTH(psurf[i]->width) | 341bf215546Sopenharmony_ci A3XX_TEX_CONST_1_HEIGHT(psurf[i]->height)); 342bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) | 343bf215546Sopenharmony_ci A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i)); 344bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci /* emit mipaddrs: */ 348bf215546Sopenharmony_ci OUT_PKT3(ring, CP_LOAD_STATE, 2 + BASETABLE_SZ * bufs); 349bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(BASETABLE_SZ * FRAG_TEX_OFF) | 350bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | 351bf215546Sopenharmony_ci CP_LOAD_STATE_0_STATE_BLOCK(SB_FRAG_MIPADDR) | 352bf215546Sopenharmony_ci CP_LOAD_STATE_0_NUM_UNIT(BASETABLE_SZ * bufs)); 353bf215546Sopenharmony_ci OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) | 354bf215546Sopenharmony_ci CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); 355bf215546Sopenharmony_ci for (i = 0; i < bufs; i++) { 356bf215546Sopenharmony_ci if (psurf[i]) { 357bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(psurf[i]->texture); 358bf215546Sopenharmony_ci /* Matches above logic for blit_zs shader */ 359bf215546Sopenharmony_ci if (rsc->stencil && i == 0) 360bf215546Sopenharmony_ci rsc = rsc->stencil; 361bf215546Sopenharmony_ci unsigned lvl = psurf[i]->u.tex.level; 362bf215546Sopenharmony_ci uint32_t offset = 363bf215546Sopenharmony_ci fd_resource_offset(rsc, lvl, psurf[i]->u.tex.first_layer); 364bf215546Sopenharmony_ci OUT_RELOC(ring, rsc->bo, offset, 0, 0); 365bf215546Sopenharmony_ci } else { 366bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 367bf215546Sopenharmony_ci } 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci /* pad the remaining entries w/ null: */ 370bf215546Sopenharmony_ci for (j = 1; j < BASETABLE_SZ; j++) { 371bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 372bf215546Sopenharmony_ci } 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci} 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_civoid 377bf215546Sopenharmony_cifd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit) 378bf215546Sopenharmony_ci{ 379bf215546Sopenharmony_ci int32_t i, j, last = -1; 380bf215546Sopenharmony_ci uint32_t total_in = 0; 381bf215546Sopenharmony_ci const struct fd_vertex_state *vtx = emit->vtx; 382bf215546Sopenharmony_ci const struct ir3_shader_variant *vp = fd3_emit_get_vp(emit); 383bf215546Sopenharmony_ci unsigned vertex_regid = regid(63, 0); 384bf215546Sopenharmony_ci unsigned instance_regid = regid(63, 0); 385bf215546Sopenharmony_ci unsigned vtxcnt_regid = regid(63, 0); 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci /* Note that sysvals come *after* normal inputs: */ 388bf215546Sopenharmony_ci for (i = 0; i < vp->inputs_count; i++) { 389bf215546Sopenharmony_ci if (!vp->inputs[i].compmask) 390bf215546Sopenharmony_ci continue; 391bf215546Sopenharmony_ci if (vp->inputs[i].sysval) { 392bf215546Sopenharmony_ci switch (vp->inputs[i].slot) { 393bf215546Sopenharmony_ci case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: 394bf215546Sopenharmony_ci vertex_regid = vp->inputs[i].regid; 395bf215546Sopenharmony_ci break; 396bf215546Sopenharmony_ci case SYSTEM_VALUE_INSTANCE_ID: 397bf215546Sopenharmony_ci instance_regid = vp->inputs[i].regid; 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci case SYSTEM_VALUE_VERTEX_CNT: 400bf215546Sopenharmony_ci vtxcnt_regid = vp->inputs[i].regid; 401bf215546Sopenharmony_ci break; 402bf215546Sopenharmony_ci default: 403bf215546Sopenharmony_ci unreachable("invalid system value"); 404bf215546Sopenharmony_ci break; 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci } else if (i < vtx->vtx->num_elements) { 407bf215546Sopenharmony_ci last = i; 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci for (i = 0, j = 0; i <= last; i++) { 412bf215546Sopenharmony_ci assert(!vp->inputs[i].sysval); 413bf215546Sopenharmony_ci if (vp->inputs[i].compmask) { 414bf215546Sopenharmony_ci struct pipe_vertex_element *elem = &vtx->vtx->pipe[i]; 415bf215546Sopenharmony_ci const struct pipe_vertex_buffer *vb = 416bf215546Sopenharmony_ci &vtx->vertexbuf.vb[elem->vertex_buffer_index]; 417bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(vb->buffer.resource); 418bf215546Sopenharmony_ci enum pipe_format pfmt = elem->src_format; 419bf215546Sopenharmony_ci enum a3xx_vtx_fmt fmt = fd3_pipe2vtx(pfmt); 420bf215546Sopenharmony_ci bool switchnext = (i != last) || (vertex_regid != regid(63, 0)) || 421bf215546Sopenharmony_ci (instance_regid != regid(63, 0)) || 422bf215546Sopenharmony_ci (vtxcnt_regid != regid(63, 0)); 423bf215546Sopenharmony_ci bool isint = util_format_is_pure_integer(pfmt); 424bf215546Sopenharmony_ci uint32_t off = vb->buffer_offset + elem->src_offset; 425bf215546Sopenharmony_ci uint32_t fs = util_format_get_blocksize(pfmt); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci assert(fmt != VFMT_NONE); 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_FETCH(j), 2); 430bf215546Sopenharmony_ci OUT_RING(ring, A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(fs - 1) | 431bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vb->stride) | 432bf215546Sopenharmony_ci COND(switchnext, A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT) | 433bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_INDEXCODE(j) | 434bf215546Sopenharmony_ci COND(elem->instance_divisor, 435bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_INSTANCED) | 436bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_STEPRATE( 437bf215546Sopenharmony_ci MAX2(1, elem->instance_divisor))); 438bf215546Sopenharmony_ci OUT_RELOC(ring, rsc->bo, off, 0, 0); 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(j), 1); 441bf215546Sopenharmony_ci OUT_RING(ring, 442bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_CONSTFILL | 443bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_WRITEMASK(vp->inputs[i].compmask) | 444bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_FORMAT(fmt) | 445bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_SWAP(fd3_pipe2swap(pfmt)) | 446bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_REGID(vp->inputs[i].regid) | 447bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_SHIFTCNT(fs) | 448bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_LASTCOMPVALID | 449bf215546Sopenharmony_ci COND(isint, A3XX_VFD_DECODE_INSTR_INT) | 450bf215546Sopenharmony_ci COND(switchnext, A3XX_VFD_DECODE_INSTR_SWITCHNEXT)); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci total_in += util_bitcount(vp->inputs[i].compmask); 453bf215546Sopenharmony_ci j++; 454bf215546Sopenharmony_ci } 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci /* hw doesn't like to be configured for zero vbo's, it seems: */ 458bf215546Sopenharmony_ci if (last < 0) { 459bf215546Sopenharmony_ci /* just recycle the shader bo, we just need to point to *something* 460bf215546Sopenharmony_ci * valid: 461bf215546Sopenharmony_ci */ 462bf215546Sopenharmony_ci struct fd_bo *dummy_vbo = vp->bo; 463bf215546Sopenharmony_ci bool switchnext = (vertex_regid != regid(63, 0)) || 464bf215546Sopenharmony_ci (instance_regid != regid(63, 0)) || 465bf215546Sopenharmony_ci (vtxcnt_regid != regid(63, 0)); 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_FETCH(0), 2); 468bf215546Sopenharmony_ci OUT_RING(ring, A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(0) | 469bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(0) | 470bf215546Sopenharmony_ci COND(switchnext, A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT) | 471bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_INDEXCODE(0) | 472bf215546Sopenharmony_ci A3XX_VFD_FETCH_INSTR_0_STEPRATE(1)); 473bf215546Sopenharmony_ci OUT_RELOC(ring, dummy_vbo, 0, 0, 0); 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(0), 1); 476bf215546Sopenharmony_ci OUT_RING(ring, A3XX_VFD_DECODE_INSTR_CONSTFILL | 477bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_WRITEMASK(0x1) | 478bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_FORMAT(VFMT_8_UNORM) | 479bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_SWAP(XYZW) | 480bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_REGID(regid(0, 0)) | 481bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_SHIFTCNT(1) | 482bf215546Sopenharmony_ci A3XX_VFD_DECODE_INSTR_LASTCOMPVALID | 483bf215546Sopenharmony_ci COND(switchnext, A3XX_VFD_DECODE_INSTR_SWITCHNEXT)); 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci total_in = 1; 486bf215546Sopenharmony_ci j = 1; 487bf215546Sopenharmony_ci } 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_CONTROL_0, 2); 490bf215546Sopenharmony_ci OUT_RING(ring, A3XX_VFD_CONTROL_0_TOTALATTRTOVS(total_in) | 491bf215546Sopenharmony_ci A3XX_VFD_CONTROL_0_PACKETSIZE(2) | 492bf215546Sopenharmony_ci A3XX_VFD_CONTROL_0_STRMDECINSTRCNT(j) | 493bf215546Sopenharmony_ci A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(j)); 494bf215546Sopenharmony_ci OUT_RING(ring, A3XX_VFD_CONTROL_1_MAXSTORAGE(1) | // XXX 495bf215546Sopenharmony_ci A3XX_VFD_CONTROL_1_REGID4VTX(vertex_regid) | 496bf215546Sopenharmony_ci A3XX_VFD_CONTROL_1_REGID4INST(instance_regid)); 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VFD_VS_THREADING_THRESHOLD, 1); 499bf215546Sopenharmony_ci OUT_RING(ring, 500bf215546Sopenharmony_ci A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD(15) | 501bf215546Sopenharmony_ci A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT(vtxcnt_regid)); 502bf215546Sopenharmony_ci} 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_civoid 505bf215546Sopenharmony_cifd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, 506bf215546Sopenharmony_ci struct fd3_emit *emit) 507bf215546Sopenharmony_ci{ 508bf215546Sopenharmony_ci const struct ir3_shader_variant *vp = fd3_emit_get_vp(emit); 509bf215546Sopenharmony_ci const struct ir3_shader_variant *fp = fd3_emit_get_fp(emit); 510bf215546Sopenharmony_ci const enum fd_dirty_3d_state dirty = emit->dirty; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci emit_marker(ring, 5); 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci if (dirty & FD_DIRTY_SAMPLE_MASK) { 515bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_MSAA_CONTROL, 1); 516bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_MSAA_CONTROL_DISABLE | 517bf215546Sopenharmony_ci A3XX_RB_MSAA_CONTROL_SAMPLES(MSAA_ONE) | 518bf215546Sopenharmony_ci A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(ctx->sample_mask)); 519bf215546Sopenharmony_ci } 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG | 522bf215546Sopenharmony_ci FD_DIRTY_BLEND_DUAL)) && 523bf215546Sopenharmony_ci !emit->binning_pass) { 524bf215546Sopenharmony_ci uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control | 525bf215546Sopenharmony_ci fd3_blend_stateobj(ctx->blend)->rb_render_control; 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci val |= COND(fp->frag_face, A3XX_RB_RENDER_CONTROL_FACENESS); 528bf215546Sopenharmony_ci val |= COND(fp->fragcoord_compmask != 0, 529bf215546Sopenharmony_ci A3XX_RB_RENDER_CONTROL_COORD_MASK(fp->fragcoord_compmask)); 530bf215546Sopenharmony_ci val |= COND(ctx->rasterizer->rasterizer_discard, 531bf215546Sopenharmony_ci A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE); 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci /* I suppose if we needed to (which I don't *think* we need 534bf215546Sopenharmony_ci * to), we could emit this for binning pass too. But we 535bf215546Sopenharmony_ci * would need to keep a different patch-list for binning 536bf215546Sopenharmony_ci * vs render pass. 537bf215546Sopenharmony_ci */ 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_RENDER_CONTROL, 1); 540bf215546Sopenharmony_ci OUT_RINGP(ring, val, &ctx->batch->rbrc_patches); 541bf215546Sopenharmony_ci } 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_STENCIL_REF)) { 544bf215546Sopenharmony_ci struct fd3_zsa_stateobj *zsa = fd3_zsa_stateobj(ctx->zsa); 545bf215546Sopenharmony_ci struct pipe_stencil_ref *sr = &ctx->stencil_ref; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_ALPHA_REF, 1); 548bf215546Sopenharmony_ci OUT_RING(ring, zsa->rb_alpha_ref); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1); 551bf215546Sopenharmony_ci OUT_RING(ring, zsa->rb_stencil_control); 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2); 554bf215546Sopenharmony_ci OUT_RING(ring, zsa->rb_stencilrefmask | 555bf215546Sopenharmony_ci A3XX_RB_STENCILREFMASK_STENCILREF(sr->ref_value[0])); 556bf215546Sopenharmony_ci OUT_RING(ring, zsa->rb_stencilrefmask_bf | 557bf215546Sopenharmony_ci A3XX_RB_STENCILREFMASK_BF_STENCILREF(sr->ref_value[1])); 558bf215546Sopenharmony_ci } 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) { 561bf215546Sopenharmony_ci uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_depth_control; 562bf215546Sopenharmony_ci if (fp->writes_pos) { 563bf215546Sopenharmony_ci val |= A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z; 564bf215546Sopenharmony_ci val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE; 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci if (fp->no_earlyz || fp->has_kill) { 567bf215546Sopenharmony_ci val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE; 568bf215546Sopenharmony_ci } 569bf215546Sopenharmony_ci if (!ctx->rasterizer->depth_clip_near) { 570bf215546Sopenharmony_ci val |= A3XX_RB_DEPTH_CONTROL_Z_CLAMP_ENABLE; 571bf215546Sopenharmony_ci } 572bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1); 573bf215546Sopenharmony_ci OUT_RING(ring, val); 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci if (dirty & FD_DIRTY_RASTERIZER) { 577bf215546Sopenharmony_ci struct fd3_rasterizer_stateobj *rasterizer = 578bf215546Sopenharmony_ci fd3_rasterizer_stateobj(ctx->rasterizer); 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1); 581bf215546Sopenharmony_ci OUT_RING(ring, rasterizer->gras_su_mode_control); 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SU_POINT_MINMAX, 2); 584bf215546Sopenharmony_ci OUT_RING(ring, rasterizer->gras_su_point_minmax); 585bf215546Sopenharmony_ci OUT_RING(ring, rasterizer->gras_su_point_size); 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE, 2); 588bf215546Sopenharmony_ci OUT_RING(ring, rasterizer->gras_su_poly_offset_scale); 589bf215546Sopenharmony_ci OUT_RING(ring, rasterizer->gras_su_poly_offset_offset); 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) { 593bf215546Sopenharmony_ci uint32_t val = 594bf215546Sopenharmony_ci fd3_rasterizer_stateobj(ctx->rasterizer)->gras_cl_clip_cntl; 595bf215546Sopenharmony_ci uint8_t planes = ctx->rasterizer->clip_plane_enable; 596bf215546Sopenharmony_ci val |= CONDREG( 597bf215546Sopenharmony_ci ir3_find_sysval_regid(fp, SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL), 598bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER); 599bf215546Sopenharmony_ci val |= CONDREG( 600bf215546Sopenharmony_ci ir3_find_sysval_regid(fp, SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL), 601bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_IJ_NON_PERSP_CENTER); 602bf215546Sopenharmony_ci val |= CONDREG( 603bf215546Sopenharmony_ci ir3_find_sysval_regid(fp, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID), 604bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTROID); 605bf215546Sopenharmony_ci val |= CONDREG( 606bf215546Sopenharmony_ci ir3_find_sysval_regid(fp, SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID), 607bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_IJ_NON_PERSP_CENTROID); 608bf215546Sopenharmony_ci /* docs say enable at least one of IJ_PERSP_CENTER/CENTROID when fragcoord 609bf215546Sopenharmony_ci * is used */ 610bf215546Sopenharmony_ci val |= CONDREG(ir3_find_sysval_regid(fp, SYSTEM_VALUE_FRAG_COORD), 611bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER); 612bf215546Sopenharmony_ci val |= COND(fp->writes_pos, A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE); 613bf215546Sopenharmony_ci val |= 614bf215546Sopenharmony_ci COND(fp->fragcoord_compmask != 0, 615bf215546Sopenharmony_ci A3XX_GRAS_CL_CLIP_CNTL_ZCOORD | A3XX_GRAS_CL_CLIP_CNTL_WCOORD); 616bf215546Sopenharmony_ci if (!emit->key.key.ucp_enables) 617bf215546Sopenharmony_ci val |= A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES( 618bf215546Sopenharmony_ci MIN2(util_bitcount(planes), 6)); 619bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); 620bf215546Sopenharmony_ci OUT_RING(ring, val); 621bf215546Sopenharmony_ci } 622bf215546Sopenharmony_ci 623bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG | FD_DIRTY_UCP)) { 624bf215546Sopenharmony_ci uint32_t planes = ctx->rasterizer->clip_plane_enable; 625bf215546Sopenharmony_ci int count = 0; 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci if (emit->key.key.ucp_enables) 628bf215546Sopenharmony_ci planes = 0; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci while (planes && count < 6) { 631bf215546Sopenharmony_ci int i = ffs(planes) - 1; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci planes &= ~(1U << i); 634bf215546Sopenharmony_ci fd_wfi(ctx->batch, ring); 635bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_USER_PLANE(count++), 4); 636bf215546Sopenharmony_ci OUT_RING(ring, fui(ctx->ucp.ucp[i][0])); 637bf215546Sopenharmony_ci OUT_RING(ring, fui(ctx->ucp.ucp[i][1])); 638bf215546Sopenharmony_ci OUT_RING(ring, fui(ctx->ucp.ucp[i][2])); 639bf215546Sopenharmony_ci OUT_RING(ring, fui(ctx->ucp.ucp[i][3])); 640bf215546Sopenharmony_ci } 641bf215546Sopenharmony_ci } 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci /* NOTE: since primitive_restart is not actually part of any 644bf215546Sopenharmony_ci * state object, we need to make sure that we always emit 645bf215546Sopenharmony_ci * PRIM_VTX_CNTL.. either that or be more clever and detect 646bf215546Sopenharmony_ci * when it changes. 647bf215546Sopenharmony_ci */ 648bf215546Sopenharmony_ci if (emit->info) { 649bf215546Sopenharmony_ci const struct pipe_draw_info *info = emit->info; 650bf215546Sopenharmony_ci uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)->pc_prim_vtx_cntl; 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci if (!emit->binning_pass) { 653bf215546Sopenharmony_ci uint32_t stride_in_vpc = align(fp->total_in, 4) / 4; 654bf215546Sopenharmony_ci if (stride_in_vpc > 0) 655bf215546Sopenharmony_ci stride_in_vpc = MAX2(stride_in_vpc, 2); 656bf215546Sopenharmony_ci val |= A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(stride_in_vpc); 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci if (info->index_size && info->primitive_restart) { 660bf215546Sopenharmony_ci val |= A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART; 661bf215546Sopenharmony_ci } 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci val |= COND(vp->writes_psize, A3XX_PC_PRIM_VTX_CNTL_PSIZE); 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1); 666bf215546Sopenharmony_ci OUT_RING(ring, val); 667bf215546Sopenharmony_ci } 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_SCISSOR | FD_DIRTY_RASTERIZER | FD_DIRTY_VIEWPORT)) { 670bf215546Sopenharmony_ci struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx); 671bf215546Sopenharmony_ci int minx = scissor->minx; 672bf215546Sopenharmony_ci int miny = scissor->miny; 673bf215546Sopenharmony_ci int maxx = scissor->maxx; 674bf215546Sopenharmony_ci int maxy = scissor->maxy; 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci /* Unfortunately there is no separate depth clip disable, only an all 677bf215546Sopenharmony_ci * or nothing deal. So when we disable clipping, we must handle the 678bf215546Sopenharmony_ci * viewport clip via scissors. 679bf215546Sopenharmony_ci */ 680bf215546Sopenharmony_ci if (!ctx->rasterizer->depth_clip_near) { 681bf215546Sopenharmony_ci struct pipe_viewport_state *vp = &ctx->viewport; 682bf215546Sopenharmony_ci minx = MAX2(minx, (int)floorf(vp->translate[0] - fabsf(vp->scale[0]))); 683bf215546Sopenharmony_ci miny = MAX2(miny, (int)floorf(vp->translate[1] - fabsf(vp->scale[1]))); 684bf215546Sopenharmony_ci maxx = MIN2(maxx, (int)ceilf(vp->translate[0] + fabsf(vp->scale[0]))); 685bf215546Sopenharmony_ci maxy = MIN2(maxy, (int)ceilf(vp->translate[1] + fabsf(vp->scale[1]))); 686bf215546Sopenharmony_ci } 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2); 689bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(minx) | 690bf215546Sopenharmony_ci A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(miny)); 691bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(maxx - 1) | 692bf215546Sopenharmony_ci A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(maxy - 1)); 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, minx); 695bf215546Sopenharmony_ci ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, miny); 696bf215546Sopenharmony_ci ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, maxx); 697bf215546Sopenharmony_ci ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, maxy); 698bf215546Sopenharmony_ci } 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci if (dirty & FD_DIRTY_VIEWPORT) { 701bf215546Sopenharmony_ci fd_wfi(ctx->batch, ring); 702bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6); 703bf215546Sopenharmony_ci OUT_RING(ring, 704bf215546Sopenharmony_ci A3XX_GRAS_CL_VPORT_XOFFSET(ctx->viewport.translate[0] - 0.5f)); 705bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE(ctx->viewport.scale[0])); 706bf215546Sopenharmony_ci OUT_RING(ring, 707bf215546Sopenharmony_ci A3XX_GRAS_CL_VPORT_YOFFSET(ctx->viewport.translate[1] - 0.5f)); 708bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(ctx->viewport.scale[1])); 709bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(ctx->viewport.translate[2])); 710bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2])); 711bf215546Sopenharmony_ci } 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci if (dirty & 714bf215546Sopenharmony_ci (FD_DIRTY_VIEWPORT | FD_DIRTY_RASTERIZER | FD_DIRTY_FRAMEBUFFER)) { 715bf215546Sopenharmony_ci float zmin, zmax; 716bf215546Sopenharmony_ci int depth = 24; 717bf215546Sopenharmony_ci if (ctx->batch->framebuffer.zsbuf) { 718bf215546Sopenharmony_ci depth = util_format_get_component_bits( 719bf215546Sopenharmony_ci pipe_surface_format(ctx->batch->framebuffer.zsbuf), 720bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_ZS, 0); 721bf215546Sopenharmony_ci } 722bf215546Sopenharmony_ci util_viewport_zmin_zmax(&ctx->viewport, ctx->rasterizer->clip_halfz, 723bf215546Sopenharmony_ci &zmin, &zmax); 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_Z_CLAMP_MIN, 2); 726bf215546Sopenharmony_ci if (depth == 32) { 727bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmin * 0xffffffff)); 728bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmax * 0xffffffff)); 729bf215546Sopenharmony_ci } else if (depth == 16) { 730bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmin * 0xffff)); 731bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmax * 0xffff)); 732bf215546Sopenharmony_ci } else { 733bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmin * 0xffffff)); 734bf215546Sopenharmony_ci OUT_RING(ring, (uint32_t)(zmax * 0xffffff)); 735bf215546Sopenharmony_ci } 736bf215546Sopenharmony_ci } 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_BLEND_DUAL)) { 739bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer; 740bf215546Sopenharmony_ci int nr_cbufs = pfb->nr_cbufs; 741bf215546Sopenharmony_ci if (fd3_blend_stateobj(ctx->blend)->rb_render_control & 742bf215546Sopenharmony_ci A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE) 743bf215546Sopenharmony_ci nr_cbufs++; 744bf215546Sopenharmony_ci fd3_program_emit(ring, emit, nr_cbufs, pfb->cbufs); 745bf215546Sopenharmony_ci } 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci /* TODO we should not need this or fd_wfi() before emit_constants(): 748bf215546Sopenharmony_ci */ 749bf215546Sopenharmony_ci OUT_PKT3(ring, CP_EVENT_WRITE, 1); 750bf215546Sopenharmony_ci OUT_RING(ring, HLSQ_FLUSH); 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci if (!emit->skip_consts) { 753bf215546Sopenharmony_ci ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw); 754bf215546Sopenharmony_ci if (!emit->binning_pass) 755bf215546Sopenharmony_ci ir3_emit_fs_consts(fp, ring, ctx); 756bf215546Sopenharmony_ci } 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) { 759bf215546Sopenharmony_ci struct fd3_blend_stateobj *blend = fd3_blend_stateobj(ctx->blend); 760bf215546Sopenharmony_ci uint32_t i; 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(blend->rb_mrt); i++) { 763bf215546Sopenharmony_ci enum pipe_format format = 764bf215546Sopenharmony_ci pipe_surface_format(ctx->batch->framebuffer.cbufs[i]); 765bf215546Sopenharmony_ci const struct util_format_description *desc = 766bf215546Sopenharmony_ci util_format_description(format); 767bf215546Sopenharmony_ci bool is_float = util_format_is_float(format); 768bf215546Sopenharmony_ci bool is_int = util_format_is_pure_integer(format); 769bf215546Sopenharmony_ci bool has_alpha = util_format_has_alpha(format); 770bf215546Sopenharmony_ci uint32_t control = blend->rb_mrt[i].control; 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci if (is_int) { 773bf215546Sopenharmony_ci control &= (A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK | 774bf215546Sopenharmony_ci A3XX_RB_MRT_CONTROL_DITHER_MODE__MASK); 775bf215546Sopenharmony_ci control |= A3XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY); 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci if (format == PIPE_FORMAT_NONE) 779bf215546Sopenharmony_ci control &= ~A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK; 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci if (!has_alpha) { 782bf215546Sopenharmony_ci control &= ~A3XX_RB_MRT_CONTROL_BLEND2; 783bf215546Sopenharmony_ci } 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci if (format && util_format_get_component_bits( 786bf215546Sopenharmony_ci format, UTIL_FORMAT_COLORSPACE_RGB, 0) < 8) { 787bf215546Sopenharmony_ci const struct pipe_rt_blend_state *rt; 788bf215546Sopenharmony_ci if (ctx->blend->independent_blend_enable) 789bf215546Sopenharmony_ci rt = &ctx->blend->rt[i]; 790bf215546Sopenharmony_ci else 791bf215546Sopenharmony_ci rt = &ctx->blend->rt[0]; 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci if (!util_format_colormask_full(desc, rt->colormask)) 794bf215546Sopenharmony_ci control |= A3XX_RB_MRT_CONTROL_READ_DEST_ENABLE; 795bf215546Sopenharmony_ci } 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1); 798bf215546Sopenharmony_ci OUT_RING(ring, control); 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1); 801bf215546Sopenharmony_ci OUT_RING(ring, 802bf215546Sopenharmony_ci blend->rb_mrt[i].blend_control | 803bf215546Sopenharmony_ci COND(!is_float, A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE)); 804bf215546Sopenharmony_ci } 805bf215546Sopenharmony_ci } 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci if (dirty & FD_DIRTY_BLEND_COLOR) { 808bf215546Sopenharmony_ci struct pipe_blend_color *bcolor = &ctx->blend_color; 809bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_BLEND_RED, 4); 810bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_RED_UINT(CLAMP(bcolor->color[0], 0.f, 1.f) * 0xff) | 811bf215546Sopenharmony_ci A3XX_RB_BLEND_RED_FLOAT(bcolor->color[0])); 812bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_GREEN_UINT(CLAMP(bcolor->color[1], 0.f, 1.f) * 0xff) | 813bf215546Sopenharmony_ci A3XX_RB_BLEND_GREEN_FLOAT(bcolor->color[1])); 814bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_BLUE_UINT(CLAMP(bcolor->color[2], 0.f, 1.f) * 0xff) | 815bf215546Sopenharmony_ci A3XX_RB_BLEND_BLUE_FLOAT(bcolor->color[2])); 816bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(CLAMP(bcolor->color[3], 0.f, 1.f) * 0xff) | 817bf215546Sopenharmony_ci A3XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3])); 818bf215546Sopenharmony_ci } 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci if (dirty & FD_DIRTY_TEX) 821bf215546Sopenharmony_ci fd_wfi(ctx->batch, ring); 822bf215546Sopenharmony_ci 823bf215546Sopenharmony_ci if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) 824bf215546Sopenharmony_ci emit_textures(ctx, ring, SB_VERT_TEX, &ctx->tex[PIPE_SHADER_VERTEX]); 825bf215546Sopenharmony_ci 826bf215546Sopenharmony_ci if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX) 827bf215546Sopenharmony_ci emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->tex[PIPE_SHADER_FRAGMENT]); 828bf215546Sopenharmony_ci} 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci/* emit setup at begin of new cmdstream buffer (don't rely on previous 831bf215546Sopenharmony_ci * state, there could have been a context switch between ioctls): 832bf215546Sopenharmony_ci */ 833bf215546Sopenharmony_civoid 834bf215546Sopenharmony_cifd3_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring) 835bf215546Sopenharmony_ci{ 836bf215546Sopenharmony_ci struct fd_context *ctx = batch->ctx; 837bf215546Sopenharmony_ci struct fd3_context *fd3_ctx = fd3_context(ctx); 838bf215546Sopenharmony_ci int i; 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci if (ctx->screen->gpu_id == 320) { 841bf215546Sopenharmony_ci OUT_PKT3(ring, CP_REG_RMW, 3); 842bf215546Sopenharmony_ci OUT_RING(ring, REG_A3XX_RBBM_CLOCK_CTL); 843bf215546Sopenharmony_ci OUT_RING(ring, 0xfffcffff); 844bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 845bf215546Sopenharmony_ci } 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci fd_wfi(batch, ring); 848bf215546Sopenharmony_ci OUT_PKT3(ring, CP_INVALIDATE_STATE, 1); 849bf215546Sopenharmony_ci OUT_RING(ring, 0x00007fff); 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_SP_VS_PVT_MEM_PARAM_REG, 3); 852bf215546Sopenharmony_ci OUT_RING(ring, 0x08000001); /* SP_VS_PVT_MEM_CTRL_REG */ 853bf215546Sopenharmony_ci OUT_RELOC(ring, fd3_ctx->vs_pvt_mem, 0, 0, 0); /* SP_VS_PVT_MEM_ADDR_REG */ 854bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* SP_VS_PVT_MEM_SIZE_REG */ 855bf215546Sopenharmony_ci 856bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_SP_FS_PVT_MEM_PARAM_REG, 3); 857bf215546Sopenharmony_ci OUT_RING(ring, 0x08000001); /* SP_FS_PVT_MEM_CTRL_REG */ 858bf215546Sopenharmony_ci OUT_RELOC(ring, fd3_ctx->fs_pvt_mem, 0, 0, 0); /* SP_FS_PVT_MEM_ADDR_REG */ 859bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* SP_FS_PVT_MEM_SIZE_REG */ 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1); 862bf215546Sopenharmony_ci OUT_RING(ring, 0x0000000b); /* PC_VERTEX_REUSE_BLOCK_CNTL */ 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1); 865bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) | 866bf215546Sopenharmony_ci A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) | 867bf215546Sopenharmony_ci A3XX_GRAS_SC_CONTROL_RASTER_MODE(0)); 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_MSAA_CONTROL, 2); 870bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_MSAA_CONTROL_DISABLE | 871bf215546Sopenharmony_ci A3XX_RB_MSAA_CONTROL_SAMPLES(MSAA_ONE) | 872bf215546Sopenharmony_ci A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(0xffff)); 873bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_ALPHA_REF */ 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_GB_CLIP_ADJ, 1); 876bf215546Sopenharmony_ci OUT_RING(ring, A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ(0) | 877bf215546Sopenharmony_ci A3XX_GRAS_CL_GB_CLIP_ADJ_VERT(0)); 878bf215546Sopenharmony_ci 879bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_TSE_DEBUG_ECO, 1); 880bf215546Sopenharmony_ci OUT_RING(ring, 0x00000001); /* GRAS_TSE_DEBUG_ECO */ 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_TPL1_TP_VS_TEX_OFFSET, 1); 883bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET(VERT_TEX_OFF) | 884bf215546Sopenharmony_ci A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET(VERT_TEX_OFF) | 885bf215546Sopenharmony_ci A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR(BASETABLE_SZ * 886bf215546Sopenharmony_ci VERT_TEX_OFF)); 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_TPL1_TP_FS_TEX_OFFSET, 1); 889bf215546Sopenharmony_ci OUT_RING(ring, A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET(FRAG_TEX_OFF) | 890bf215546Sopenharmony_ci A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET(FRAG_TEX_OFF) | 891bf215546Sopenharmony_ci A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR(BASETABLE_SZ * 892bf215546Sopenharmony_ci FRAG_TEX_OFF)); 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_VPC_VARY_CYLWRAP_ENABLE_0, 2); 895bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* VPC_VARY_CYLWRAP_ENABLE_0 */ 896bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* VPC_VARY_CYLWRAP_ENABLE_1 */ 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_UNKNOWN_0E43, 1); 899bf215546Sopenharmony_ci OUT_RING(ring, 0x00000001); /* UNKNOWN_0E43 */ 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_UNKNOWN_0F03, 1); 902bf215546Sopenharmony_ci OUT_RING(ring, 0x00000001); /* UNKNOWN_0F03 */ 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_UNKNOWN_0EE0, 1); 905bf215546Sopenharmony_ci OUT_RING(ring, 0x00000003); /* UNKNOWN_0EE0 */ 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_UNKNOWN_0C3D, 1); 908bf215546Sopenharmony_ci OUT_RING(ring, 0x00000001); /* UNKNOWN_0C3D */ 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_HLSQ_PERFCOUNTER0_SELECT, 1); 911bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* HLSQ_PERFCOUNTER0_SELECT */ 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_HLSQ_CONST_VSPRESV_RANGE_REG, 2); 914bf215546Sopenharmony_ci OUT_RING(ring, A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY(0) | 915bf215546Sopenharmony_ci A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY(0)); 916bf215546Sopenharmony_ci OUT_RING(ring, A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY(0) | 917bf215546Sopenharmony_ci A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(0)); 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci fd3_emit_cache_flush(batch, ring); 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); 922bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_CL_CLIP_CNTL */ 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_SU_POINT_MINMAX, 2); 925bf215546Sopenharmony_ci OUT_RING(ring, 0xffc00010); /* GRAS_SU_POINT_MINMAX */ 926bf215546Sopenharmony_ci OUT_RING(ring, 0x00000008); /* GRAS_SU_POINT_SIZE */ 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1); 929bf215546Sopenharmony_ci OUT_RING(ring, 0xffffffff); /* PC_RESTART_INDEX */ 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1); 932bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(0) | A3XX_RB_WINDOW_OFFSET_Y(0)); 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_RB_BLEND_RED, 4); 935bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_RED_UINT(0) | A3XX_RB_BLEND_RED_FLOAT(0.0f)); 936bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_GREEN_UINT(0) | A3XX_RB_BLEND_GREEN_FLOAT(0.0f)); 937bf215546Sopenharmony_ci OUT_RING(ring, A3XX_RB_BLEND_BLUE_UINT(0) | A3XX_RB_BLEND_BLUE_FLOAT(0.0f)); 938bf215546Sopenharmony_ci OUT_RING(ring, 939bf215546Sopenharmony_ci A3XX_RB_BLEND_ALPHA_UINT(0xff) | A3XX_RB_BLEND_ALPHA_FLOAT(1.0f)); 940bf215546Sopenharmony_ci 941bf215546Sopenharmony_ci for (i = 0; i < 6; i++) { 942bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_GRAS_CL_USER_PLANE(i), 4); 943bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_CL_USER_PLANE[i].X */ 944bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_CL_USER_PLANE[i].Y */ 945bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_CL_USER_PLANE[i].Z */ 946bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_CL_USER_PLANE[i].W */ 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci OUT_PKT0(ring, REG_A3XX_PC_VSTREAM_CONTROL, 1); 950bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 951bf215546Sopenharmony_ci 952bf215546Sopenharmony_ci fd_event_write(batch, ring, CACHE_FLUSH); 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci if (is_a3xx_p0(ctx->screen)) { 955bf215546Sopenharmony_ci OUT_PKT3(ring, CP_DRAW_INDX, 3); 956bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 957bf215546Sopenharmony_ci OUT_RING(ring, DRAW(1, DI_SRC_SEL_AUTO_INDEX, INDEX_SIZE_IGN, 958bf215546Sopenharmony_ci IGNORE_VISIBILITY, 0)); 959bf215546Sopenharmony_ci OUT_RING(ring, 0); /* NumIndices */ 960bf215546Sopenharmony_ci } 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci OUT_PKT3(ring, CP_NOP, 4); 963bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 964bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 965bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 966bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci fd_wfi(batch, ring); 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci fd_hw_query_enable(batch, ring); 971bf215546Sopenharmony_ci} 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_civoid 974bf215546Sopenharmony_cifd3_emit_init_screen(struct pipe_screen *pscreen) 975bf215546Sopenharmony_ci{ 976bf215546Sopenharmony_ci struct fd_screen *screen = fd_screen(pscreen); 977bf215546Sopenharmony_ci screen->emit_ib = fd3_emit_ib; 978bf215546Sopenharmony_ci} 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_civoid 981bf215546Sopenharmony_cifd3_emit_init(struct pipe_context *pctx) 982bf215546Sopenharmony_ci{ 983bf215546Sopenharmony_ci} 984