1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2016 Rob Clark <robclark@freedesktop.org> 3bf215546Sopenharmony_ci * Copyright © 2018 Google, Inc. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Rob Clark <robclark@freedesktop.org> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <stdio.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_state.h" 31bf215546Sopenharmony_ci#include "util/format/u_format.h" 32bf215546Sopenharmony_ci#include "util/u_inlines.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci#include "util/u_string.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "freedreno_draw.h" 37bf215546Sopenharmony_ci#include "freedreno_resource.h" 38bf215546Sopenharmony_ci#include "freedreno_state.h" 39bf215546Sopenharmony_ci#include "freedreno_tracepoints.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include "fd6_blitter.h" 42bf215546Sopenharmony_ci#include "fd6_context.h" 43bf215546Sopenharmony_ci#include "fd6_draw.h" 44bf215546Sopenharmony_ci#include "fd6_emit.h" 45bf215546Sopenharmony_ci#include "fd6_gmem.h" 46bf215546Sopenharmony_ci#include "fd6_pack.h" 47bf215546Sopenharmony_ci#include "fd6_program.h" 48bf215546Sopenharmony_ci#include "fd6_resource.h" 49bf215546Sopenharmony_ci#include "fd6_zsa.h" 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci/** 52bf215546Sopenharmony_ci * Emits the flags registers, suitable for RB_MRT_FLAG_BUFFER, 53bf215546Sopenharmony_ci * RB_DEPTH_FLAG_BUFFER, SP_PS_2D_SRC_FLAGS, and RB_BLIT_FLAG_DST. 54bf215546Sopenharmony_ci */ 55bf215546Sopenharmony_civoid 56bf215546Sopenharmony_cifd6_emit_flag_reference(struct fd_ringbuffer *ring, struct fd_resource *rsc, 57bf215546Sopenharmony_ci int level, int layer) 58bf215546Sopenharmony_ci{ 59bf215546Sopenharmony_ci if (fd_resource_ubwc_enabled(rsc, level)) { 60bf215546Sopenharmony_ci OUT_RELOC(ring, rsc->bo, fd_resource_ubwc_offset(rsc, level, layer), 0, 61bf215546Sopenharmony_ci 0); 62bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH( 63bf215546Sopenharmony_ci fdl_ubwc_pitch(&rsc->layout, level)) | 64bf215546Sopenharmony_ci A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH( 65bf215546Sopenharmony_ci rsc->layout.ubwc_layer_size >> 2)); 66bf215546Sopenharmony_ci } else { 67bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */ 68bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_HI */ 69bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 70bf215546Sopenharmony_ci } 71bf215546Sopenharmony_ci} 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic void 74bf215546Sopenharmony_ciemit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb, 75bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci unsigned srgb_cntl = 0; 78bf215546Sopenharmony_ci unsigned i; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci /* Note, GLES 3.2 says "If the fragment’s layer number is negative, or 81bf215546Sopenharmony_ci * greater than or equal to the minimum number of layers of any attachment, 82bf215546Sopenharmony_ci * the effects of the fragment on the framebuffer contents are undefined." 83bf215546Sopenharmony_ci */ 84bf215546Sopenharmony_ci unsigned max_layer_index = 0; 85bf215546Sopenharmony_ci enum a6xx_format mrt0_format = 0; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci for (i = 0; i < pfb->nr_cbufs; i++) { 88bf215546Sopenharmony_ci enum a3xx_color_swap swap = WZYX; 89bf215546Sopenharmony_ci bool sint = false, uint = false; 90bf215546Sopenharmony_ci struct fd_resource *rsc = NULL; 91bf215546Sopenharmony_ci struct fdl_slice *slice = NULL; 92bf215546Sopenharmony_ci uint32_t stride = 0; 93bf215546Sopenharmony_ci uint32_t array_stride = 0; 94bf215546Sopenharmony_ci uint32_t offset; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 97bf215546Sopenharmony_ci continue; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci struct pipe_surface *psurf = pfb->cbufs[i]; 100bf215546Sopenharmony_ci enum pipe_format pformat = psurf->format; 101bf215546Sopenharmony_ci rsc = fd_resource(psurf->texture); 102bf215546Sopenharmony_ci if (!rsc->bo) 103bf215546Sopenharmony_ci continue; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci uint32_t base = gmem ? gmem->cbuf_base[i] : 0; 106bf215546Sopenharmony_ci slice = fd_resource_slice(rsc, psurf->u.tex.level); 107bf215546Sopenharmony_ci uint32_t tile_mode = fd_resource_tile_mode(psurf->texture, psurf->u.tex.level); 108bf215546Sopenharmony_ci enum a6xx_format format = fd6_color_format(pformat, tile_mode); 109bf215546Sopenharmony_ci sint = util_format_is_pure_sint(pformat); 110bf215546Sopenharmony_ci uint = util_format_is_pure_uint(pformat); 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci if (util_format_is_srgb(pformat)) 113bf215546Sopenharmony_ci srgb_cntl |= (1 << i); 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci offset = 116bf215546Sopenharmony_ci fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci stride = fd_resource_pitch(rsc, psurf->u.tex.level); 119bf215546Sopenharmony_ci array_stride = fd_resource_layer_stride(rsc, psurf->u.tex.level); 120bf215546Sopenharmony_ci swap = fd6_color_swap(pformat, rsc->layout.tile_mode); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci max_layer_index = psurf->u.tex.last_layer - psurf->u.tex.first_layer; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci assert((offset + slice->size0) <= fd_bo_size(rsc->bo)); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci OUT_REG( 127bf215546Sopenharmony_ci ring, 128bf215546Sopenharmony_ci A6XX_RB_MRT_BUF_INFO(i, .color_format = format, 129bf215546Sopenharmony_ci .color_tile_mode = tile_mode, .color_swap = swap), 130bf215546Sopenharmony_ci A6XX_RB_MRT_PITCH(i, .a6xx_rb_mrt_pitch = stride), 131bf215546Sopenharmony_ci A6XX_RB_MRT_ARRAY_PITCH(i, .a6xx_rb_mrt_array_pitch = array_stride), 132bf215546Sopenharmony_ci A6XX_RB_MRT_BASE(i, .bo = rsc->bo, .bo_offset = offset), 133bf215546Sopenharmony_ci A6XX_RB_MRT_BASE_GMEM(i, .unknown = base)); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci OUT_REG(ring, A6XX_SP_FS_MRT_REG(i, .color_format = format, 136bf215546Sopenharmony_ci .color_sint = sint, .color_uint = uint)); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_MRT_FLAG_BUFFER(i), 3); 139bf215546Sopenharmony_ci fd6_emit_flag_reference(ring, rsc, psurf->u.tex.level, 140bf215546Sopenharmony_ci psurf->u.tex.first_layer); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci if (i == 0) 143bf215546Sopenharmony_ci mrt0_format = format; 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci if (pfb->zsbuf) 146bf215546Sopenharmony_ci max_layer_index = pfb->zsbuf->u.tex.last_layer - pfb->zsbuf->u.tex.first_layer; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_LRZ_MRT_BUF_INFO_0(.color_format = mrt0_format)); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_SRGB_CNTL(.dword = srgb_cntl)); 151bf215546Sopenharmony_ci OUT_REG(ring, A6XX_SP_SRGB_CNTL(.dword = srgb_cntl)); 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_MAX_LAYER_INDEX(max_layer_index)); 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_cistatic void 157bf215546Sopenharmony_ciemit_zs(struct fd_ringbuffer *ring, struct pipe_surface *zsbuf, 158bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci if (zsbuf) { 161bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(zsbuf->texture); 162bf215546Sopenharmony_ci enum a6xx_depth_format fmt = fd6_pipe2depth(zsbuf->format); 163bf215546Sopenharmony_ci uint32_t stride = fd_resource_pitch(rsc, zsbuf->u.tex.level); 164bf215546Sopenharmony_ci uint32_t array_stride = fd_resource_layer_stride(rsc, zsbuf->u.tex.level); 165bf215546Sopenharmony_ci uint32_t base = gmem ? gmem->zsbuf_base[0] : 0; 166bf215546Sopenharmony_ci uint32_t offset = 167bf215546Sopenharmony_ci fd_resource_offset(rsc, zsbuf->u.tex.level, zsbuf->u.tex.first_layer); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci OUT_REG( 170bf215546Sopenharmony_ci ring, A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt), 171bf215546Sopenharmony_ci A6XX_RB_DEPTH_BUFFER_PITCH(.a6xx_rb_depth_buffer_pitch = stride), 172bf215546Sopenharmony_ci A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(.a6xx_rb_depth_buffer_array_pitch = 173bf215546Sopenharmony_ci array_stride), 174bf215546Sopenharmony_ci A6XX_RB_DEPTH_BUFFER_BASE(.bo = rsc->bo, .bo_offset = offset), 175bf215546Sopenharmony_ci A6XX_RB_DEPTH_BUFFER_BASE_GMEM(.dword = base)); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_SU_DEPTH_BUFFER_INFO(.depth_format = fmt)); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE, 3); 180bf215546Sopenharmony_ci fd6_emit_flag_reference(ring, rsc, zsbuf->u.tex.level, 181bf215546Sopenharmony_ci zsbuf->u.tex.first_layer); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci if (rsc->lrz) { 184bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_LRZ_BUFFER_BASE(.bo = rsc->lrz), 185bf215546Sopenharmony_ci A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = rsc->lrz_pitch), 186bf215546Sopenharmony_ci // XXX a6xx seems to use a different buffer here.. not sure 187bf215546Sopenharmony_ci // what for.. 188bf215546Sopenharmony_ci A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE()); 189bf215546Sopenharmony_ci } else { 190bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_BUFFER_BASE, 5); 191bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 192bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 193bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */ 194bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */ 195bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); 196bf215546Sopenharmony_ci } 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci /* NOTE: blob emits GRAS_LRZ_CNTL plus GRAZ_LRZ_BUFFER_BASE 199bf215546Sopenharmony_ci * plus this CP_EVENT_WRITE at the end in it's own IB.. 200bf215546Sopenharmony_ci */ 201bf215546Sopenharmony_ci OUT_PKT7(ring, CP_EVENT_WRITE, 1); 202bf215546Sopenharmony_ci OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(LRZ_CLEAR)); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci if (rsc->stencil) { 205bf215546Sopenharmony_ci stride = fd_resource_pitch(rsc->stencil, zsbuf->u.tex.level); 206bf215546Sopenharmony_ci array_stride = fd_resource_layer_stride(rsc->stencil, zsbuf->u.tex.level); 207bf215546Sopenharmony_ci uint32_t base = gmem ? gmem->zsbuf_base[1] : 0; 208bf215546Sopenharmony_ci uint32_t offset = 209bf215546Sopenharmony_ci fd_resource_offset(rsc->stencil, zsbuf->u.tex.level, zsbuf->u.tex.first_layer); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_STENCIL_INFO(.separate_stencil = true), 212bf215546Sopenharmony_ci A6XX_RB_STENCIL_BUFFER_PITCH(.a6xx_rb_stencil_buffer_pitch = 213bf215546Sopenharmony_ci stride), 214bf215546Sopenharmony_ci A6XX_RB_STENCIL_BUFFER_ARRAY_PITCH( 215bf215546Sopenharmony_ci .a6xx_rb_stencil_buffer_array_pitch = array_stride), 216bf215546Sopenharmony_ci A6XX_RB_STENCIL_BUFFER_BASE(.bo = rsc->stencil->bo, .bo_offset = offset), 217bf215546Sopenharmony_ci A6XX_RB_STENCIL_BUFFER_BASE_GMEM(.dword = base)); 218bf215546Sopenharmony_ci } else { 219bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_STENCIL_INFO(0)); 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci } else { 222bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6); 223bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(DEPTH6_NONE)); 224bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_BUFFER_PITCH */ 225bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_BUFFER_ARRAY_PITCH */ 226bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_BUFFER_BASE_LO */ 227bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_BUFFER_BASE_HI */ 228bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_BUFFER_BASE_GMEM */ 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci OUT_REG(ring, 231bf215546Sopenharmony_ci A6XX_GRAS_SU_DEPTH_BUFFER_INFO(.depth_format = DEPTH6_NONE)); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_BUFFER_BASE, 5); 234bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_LO */ 235bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* RB_DEPTH_FLAG_BUFFER_BASE_HI */ 236bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_LRZ_BUFFER_PITCH */ 237bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO */ 238bf215546Sopenharmony_ci OUT_RING(ring, 0x00000000); /* GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI */ 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_STENCIL_INFO(0)); 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci} 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_cistatic bool 245bf215546Sopenharmony_ciuse_hw_binning(struct fd_batch *batch) 246bf215546Sopenharmony_ci{ 247bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci if ((gmem->maxpw * gmem->maxph) > 32) 250bf215546Sopenharmony_ci return false; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci return fd_binning_enabled && ((gmem->nbins_x * gmem->nbins_y) >= 2) && 253bf215546Sopenharmony_ci (batch->num_draws > 0); 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_cistatic void 257bf215546Sopenharmony_cipatch_fb_read_gmem(struct fd_batch *batch) 258bf215546Sopenharmony_ci{ 259bf215546Sopenharmony_ci unsigned num_patches = fd_patch_num_elements(&batch->fb_read_patches); 260bf215546Sopenharmony_ci if (!num_patches) 261bf215546Sopenharmony_ci return; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci struct fd_screen *screen = batch->ctx->screen; 264bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 265bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 266bf215546Sopenharmony_ci struct pipe_surface *psurf = pfb->cbufs[0]; 267bf215546Sopenharmony_ci struct pipe_resource *prsc = psurf->texture; 268bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(prsc); 269bf215546Sopenharmony_ci enum pipe_format format = psurf->format; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci uint8_t swiz[4]; 272bf215546Sopenharmony_ci fdl6_format_swiz(psurf->format, false, swiz); 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci /* always TILE6_2 mode in GMEM, which also means no swap: */ 275bf215546Sopenharmony_ci uint32_t texconst0 = A6XX_TEX_CONST_0_FMT(fd6_texture_format(format, rsc->layout.tile_mode)) | 276bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) | 277bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SWAP(WZYX) | 278bf215546Sopenharmony_ci A6XX_TEX_CONST_0_TILE_MODE(TILE6_2) | 279bf215546Sopenharmony_ci COND(util_format_is_srgb(format), A6XX_TEX_CONST_0_SRGB) | 280bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SWIZ_X(fdl6_swiz(swiz[0])) | 281bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SWIZ_Y(fdl6_swiz(swiz[1])) | 282bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SWIZ_Z(fdl6_swiz(swiz[2])) | 283bf215546Sopenharmony_ci A6XX_TEX_CONST_0_SWIZ_W(fdl6_swiz(swiz[3])); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci for (unsigned i = 0; i < num_patches; i++) { 286bf215546Sopenharmony_ci struct fd_cs_patch *patch = fd_patch_element(&batch->fb_read_patches, i); 287bf215546Sopenharmony_ci patch->cs[0] = texconst0; 288bf215546Sopenharmony_ci patch->cs[2] = A6XX_TEX_CONST_2_PITCH(gmem->bin_w * gmem->cbuf_cpp[0]) | 289bf215546Sopenharmony_ci A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D); 290bf215546Sopenharmony_ci patch->cs[4] = A6XX_TEX_CONST_4_BASE_LO(screen->gmem_base); 291bf215546Sopenharmony_ci patch->cs[5] = A6XX_TEX_CONST_5_BASE_HI(screen->gmem_base >> 32) | 292bf215546Sopenharmony_ci A6XX_TEX_CONST_5_DEPTH(1); 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci util_dynarray_clear(&batch->fb_read_patches); 295bf215546Sopenharmony_ci} 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_cistatic void 298bf215546Sopenharmony_cipatch_fb_read_sysmem(struct fd_batch *batch) 299bf215546Sopenharmony_ci{ 300bf215546Sopenharmony_ci unsigned num_patches = fd_patch_num_elements(&batch->fb_read_patches); 301bf215546Sopenharmony_ci if (!num_patches) 302bf215546Sopenharmony_ci return; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 305bf215546Sopenharmony_ci struct pipe_surface *psurf = pfb->cbufs[0]; 306bf215546Sopenharmony_ci if (!psurf) 307bf215546Sopenharmony_ci return; 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(psurf->texture); 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci uint32_t block_width, block_height; 312bf215546Sopenharmony_ci fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci struct fdl_view_args args = { 315bf215546Sopenharmony_ci .iova = fd_bo_get_iova(rsc->bo), 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci .base_miplevel = psurf->u.tex.level, 318bf215546Sopenharmony_ci .level_count = 1, 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci .base_array_layer = psurf->u.tex.first_layer, 321bf215546Sopenharmony_ci .layer_count = 1, 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci .format = psurf->format, 324bf215546Sopenharmony_ci .swiz = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W}, 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci .type = FDL_VIEW_TYPE_2D, 327bf215546Sopenharmony_ci .chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN, 328bf215546Sopenharmony_ci FDL_CHROMA_LOCATION_COSITED_EVEN}, 329bf215546Sopenharmony_ci }; 330bf215546Sopenharmony_ci const struct fdl_layout *layouts[3] = {&rsc->layout, NULL, NULL}; 331bf215546Sopenharmony_ci struct fdl6_view view; 332bf215546Sopenharmony_ci fdl6_view_init(&view, layouts, &args, 333bf215546Sopenharmony_ci batch->ctx->screen->info->a6xx.has_z24uint_s8uint); 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci for (unsigned i = 0; i < num_patches; i++) { 336bf215546Sopenharmony_ci struct fd_cs_patch *patch = fd_patch_element(&batch->fb_read_patches, i); 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci /* This is cheating a bit, since we can't use OUT_RELOC() here.. but 339bf215546Sopenharmony_ci * the render target will already have a reloc emitted for RB_MRT state, 340bf215546Sopenharmony_ci * so we can get away with manually patching in the address here: 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_ci memcpy(patch->cs, view.descriptor, FDL6_TEX_CONST_DWORDS * 4); 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci util_dynarray_clear(&batch->fb_read_patches); 345bf215546Sopenharmony_ci} 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_cistatic void 348bf215546Sopenharmony_ciupdate_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb, 349bf215546Sopenharmony_ci bool binning) 350bf215546Sopenharmony_ci{ 351bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 352bf215546Sopenharmony_ci struct fd_screen *screen = batch->ctx->screen; 353bf215546Sopenharmony_ci uint32_t cntl = 0; 354bf215546Sopenharmony_ci bool depth_ubwc_enable = false; 355bf215546Sopenharmony_ci uint32_t mrts_ubwc_enable = 0; 356bf215546Sopenharmony_ci int i; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci if (pfb->zsbuf) { 359bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture); 360bf215546Sopenharmony_ci depth_ubwc_enable = 361bf215546Sopenharmony_ci fd_resource_ubwc_enabled(rsc, pfb->zsbuf->u.tex.level); 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci for (i = 0; i < pfb->nr_cbufs; i++) { 365bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 366bf215546Sopenharmony_ci continue; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci struct pipe_surface *psurf = pfb->cbufs[i]; 369bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(psurf->texture); 370bf215546Sopenharmony_ci if (!rsc->bo) 371bf215546Sopenharmony_ci continue; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (fd_resource_ubwc_enabled(rsc, psurf->u.tex.level)) 374bf215546Sopenharmony_ci mrts_ubwc_enable |= 1 << i; 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci cntl |= A6XX_RB_RENDER_CNTL_CCUSINGLECACHELINESIZE(2); 378bf215546Sopenharmony_ci if (binning) 379bf215546Sopenharmony_ci cntl |= A6XX_RB_RENDER_CNTL_BINNING; 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci if (screen->info->a6xx.has_cp_reg_write) { 382bf215546Sopenharmony_ci OUT_PKT7(ring, CP_REG_WRITE, 3); 383bf215546Sopenharmony_ci OUT_RING(ring, CP_REG_WRITE_0_TRACKER(TRACK_RENDER_CNTL)); 384bf215546Sopenharmony_ci OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL); 385bf215546Sopenharmony_ci } else { 386bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_RENDER_CNTL, 1); 387bf215546Sopenharmony_ci } 388bf215546Sopenharmony_ci OUT_RING(ring, cntl | 389bf215546Sopenharmony_ci COND(depth_ubwc_enable, A6XX_RB_RENDER_CNTL_FLAG_DEPTH) | 390bf215546Sopenharmony_ci A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable)); 391bf215546Sopenharmony_ci} 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci/* extra size to store VSC_DRAW_STRM_SIZE: */ 394bf215546Sopenharmony_ci#define VSC_DRAW_STRM_SIZE(pitch) ((pitch)*32 + 0x100) 395bf215546Sopenharmony_ci#define VSC_PRIM_STRM_SIZE(pitch) ((pitch)*32) 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_cistatic void 398bf215546Sopenharmony_ciupdate_vsc_pipe(struct fd_batch *batch) 399bf215546Sopenharmony_ci{ 400bf215546Sopenharmony_ci struct fd_context *ctx = batch->ctx; 401bf215546Sopenharmony_ci struct fd6_context *fd6_ctx = fd6_context(ctx); 402bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 403bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 404bf215546Sopenharmony_ci int i; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci if (batch->draw_strm_bits / 8 > fd6_ctx->vsc_draw_strm_pitch) { 407bf215546Sopenharmony_ci if (fd6_ctx->vsc_draw_strm) 408bf215546Sopenharmony_ci fd_bo_del(fd6_ctx->vsc_draw_strm); 409bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm = NULL; 410bf215546Sopenharmony_ci /* Note: probably only need to align to 0x40, but aligning stronger 411bf215546Sopenharmony_ci * reduces the odds that we will have to realloc again on the next 412bf215546Sopenharmony_ci * frame: 413bf215546Sopenharmony_ci */ 414bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm_pitch = align(batch->draw_strm_bits / 8, 0x4000); 415bf215546Sopenharmony_ci mesa_logd("pre-resize VSC_DRAW_STRM_PITCH to: 0x%x", 416bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm_pitch); 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci if (batch->prim_strm_bits / 8 > fd6_ctx->vsc_prim_strm_pitch) { 420bf215546Sopenharmony_ci if (fd6_ctx->vsc_prim_strm) 421bf215546Sopenharmony_ci fd_bo_del(fd6_ctx->vsc_prim_strm); 422bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm = NULL; 423bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm_pitch = align(batch->prim_strm_bits / 8, 0x4000); 424bf215546Sopenharmony_ci mesa_logd("pre-resize VSC_PRIM_STRM_PITCH to: 0x%x", 425bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm_pitch); 426bf215546Sopenharmony_ci } 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci if (!fd6_ctx->vsc_draw_strm) { 429bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm = fd_bo_new( 430bf215546Sopenharmony_ci ctx->screen->dev, VSC_DRAW_STRM_SIZE(fd6_ctx->vsc_draw_strm_pitch), 431bf215546Sopenharmony_ci FD_BO_NOMAP, "vsc_draw_strm"); 432bf215546Sopenharmony_ci } 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci if (!fd6_ctx->vsc_prim_strm) { 435bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm = fd_bo_new( 436bf215546Sopenharmony_ci ctx->screen->dev, VSC_PRIM_STRM_SIZE(fd6_ctx->vsc_prim_strm_pitch), 437bf215546Sopenharmony_ci FD_BO_NOMAP, "vsc_prim_strm"); 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci OUT_REG( 441bf215546Sopenharmony_ci ring, A6XX_VSC_BIN_SIZE(.width = gmem->bin_w, .height = gmem->bin_h), 442bf215546Sopenharmony_ci A6XX_VSC_DRAW_STRM_SIZE_ADDRESS(.bo = fd6_ctx->vsc_draw_strm, 443bf215546Sopenharmony_ci .bo_offset = 444bf215546Sopenharmony_ci 32 * fd6_ctx->vsc_draw_strm_pitch)); 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VSC_BIN_COUNT(.nx = gmem->nbins_x, .ny = gmem->nbins_y)); 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_VSC_PIPE_CONFIG_REG(0), 32); 449bf215546Sopenharmony_ci for (i = 0; i < 32; i++) { 450bf215546Sopenharmony_ci const struct fd_vsc_pipe *pipe = &gmem->vsc_pipe[i]; 451bf215546Sopenharmony_ci OUT_RING(ring, A6XX_VSC_PIPE_CONFIG_REG_X(pipe->x) | 452bf215546Sopenharmony_ci A6XX_VSC_PIPE_CONFIG_REG_Y(pipe->y) | 453bf215546Sopenharmony_ci A6XX_VSC_PIPE_CONFIG_REG_W(pipe->w) | 454bf215546Sopenharmony_ci A6XX_VSC_PIPE_CONFIG_REG_H(pipe->h)); 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci OUT_REG( 458bf215546Sopenharmony_ci ring, A6XX_VSC_PRIM_STRM_ADDRESS(.bo = fd6_ctx->vsc_prim_strm), 459bf215546Sopenharmony_ci A6XX_VSC_PRIM_STRM_PITCH(.dword = fd6_ctx->vsc_prim_strm_pitch), 460bf215546Sopenharmony_ci A6XX_VSC_PRIM_STRM_LIMIT(.dword = fd6_ctx->vsc_prim_strm_pitch - 64)); 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci OUT_REG( 463bf215546Sopenharmony_ci ring, A6XX_VSC_DRAW_STRM_ADDRESS(.bo = fd6_ctx->vsc_draw_strm), 464bf215546Sopenharmony_ci A6XX_VSC_DRAW_STRM_PITCH(.dword = fd6_ctx->vsc_draw_strm_pitch), 465bf215546Sopenharmony_ci A6XX_VSC_DRAW_STRM_LIMIT(.dword = fd6_ctx->vsc_draw_strm_pitch - 64)); 466bf215546Sopenharmony_ci} 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci/* 469bf215546Sopenharmony_ci * If overflow is detected, either 0x1 (VSC_DRAW_STRM overflow) or 0x3 470bf215546Sopenharmony_ci * (VSC_PRIM_STRM overflow) plus the size of the overflowed buffer is 471bf215546Sopenharmony_ci * written to control->vsc_overflow. This allows the CPU to 472bf215546Sopenharmony_ci * detect which buffer overflowed (and, since the current size is 473bf215546Sopenharmony_ci * encoded as well, this protects against already-submitted but 474bf215546Sopenharmony_ci * not executed batches from fooling the CPU into increasing the 475bf215546Sopenharmony_ci * size again unnecessarily). 476bf215546Sopenharmony_ci */ 477bf215546Sopenharmony_cistatic void 478bf215546Sopenharmony_ciemit_vsc_overflow_test(struct fd_batch *batch) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 481bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 482bf215546Sopenharmony_ci struct fd6_context *fd6_ctx = fd6_context(batch->ctx); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci assert((fd6_ctx->vsc_draw_strm_pitch & 0x3) == 0); 485bf215546Sopenharmony_ci assert((fd6_ctx->vsc_prim_strm_pitch & 0x3) == 0); 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci /* Check for overflow, write vsc_scratch if detected: */ 488bf215546Sopenharmony_ci for (int i = 0; i < gmem->num_vsc_pipes; i++) { 489bf215546Sopenharmony_ci OUT_PKT7(ring, CP_COND_WRITE5, 8); 490bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_0_FUNCTION(WRITE_GE) | 491bf215546Sopenharmony_ci CP_COND_WRITE5_0_WRITE_MEMORY); 492bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_1_POLL_ADDR_LO( 493bf215546Sopenharmony_ci REG_A6XX_VSC_DRAW_STRM_SIZE_REG(i))); 494bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_2_POLL_ADDR_HI(0)); 495bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_3_REF(fd6_ctx->vsc_draw_strm_pitch - 64)); 496bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_4_MASK(~0)); 497bf215546Sopenharmony_ci OUT_RELOC(ring, 498bf215546Sopenharmony_ci control_ptr(fd6_ctx, vsc_overflow)); /* WRITE_ADDR_LO/HI */ 499bf215546Sopenharmony_ci OUT_RING(ring, 500bf215546Sopenharmony_ci CP_COND_WRITE5_7_WRITE_DATA(1 + fd6_ctx->vsc_draw_strm_pitch)); 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci OUT_PKT7(ring, CP_COND_WRITE5, 8); 503bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_0_FUNCTION(WRITE_GE) | 504bf215546Sopenharmony_ci CP_COND_WRITE5_0_WRITE_MEMORY); 505bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_1_POLL_ADDR_LO( 506bf215546Sopenharmony_ci REG_A6XX_VSC_PRIM_STRM_SIZE_REG(i))); 507bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_2_POLL_ADDR_HI(0)); 508bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_3_REF(fd6_ctx->vsc_prim_strm_pitch - 64)); 509bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_WRITE5_4_MASK(~0)); 510bf215546Sopenharmony_ci OUT_RELOC(ring, 511bf215546Sopenharmony_ci control_ptr(fd6_ctx, vsc_overflow)); /* WRITE_ADDR_LO/HI */ 512bf215546Sopenharmony_ci OUT_RING(ring, 513bf215546Sopenharmony_ci CP_COND_WRITE5_7_WRITE_DATA(3 + fd6_ctx->vsc_prim_strm_pitch)); 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci 516bf215546Sopenharmony_ci OUT_PKT7(ring, CP_WAIT_MEM_WRITES, 0); 517bf215546Sopenharmony_ci} 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_cistatic void 520bf215546Sopenharmony_cicheck_vsc_overflow(struct fd_context *ctx) 521bf215546Sopenharmony_ci{ 522bf215546Sopenharmony_ci struct fd6_context *fd6_ctx = fd6_context(ctx); 523bf215546Sopenharmony_ci struct fd6_control *control = fd_bo_map(fd6_ctx->control_mem); 524bf215546Sopenharmony_ci uint32_t vsc_overflow = control->vsc_overflow; 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci if (!vsc_overflow) 527bf215546Sopenharmony_ci return; 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci /* clear overflow flag: */ 530bf215546Sopenharmony_ci control->vsc_overflow = 0; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci unsigned buffer = vsc_overflow & 0x3; 533bf215546Sopenharmony_ci unsigned size = vsc_overflow & ~0x3; 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_ci if (buffer == 0x1) { 536bf215546Sopenharmony_ci /* VSC_DRAW_STRM overflow: */ 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci if (size < fd6_ctx->vsc_draw_strm_pitch) { 539bf215546Sopenharmony_ci /* we've already increased the size, this overflow is 540bf215546Sopenharmony_ci * from a batch submitted before resize, but executed 541bf215546Sopenharmony_ci * after 542bf215546Sopenharmony_ci */ 543bf215546Sopenharmony_ci return; 544bf215546Sopenharmony_ci } 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci fd_bo_del(fd6_ctx->vsc_draw_strm); 547bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm = NULL; 548bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm_pitch *= 2; 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci mesa_logd("resized VSC_DRAW_STRM_PITCH to: 0x%x", 551bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm_pitch); 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci } else if (buffer == 0x3) { 554bf215546Sopenharmony_ci /* VSC_PRIM_STRM overflow: */ 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci if (size < fd6_ctx->vsc_prim_strm_pitch) { 557bf215546Sopenharmony_ci /* we've already increased the size */ 558bf215546Sopenharmony_ci return; 559bf215546Sopenharmony_ci } 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci fd_bo_del(fd6_ctx->vsc_prim_strm); 562bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm = NULL; 563bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm_pitch *= 2; 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci mesa_logd("resized VSC_PRIM_STRM_PITCH to: 0x%x", 566bf215546Sopenharmony_ci fd6_ctx->vsc_prim_strm_pitch); 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci } else { 569bf215546Sopenharmony_ci /* NOTE: it's possible, for example, for overflow to corrupt the 570bf215546Sopenharmony_ci * control page. I mostly just see this hit if I set initial VSC 571bf215546Sopenharmony_ci * buffer size extremely small. Things still seem to recover, 572bf215546Sopenharmony_ci * but maybe we should pre-emptively realloc vsc_data/vsc_data2 573bf215546Sopenharmony_ci * and hope for different memory placement? 574bf215546Sopenharmony_ci */ 575bf215546Sopenharmony_ci mesa_loge("invalid vsc_overflow value: 0x%08x", vsc_overflow); 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci} 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_cistatic void 580bf215546Sopenharmony_ciemit_common_init(struct fd_batch *batch) 581bf215546Sopenharmony_ci{ 582bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 583bf215546Sopenharmony_ci struct fd_autotune *at = &batch->ctx->autotune; 584bf215546Sopenharmony_ci struct fd_batch_result *result = batch->autotune_result; 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci if (!result) 587bf215546Sopenharmony_ci return; 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_SAMPLE_COUNT_CONTROL, 1); 590bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_SAMPLE_COUNT_CONTROL_COPY); 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_SAMPLE_COUNT_ADDR, 2); 593bf215546Sopenharmony_ci OUT_RELOC(ring, results_ptr(at, result[result->idx].samples_start)); 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci fd6_event_write(batch, ring, ZPASS_DONE, false); 596bf215546Sopenharmony_ci} 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_cistatic void 599bf215546Sopenharmony_ciemit_common_fini(struct fd_batch *batch) 600bf215546Sopenharmony_ci{ 601bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 602bf215546Sopenharmony_ci struct fd_autotune *at = &batch->ctx->autotune; 603bf215546Sopenharmony_ci struct fd_batch_result *result = batch->autotune_result; 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci if (!result) 606bf215546Sopenharmony_ci return; 607bf215546Sopenharmony_ci 608bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_SAMPLE_COUNT_CONTROL, 1); 609bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_SAMPLE_COUNT_CONTROL_COPY); 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_SAMPLE_COUNT_ADDR, 2); 612bf215546Sopenharmony_ci OUT_RELOC(ring, results_ptr(at, result[result->idx].samples_end)); 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci fd6_event_write(batch, ring, ZPASS_DONE, false); 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci // TODO is there a better event to use.. a single ZPASS_DONE_TS would be nice 617bf215546Sopenharmony_ci OUT_PKT7(ring, CP_EVENT_WRITE, 4); 618bf215546Sopenharmony_ci OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_TS)); 619bf215546Sopenharmony_ci OUT_RELOC(ring, results_ptr(at, fence)); 620bf215546Sopenharmony_ci OUT_RING(ring, result->fence); 621bf215546Sopenharmony_ci} 622bf215546Sopenharmony_ci 623bf215546Sopenharmony_ci/* 624bf215546Sopenharmony_ci * Emit conditional CP_INDIRECT_BRANCH based on VSC_STATE[p], ie. the IB 625bf215546Sopenharmony_ci * is skipped for tiles that have no visible geometry. 626bf215546Sopenharmony_ci */ 627bf215546Sopenharmony_cistatic void 628bf215546Sopenharmony_ciemit_conditional_ib(struct fd_batch *batch, const struct fd_tile *tile, 629bf215546Sopenharmony_ci struct fd_ringbuffer *target) 630bf215546Sopenharmony_ci{ 631bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci if (target->cur == target->start) 634bf215546Sopenharmony_ci return; 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci emit_marker6(ring, 6); 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci unsigned count = fd_ringbuffer_cmd_count(target); 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_ci BEGIN_RING(ring, 5 + 4 * count); /* ensure conditional doesn't get split */ 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci OUT_PKT7(ring, CP_REG_TEST, 1); 643bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_REG_TEST_0_REG(REG_A6XX_VSC_STATE_REG(tile->p)) | 644bf215546Sopenharmony_ci A6XX_CP_REG_TEST_0_BIT(tile->n) | 645bf215546Sopenharmony_ci A6XX_CP_REG_TEST_0_WAIT_FOR_ME); 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci OUT_PKT7(ring, CP_COND_REG_EXEC, 2); 648bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_REG_EXEC_0_MODE(PRED_TEST)); 649bf215546Sopenharmony_ci OUT_RING(ring, CP_COND_REG_EXEC_1_DWORDS(4 * count)); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci for (unsigned i = 0; i < count; i++) { 652bf215546Sopenharmony_ci uint32_t dwords; 653bf215546Sopenharmony_ci OUT_PKT7(ring, CP_INDIRECT_BUFFER, 3); 654bf215546Sopenharmony_ci dwords = fd_ringbuffer_emit_reloc_ring_full(ring, target, i) / 4; 655bf215546Sopenharmony_ci assert(dwords > 0); 656bf215546Sopenharmony_ci OUT_RING(ring, dwords); 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci emit_marker6(ring, 6); 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_cistatic void 663bf215546Sopenharmony_ciset_scissor(struct fd_ringbuffer *ring, uint32_t x1, uint32_t y1, uint32_t x2, 664bf215546Sopenharmony_ci uint32_t y2) 665bf215546Sopenharmony_ci{ 666bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_SC_WINDOW_SCISSOR_TL(.x = x1, .y = y1), 667bf215546Sopenharmony_ci A6XX_GRAS_SC_WINDOW_SCISSOR_BR(.x = x2, .y = y2)); 668bf215546Sopenharmony_ci 669bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_2D_RESOLVE_CNTL_1(.x = x1, .y = y1), 670bf215546Sopenharmony_ci A6XX_GRAS_2D_RESOLVE_CNTL_2(.x = x2, .y = y2)); 671bf215546Sopenharmony_ci} 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_cistatic void 674bf215546Sopenharmony_ciset_bin_size(struct fd_ringbuffer *ring, uint32_t w, uint32_t h, uint32_t flag) 675bf215546Sopenharmony_ci{ 676bf215546Sopenharmony_ci OUT_REG(ring, A6XX_GRAS_BIN_CONTROL(.binw = w, .binh = h, .dword = flag)); 677bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_BIN_CONTROL(.binw = w, .binh = h, .dword = flag)); 678bf215546Sopenharmony_ci /* no flag for RB_BIN_CONTROL2... */ 679bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_BIN_CONTROL2(.binw = w, .binh = h)); 680bf215546Sopenharmony_ci} 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_cistatic void 683bf215546Sopenharmony_ciemit_binning_pass(struct fd_batch *batch) assert_dt 684bf215546Sopenharmony_ci{ 685bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 686bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 687bf215546Sopenharmony_ci struct fd_screen *screen = batch->ctx->screen; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci assert(!batch->tessellation); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci set_scissor(ring, 0, 0, gmem->width - 1, gmem->height - 1); 692bf215546Sopenharmony_ci 693bf215546Sopenharmony_ci emit_marker6(ring, 7); 694bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MARKER, 1); 695bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BINNING)); 696bf215546Sopenharmony_ci emit_marker6(ring, 7); 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); 699bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MODE, 1); 702bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci OUT_WFI5(ring); 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VFD_MODE_CNTL(.render_mode = BINNING_PASS)); 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci update_vsc_pipe(batch); 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_PC_POWER_CNTL, 1); 711bf215546Sopenharmony_ci OUT_RING(ring, screen->info->a6xx.magic.PC_POWER_CNTL); 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_VFD_POWER_CNTL, 1); 714bf215546Sopenharmony_ci OUT_RING(ring, screen->info->a6xx.magic.PC_POWER_CNTL); 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci OUT_PKT7(ring, CP_EVENT_WRITE, 1); 717bf215546Sopenharmony_ci OUT_RING(ring, UNK_2C); 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_WINDOW_OFFSET, 1); 720bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_WINDOW_OFFSET_X(0) | A6XX_RB_WINDOW_OFFSET_Y(0)); 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_SP_TP_WINDOW_OFFSET, 1); 723bf215546Sopenharmony_ci OUT_RING(ring, 724bf215546Sopenharmony_ci A6XX_SP_TP_WINDOW_OFFSET_X(0) | A6XX_SP_TP_WINDOW_OFFSET_Y(0)); 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci /* emit IB to binning drawcmds: */ 727bf215546Sopenharmony_ci trace_start_binning_ib(&batch->trace, ring); 728bf215546Sopenharmony_ci fd6_emit_ib(ring, batch->draw); 729bf215546Sopenharmony_ci trace_end_binning_ib(&batch->trace, ring); 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci fd_reset_wfi(batch); 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_DRAW_STATE, 3); 734bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__0_COUNT(0) | 735bf215546Sopenharmony_ci CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS | 736bf215546Sopenharmony_ci CP_SET_DRAW_STATE__0_GROUP_ID(0)); 737bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__1_ADDR_LO(0)); 738bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__2_ADDR_HI(0)); 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci OUT_PKT7(ring, CP_EVENT_WRITE, 1); 741bf215546Sopenharmony_ci OUT_RING(ring, UNK_2D); 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci fd6_cache_inv(batch, ring); 744bf215546Sopenharmony_ci fd6_cache_flush(batch, ring); 745bf215546Sopenharmony_ci fd_wfi(batch, ring); 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci trace_start_vsc_overflow_test(&batch->trace, batch->gmem); 750bf215546Sopenharmony_ci emit_vsc_overflow_test(batch); 751bf215546Sopenharmony_ci trace_end_vsc_overflow_test(&batch->trace, batch->gmem); 752bf215546Sopenharmony_ci 753bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); 754bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MODE, 1); 757bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_ci OUT_WFI5(ring); 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci OUT_REG(ring, 762bf215546Sopenharmony_ci A6XX_RB_CCU_CNTL(.color_offset = screen->ccu_offset_gmem, 763bf215546Sopenharmony_ci .gmem = true, 764bf215546Sopenharmony_ci .concurrent_resolve = screen->info->a6xx.concurrent_resolve)); 765bf215546Sopenharmony_ci} 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_cistatic void 768bf215546Sopenharmony_ciemit_msaa(struct fd_ringbuffer *ring, unsigned nr) 769bf215546Sopenharmony_ci{ 770bf215546Sopenharmony_ci enum a3xx_msaa_samples samples = fd_msaa_samples(nr); 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_SP_TP_RAS_MSAA_CNTL, 2); 773bf215546Sopenharmony_ci OUT_RING(ring, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(samples)); 774bf215546Sopenharmony_ci OUT_RING(ring, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(samples) | 775bf215546Sopenharmony_ci COND(samples == MSAA_ONE, 776bf215546Sopenharmony_ci A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE)); 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_GRAS_RAS_MSAA_CNTL, 2); 779bf215546Sopenharmony_ci OUT_RING(ring, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(samples)); 780bf215546Sopenharmony_ci OUT_RING(ring, A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(samples) | 781bf215546Sopenharmony_ci COND(samples == MSAA_ONE, 782bf215546Sopenharmony_ci A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE)); 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_RAS_MSAA_CNTL, 2); 785bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(samples)); 786bf215546Sopenharmony_ci OUT_RING(ring, 787bf215546Sopenharmony_ci A6XX_RB_DEST_MSAA_CNTL_SAMPLES(samples) | 788bf215546Sopenharmony_ci COND(samples == MSAA_ONE, A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE)); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_MSAA_CNTL, 1); 791bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_MSAA_CNTL_SAMPLES(samples)); 792bf215546Sopenharmony_ci} 793bf215546Sopenharmony_ci 794bf215546Sopenharmony_cistatic void prepare_tile_setup_ib(struct fd_batch *batch); 795bf215546Sopenharmony_cistatic void prepare_tile_fini_ib(struct fd_batch *batch); 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci/* before first tile */ 798bf215546Sopenharmony_cistatic void 799bf215546Sopenharmony_cifd6_emit_tile_init(struct fd_batch *batch) assert_dt 800bf215546Sopenharmony_ci{ 801bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 802bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 803bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 804bf215546Sopenharmony_ci struct fd_screen *screen = batch->ctx->screen; 805bf215546Sopenharmony_ci 806bf215546Sopenharmony_ci fd6_emit_restore(batch, ring); 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_ci fd6_emit_lrz_flush(ring); 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci if (batch->prologue) { 811bf215546Sopenharmony_ci trace_start_prologue(&batch->trace, ring); 812bf215546Sopenharmony_ci fd6_emit_ib(ring, batch->prologue); 813bf215546Sopenharmony_ci trace_end_prologue(&batch->trace, ring); 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci fd6_cache_inv(batch, ring); 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci prepare_tile_setup_ib(batch); 819bf215546Sopenharmony_ci prepare_tile_fini_ib(batch); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1); 822bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci /* blob controls "local" in IB2, but I think that is not required */ 825bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_LOCAL, 1); 826bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci fd_wfi(batch, ring); 829bf215546Sopenharmony_ci OUT_REG(ring, 830bf215546Sopenharmony_ci A6XX_RB_CCU_CNTL(.color_offset = screen->ccu_offset_gmem, 831bf215546Sopenharmony_ci .gmem = true, 832bf215546Sopenharmony_ci .concurrent_resolve = screen->info->a6xx.concurrent_resolve)); 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci emit_zs(ring, pfb->zsbuf, batch->gmem_state); 835bf215546Sopenharmony_ci emit_mrt(ring, pfb, batch->gmem_state); 836bf215546Sopenharmony_ci emit_msaa(ring, pfb->samples); 837bf215546Sopenharmony_ci patch_fb_read_gmem(batch); 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci if (use_hw_binning(batch)) { 840bf215546Sopenharmony_ci /* enable stream-out during binning pass: */ 841bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VPC_SO_DISABLE(false)); 842bf215546Sopenharmony_ci 843bf215546Sopenharmony_ci set_bin_size(ring, gmem->bin_w, gmem->bin_h, 844bf215546Sopenharmony_ci A6XX_RB_BIN_CONTROL_RENDER_MODE(BINNING_PASS) | 845bf215546Sopenharmony_ci A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK(0x6)); 846bf215546Sopenharmony_ci update_render_cntl(batch, pfb, true); 847bf215546Sopenharmony_ci emit_binning_pass(batch); 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci /* and disable stream-out for draw pass: */ 850bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VPC_SO_DISABLE(true)); 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci /* 853bf215546Sopenharmony_ci * NOTE: even if we detect VSC overflow and disable use of 854bf215546Sopenharmony_ci * visibility stream in draw pass, it is still safe to execute 855bf215546Sopenharmony_ci * the reset of these cmds: 856bf215546Sopenharmony_ci */ 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci // NOTE a618 not setting .FORCE_LRZ_WRITE_DIS .. 859bf215546Sopenharmony_ci set_bin_size(ring, gmem->bin_w, gmem->bin_h, 860bf215546Sopenharmony_ci A6XX_RB_BIN_CONTROL_FORCE_LRZ_WRITE_DIS | 861bf215546Sopenharmony_ci A6XX_RB_BIN_CONTROL_LRZ_FEEDBACK_ZMODE_MASK(0x6)); 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_VFD_MODE_CNTL, 1); 864bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_PC_POWER_CNTL, 1); 867bf215546Sopenharmony_ci OUT_RING(ring, screen->info->a6xx.magic.PC_POWER_CNTL); 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_VFD_POWER_CNTL, 1); 870bf215546Sopenharmony_ci OUT_RING(ring, screen->info->a6xx.magic.PC_POWER_CNTL); 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1); 873bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 874bf215546Sopenharmony_ci } else { 875bf215546Sopenharmony_ci /* no binning pass, so enable stream-out for draw pass:: */ 876bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VPC_SO_DISABLE(false)); 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci set_bin_size(ring, gmem->bin_w, gmem->bin_h, 0x6000000); 879bf215546Sopenharmony_ci } 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci update_render_cntl(batch, pfb, false); 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci emit_common_init(batch); 884bf215546Sopenharmony_ci} 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_cistatic void 887bf215546Sopenharmony_ciset_window_offset(struct fd_ringbuffer *ring, uint32_t x1, uint32_t y1) 888bf215546Sopenharmony_ci{ 889bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_WINDOW_OFFSET, 1); 890bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_WINDOW_OFFSET_X(x1) | A6XX_RB_WINDOW_OFFSET_Y(y1)); 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_WINDOW_OFFSET2, 1); 893bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_WINDOW_OFFSET2_X(x1) | A6XX_RB_WINDOW_OFFSET2_Y(y1)); 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_SP_WINDOW_OFFSET, 1); 896bf215546Sopenharmony_ci OUT_RING(ring, A6XX_SP_WINDOW_OFFSET_X(x1) | A6XX_SP_WINDOW_OFFSET_Y(y1)); 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_SP_TP_WINDOW_OFFSET, 1); 899bf215546Sopenharmony_ci OUT_RING(ring, 900bf215546Sopenharmony_ci A6XX_SP_TP_WINDOW_OFFSET_X(x1) | A6XX_SP_TP_WINDOW_OFFSET_Y(y1)); 901bf215546Sopenharmony_ci} 902bf215546Sopenharmony_ci 903bf215546Sopenharmony_ci/* before mem2gmem */ 904bf215546Sopenharmony_cistatic void 905bf215546Sopenharmony_cifd6_emit_tile_prep(struct fd_batch *batch, const struct fd_tile *tile) 906bf215546Sopenharmony_ci{ 907bf215546Sopenharmony_ci struct fd_context *ctx = batch->ctx; 908bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 909bf215546Sopenharmony_ci struct fd6_context *fd6_ctx = fd6_context(ctx); 910bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci emit_marker6(ring, 7); 913bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MARKER, 1); 914bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_GMEM)); 915bf215546Sopenharmony_ci emit_marker6(ring, 7); 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci uint32_t x1 = tile->xoff; 918bf215546Sopenharmony_ci uint32_t y1 = tile->yoff; 919bf215546Sopenharmony_ci uint32_t x2 = tile->xoff + tile->bin_w - 1; 920bf215546Sopenharmony_ci uint32_t y2 = tile->yoff + tile->bin_h - 1; 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci set_scissor(ring, x1, y1, x2, y2); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci if (use_hw_binning(batch)) { 925bf215546Sopenharmony_ci const struct fd_vsc_pipe *pipe = &gmem->vsc_pipe[tile->p]; 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MODE, 1); 930bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_BIN_DATA5, 7); 933bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_BIN_DATA5_0_VSC_SIZE(pipe->w * pipe->h) | 934bf215546Sopenharmony_ci CP_SET_BIN_DATA5_0_VSC_N(tile->n)); 935bf215546Sopenharmony_ci OUT_RELOC(ring, fd6_ctx->vsc_draw_strm, /* per-pipe draw-stream address */ 936bf215546Sopenharmony_ci (tile->p * fd6_ctx->vsc_draw_strm_pitch), 0, 0); 937bf215546Sopenharmony_ci OUT_RELOC(ring, 938bf215546Sopenharmony_ci fd6_ctx->vsc_draw_strm, /* VSC_DRAW_STRM_ADDRESS + (p * 4) */ 939bf215546Sopenharmony_ci (tile->p * 4) + (32 * fd6_ctx->vsc_draw_strm_pitch), 0, 0); 940bf215546Sopenharmony_ci OUT_RELOC(ring, fd6_ctx->vsc_prim_strm, 941bf215546Sopenharmony_ci (tile->p * fd6_ctx->vsc_prim_strm_pitch), 0, 0); 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); 944bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 945bf215546Sopenharmony_ci 946bf215546Sopenharmony_ci set_window_offset(ring, x1, y1); 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 949bf215546Sopenharmony_ci set_bin_size(ring, gmem->bin_w, gmem->bin_h, 0x6000000); 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MODE, 1); 952bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 953bf215546Sopenharmony_ci } else { 954bf215546Sopenharmony_ci set_window_offset(ring, x1, y1); 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); 957bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MODE, 1); 960bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 961bf215546Sopenharmony_ci } 962bf215546Sopenharmony_ci} 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_cistatic void 965bf215546Sopenharmony_ciset_blit_scissor(struct fd_batch *batch, struct fd_ringbuffer *ring) 966bf215546Sopenharmony_ci{ 967bf215546Sopenharmony_ci struct pipe_scissor_state blit_scissor = batch->max_scissor; 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci blit_scissor.minx = ROUND_DOWN_TO(blit_scissor.minx, 16); 970bf215546Sopenharmony_ci blit_scissor.miny = ROUND_DOWN_TO(blit_scissor.miny, 4); 971bf215546Sopenharmony_ci blit_scissor.maxx = ALIGN(blit_scissor.maxx, 16); 972bf215546Sopenharmony_ci blit_scissor.maxy = ALIGN(blit_scissor.maxy, 4); 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_SCISSOR_TL, 2); 975bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_BLIT_SCISSOR_TL_X(blit_scissor.minx) | 976bf215546Sopenharmony_ci A6XX_RB_BLIT_SCISSOR_TL_Y(blit_scissor.miny)); 977bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_BLIT_SCISSOR_BR_X(blit_scissor.maxx - 1) | 978bf215546Sopenharmony_ci A6XX_RB_BLIT_SCISSOR_BR_Y(blit_scissor.maxy - 1)); 979bf215546Sopenharmony_ci} 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_cistatic void 982bf215546Sopenharmony_ciemit_blit(struct fd_batch *batch, struct fd_ringbuffer *ring, uint32_t base, 983bf215546Sopenharmony_ci struct pipe_surface *psurf, bool stencil) 984bf215546Sopenharmony_ci{ 985bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(psurf->texture); 986bf215546Sopenharmony_ci enum pipe_format pfmt = psurf->format; 987bf215546Sopenharmony_ci uint32_t offset; 988bf215546Sopenharmony_ci bool ubwc_enabled; 989bf215546Sopenharmony_ci 990bf215546Sopenharmony_ci assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer); 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci /* separate stencil case: */ 993bf215546Sopenharmony_ci if (stencil) { 994bf215546Sopenharmony_ci rsc = rsc->stencil; 995bf215546Sopenharmony_ci pfmt = rsc->b.b.format; 996bf215546Sopenharmony_ci } 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci offset = 999bf215546Sopenharmony_ci fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); 1000bf215546Sopenharmony_ci ubwc_enabled = fd_resource_ubwc_enabled(rsc, psurf->u.tex.level); 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer); 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci uint32_t tile_mode = fd_resource_tile_mode(&rsc->b.b, psurf->u.tex.level); 1005bf215546Sopenharmony_ci enum a6xx_format format = fd6_color_format(pfmt, tile_mode); 1006bf215546Sopenharmony_ci uint32_t stride = fd_resource_pitch(rsc, psurf->u.tex.level); 1007bf215546Sopenharmony_ci uint32_t array_stride = fd_resource_layer_stride(rsc, psurf->u.tex.level); 1008bf215546Sopenharmony_ci enum a3xx_color_swap swap = fd6_color_swap(pfmt, rsc->layout.tile_mode); 1009bf215546Sopenharmony_ci enum a3xx_msaa_samples samples = fd_msaa_samples(rsc->b.b.nr_samples); 1010bf215546Sopenharmony_ci 1011bf215546Sopenharmony_ci OUT_REG(ring, 1012bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO(.tile_mode = tile_mode, .samples = samples, 1013bf215546Sopenharmony_ci .color_format = format, .color_swap = swap, 1014bf215546Sopenharmony_ci .flags = ubwc_enabled), 1015bf215546Sopenharmony_ci A6XX_RB_BLIT_DST(.bo = rsc->bo, .bo_offset = offset), 1016bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_PITCH(.a6xx_rb_blit_dst_pitch = stride), 1017bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_ARRAY_PITCH(.a6xx_rb_blit_dst_array_pitch = array_stride)); 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_BLIT_BASE_GMEM(.dword = base)); 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci if (ubwc_enabled) { 1022bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_FLAG_DST, 3); 1023bf215546Sopenharmony_ci fd6_emit_flag_reference(ring, rsc, psurf->u.tex.level, 1024bf215546Sopenharmony_ci psurf->u.tex.first_layer); 1025bf215546Sopenharmony_ci } 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci fd6_emit_blit(batch, ring); 1028bf215546Sopenharmony_ci} 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_cistatic void 1031bf215546Sopenharmony_ciemit_restore_blit(struct fd_batch *batch, struct fd_ringbuffer *ring, 1032bf215546Sopenharmony_ci uint32_t base, struct pipe_surface *psurf, unsigned buffer) 1033bf215546Sopenharmony_ci{ 1034bf215546Sopenharmony_ci bool stencil = (buffer == FD_BUFFER_STENCIL); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_BLIT_INFO(.gmem = true, .unk0 = true, 1037bf215546Sopenharmony_ci .depth = (buffer == FD_BUFFER_DEPTH), 1038bf215546Sopenharmony_ci .sample_0 = util_format_is_pure_integer( 1039bf215546Sopenharmony_ci psurf->format))); 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci emit_blit(batch, ring, base, psurf, stencil); 1042bf215546Sopenharmony_ci} 1043bf215546Sopenharmony_ci 1044bf215546Sopenharmony_cistatic void 1045bf215546Sopenharmony_ciemit_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) 1046bf215546Sopenharmony_ci{ 1047bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 1048bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 1049bf215546Sopenharmony_ci enum a3xx_msaa_samples samples = fd_msaa_samples(pfb->samples); 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci uint32_t buffers = batch->fast_cleared; 1052bf215546Sopenharmony_ci 1053bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR) { 1054bf215546Sopenharmony_ci 1055bf215546Sopenharmony_ci for (int i = 0; i < pfb->nr_cbufs; i++) { 1056bf215546Sopenharmony_ci union pipe_color_union *color = &batch->clear_color[i]; 1057bf215546Sopenharmony_ci union util_color uc = {0}; 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 1060bf215546Sopenharmony_ci continue; 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_ci if (!(buffers & (PIPE_CLEAR_COLOR0 << i))) 1063bf215546Sopenharmony_ci continue; 1064bf215546Sopenharmony_ci 1065bf215546Sopenharmony_ci enum pipe_format pfmt = pfb->cbufs[i]->format; 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ci // XXX I think RB_CLEAR_COLOR_DWn wants to take into account SWAP?? 1068bf215546Sopenharmony_ci union pipe_color_union swapped; 1069bf215546Sopenharmony_ci switch (fd6_color_swap(pfmt, TILE6_LINEAR)) { 1070bf215546Sopenharmony_ci case WZYX: 1071bf215546Sopenharmony_ci swapped.ui[0] = color->ui[0]; 1072bf215546Sopenharmony_ci swapped.ui[1] = color->ui[1]; 1073bf215546Sopenharmony_ci swapped.ui[2] = color->ui[2]; 1074bf215546Sopenharmony_ci swapped.ui[3] = color->ui[3]; 1075bf215546Sopenharmony_ci break; 1076bf215546Sopenharmony_ci case WXYZ: 1077bf215546Sopenharmony_ci swapped.ui[2] = color->ui[0]; 1078bf215546Sopenharmony_ci swapped.ui[1] = color->ui[1]; 1079bf215546Sopenharmony_ci swapped.ui[0] = color->ui[2]; 1080bf215546Sopenharmony_ci swapped.ui[3] = color->ui[3]; 1081bf215546Sopenharmony_ci break; 1082bf215546Sopenharmony_ci case ZYXW: 1083bf215546Sopenharmony_ci swapped.ui[3] = color->ui[0]; 1084bf215546Sopenharmony_ci swapped.ui[0] = color->ui[1]; 1085bf215546Sopenharmony_ci swapped.ui[1] = color->ui[2]; 1086bf215546Sopenharmony_ci swapped.ui[2] = color->ui[3]; 1087bf215546Sopenharmony_ci break; 1088bf215546Sopenharmony_ci case XYZW: 1089bf215546Sopenharmony_ci swapped.ui[3] = color->ui[0]; 1090bf215546Sopenharmony_ci swapped.ui[2] = color->ui[1]; 1091bf215546Sopenharmony_ci swapped.ui[1] = color->ui[2]; 1092bf215546Sopenharmony_ci swapped.ui[0] = color->ui[3]; 1093bf215546Sopenharmony_ci break; 1094bf215546Sopenharmony_ci } 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci util_pack_color_union(pfmt, &uc, &swapped); 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1); 1099bf215546Sopenharmony_ci OUT_RING(ring, 1100bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) | 1101bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) | 1102bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_color_format(pfmt, TILE6_LINEAR))); 1103bf215546Sopenharmony_ci 1104bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1); 1105bf215546Sopenharmony_ci OUT_RING(ring, 1106bf215546Sopenharmony_ci A6XX_RB_BLIT_INFO_GMEM | A6XX_RB_BLIT_INFO_CLEAR_MASK(0xf)); 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1); 1109bf215546Sopenharmony_ci OUT_RING(ring, gmem->cbuf_base[i]); 1110bf215546Sopenharmony_ci 1111bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_88D0, 1); 1112bf215546Sopenharmony_ci OUT_RING(ring, 0); 1113bf215546Sopenharmony_ci 1114bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 4); 1115bf215546Sopenharmony_ci OUT_RING(ring, uc.ui[0]); 1116bf215546Sopenharmony_ci OUT_RING(ring, uc.ui[1]); 1117bf215546Sopenharmony_ci OUT_RING(ring, uc.ui[2]); 1118bf215546Sopenharmony_ci OUT_RING(ring, uc.ui[3]); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci fd6_emit_blit(batch, ring); 1121bf215546Sopenharmony_ci } 1122bf215546Sopenharmony_ci } 1123bf215546Sopenharmony_ci 1124bf215546Sopenharmony_ci const bool has_depth = pfb->zsbuf; 1125bf215546Sopenharmony_ci const bool has_separate_stencil = 1126bf215546Sopenharmony_ci has_depth && fd_resource(pfb->zsbuf->texture)->stencil; 1127bf215546Sopenharmony_ci 1128bf215546Sopenharmony_ci /* First clear depth or combined depth/stencil. */ 1129bf215546Sopenharmony_ci if ((has_depth && (buffers & PIPE_CLEAR_DEPTH)) || 1130bf215546Sopenharmony_ci (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) { 1131bf215546Sopenharmony_ci enum pipe_format pfmt = pfb->zsbuf->format; 1132bf215546Sopenharmony_ci uint32_t clear_value; 1133bf215546Sopenharmony_ci uint32_t mask = 0; 1134bf215546Sopenharmony_ci 1135bf215546Sopenharmony_ci if (has_separate_stencil) { 1136bf215546Sopenharmony_ci pfmt = util_format_get_depth_only(pfb->zsbuf->format); 1137bf215546Sopenharmony_ci clear_value = util_pack_z(pfmt, batch->clear_depth); 1138bf215546Sopenharmony_ci } else { 1139bf215546Sopenharmony_ci pfmt = pfb->zsbuf->format; 1140bf215546Sopenharmony_ci clear_value = 1141bf215546Sopenharmony_ci util_pack_z_stencil(pfmt, batch->clear_depth, batch->clear_stencil); 1142bf215546Sopenharmony_ci } 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_DEPTH) 1145bf215546Sopenharmony_ci mask |= 0x1; 1146bf215546Sopenharmony_ci 1147bf215546Sopenharmony_ci if (!has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) 1148bf215546Sopenharmony_ci mask |= 0x2; 1149bf215546Sopenharmony_ci 1150bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1); 1151bf215546Sopenharmony_ci OUT_RING(ring, 1152bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) | 1153bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) | 1154bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_color_format(pfmt, TILE6_LINEAR))); 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1); 1157bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_BLIT_INFO_GMEM | 1158bf215546Sopenharmony_ci // XXX UNK0 for separate stencil ?? 1159bf215546Sopenharmony_ci A6XX_RB_BLIT_INFO_DEPTH | 1160bf215546Sopenharmony_ci A6XX_RB_BLIT_INFO_CLEAR_MASK(mask)); 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1); 1163bf215546Sopenharmony_ci OUT_RING(ring, gmem->zsbuf_base[0]); 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_88D0, 1); 1166bf215546Sopenharmony_ci OUT_RING(ring, 0); 1167bf215546Sopenharmony_ci 1168bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1); 1169bf215546Sopenharmony_ci OUT_RING(ring, clear_value); 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_ci fd6_emit_blit(batch, ring); 1172bf215546Sopenharmony_ci } 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci /* Then clear the separate stencil buffer in case of 32 bit depth 1175bf215546Sopenharmony_ci * formats with separate stencil. */ 1176bf215546Sopenharmony_ci if (has_separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) { 1177bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1); 1178bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) | 1179bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) | 1180bf215546Sopenharmony_ci A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(FMT6_8_UINT)); 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1); 1183bf215546Sopenharmony_ci OUT_RING(ring, A6XX_RB_BLIT_INFO_GMEM | 1184bf215546Sopenharmony_ci // A6XX_RB_BLIT_INFO_UNK0 | 1185bf215546Sopenharmony_ci A6XX_RB_BLIT_INFO_DEPTH | 1186bf215546Sopenharmony_ci A6XX_RB_BLIT_INFO_CLEAR_MASK(0x1)); 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_BASE_GMEM, 1); 1189bf215546Sopenharmony_ci OUT_RING(ring, gmem->zsbuf_base[1]); 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_UNKNOWN_88D0, 1); 1192bf215546Sopenharmony_ci OUT_RING(ring, 0); 1193bf215546Sopenharmony_ci 1194bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_CLEAR_COLOR_DW0, 1); 1195bf215546Sopenharmony_ci OUT_RING(ring, batch->clear_stencil & 0xff); 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci fd6_emit_blit(batch, ring); 1198bf215546Sopenharmony_ci } 1199bf215546Sopenharmony_ci} 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_ci/* 1202bf215546Sopenharmony_ci * transfer from system memory to gmem 1203bf215546Sopenharmony_ci */ 1204bf215546Sopenharmony_cistatic void 1205bf215546Sopenharmony_ciemit_restore_blits(struct fd_batch *batch, struct fd_ringbuffer *ring) 1206bf215546Sopenharmony_ci{ 1207bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 1208bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_ci if (batch->restore & FD_BUFFER_COLOR) { 1211bf215546Sopenharmony_ci unsigned i; 1212bf215546Sopenharmony_ci for (i = 0; i < pfb->nr_cbufs; i++) { 1213bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 1214bf215546Sopenharmony_ci continue; 1215bf215546Sopenharmony_ci if (!(batch->restore & (PIPE_CLEAR_COLOR0 << i))) 1216bf215546Sopenharmony_ci continue; 1217bf215546Sopenharmony_ci emit_restore_blit(batch, ring, gmem->cbuf_base[i], pfb->cbufs[i], 1218bf215546Sopenharmony_ci FD_BUFFER_COLOR); 1219bf215546Sopenharmony_ci } 1220bf215546Sopenharmony_ci } 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci if (batch->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { 1223bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture); 1224bf215546Sopenharmony_ci 1225bf215546Sopenharmony_ci if (!rsc->stencil || (batch->restore & FD_BUFFER_DEPTH)) { 1226bf215546Sopenharmony_ci emit_restore_blit(batch, ring, gmem->zsbuf_base[0], pfb->zsbuf, 1227bf215546Sopenharmony_ci FD_BUFFER_DEPTH); 1228bf215546Sopenharmony_ci } 1229bf215546Sopenharmony_ci if (rsc->stencil && (batch->restore & FD_BUFFER_STENCIL)) { 1230bf215546Sopenharmony_ci emit_restore_blit(batch, ring, gmem->zsbuf_base[1], pfb->zsbuf, 1231bf215546Sopenharmony_ci FD_BUFFER_STENCIL); 1232bf215546Sopenharmony_ci } 1233bf215546Sopenharmony_ci } 1234bf215546Sopenharmony_ci} 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_cistatic void 1237bf215546Sopenharmony_ciprepare_tile_setup_ib(struct fd_batch *batch) 1238bf215546Sopenharmony_ci{ 1239bf215546Sopenharmony_ci if (!(batch->restore || batch->fast_cleared)) 1240bf215546Sopenharmony_ci return; 1241bf215546Sopenharmony_ci 1242bf215546Sopenharmony_ci batch->tile_setup = 1243bf215546Sopenharmony_ci fd_submit_new_ringbuffer(batch->submit, 0x1000, FD_RINGBUFFER_STREAMING); 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci set_blit_scissor(batch, batch->tile_setup); 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci emit_restore_blits(batch, batch->tile_setup); 1248bf215546Sopenharmony_ci emit_clears(batch, batch->tile_setup); 1249bf215546Sopenharmony_ci} 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci/* 1252bf215546Sopenharmony_ci * transfer from system memory to gmem 1253bf215546Sopenharmony_ci */ 1254bf215546Sopenharmony_cistatic void 1255bf215546Sopenharmony_cifd6_emit_tile_mem2gmem(struct fd_batch *batch, const struct fd_tile *tile) 1256bf215546Sopenharmony_ci{ 1257bf215546Sopenharmony_ci} 1258bf215546Sopenharmony_ci 1259bf215546Sopenharmony_ci/* before IB to rendering cmds: */ 1260bf215546Sopenharmony_cistatic void 1261bf215546Sopenharmony_cifd6_emit_tile_renderprep(struct fd_batch *batch, const struct fd_tile *tile) 1262bf215546Sopenharmony_ci{ 1263bf215546Sopenharmony_ci if (!batch->tile_setup) 1264bf215546Sopenharmony_ci return; 1265bf215546Sopenharmony_ci 1266bf215546Sopenharmony_ci trace_start_clear_restore(&batch->trace, batch->gmem, batch->fast_cleared); 1267bf215546Sopenharmony_ci if (batch->fast_cleared || !use_hw_binning(batch)) { 1268bf215546Sopenharmony_ci fd6_emit_ib(batch->gmem, batch->tile_setup); 1269bf215546Sopenharmony_ci } else { 1270bf215546Sopenharmony_ci emit_conditional_ib(batch, tile, batch->tile_setup); 1271bf215546Sopenharmony_ci } 1272bf215546Sopenharmony_ci trace_end_clear_restore(&batch->trace, batch->gmem); 1273bf215546Sopenharmony_ci} 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_cistatic bool 1276bf215546Sopenharmony_ciblit_can_resolve(enum pipe_format format) 1277bf215546Sopenharmony_ci{ 1278bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_ci /* blit event can only do resolve for simple cases: 1281bf215546Sopenharmony_ci * averaging samples as unsigned integers or choosing only one sample 1282bf215546Sopenharmony_ci */ 1283bf215546Sopenharmony_ci if (util_format_is_snorm(format) || util_format_is_srgb(format)) 1284bf215546Sopenharmony_ci return false; 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci /* can't do formats with larger channel sizes 1287bf215546Sopenharmony_ci * note: this includes all float formats 1288bf215546Sopenharmony_ci * note2: single channel integer formats seem OK 1289bf215546Sopenharmony_ci */ 1290bf215546Sopenharmony_ci if (desc->channel[0].size > 10) 1291bf215546Sopenharmony_ci return false; 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci switch (format) { 1294bf215546Sopenharmony_ci /* for unknown reasons blit event can't msaa resolve these formats when tiled 1295bf215546Sopenharmony_ci * likely related to these formats having different layout from other cpp=2 1296bf215546Sopenharmony_ci * formats 1297bf215546Sopenharmony_ci */ 1298bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8_UNORM: 1299bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8_UINT: 1300bf215546Sopenharmony_ci case PIPE_FORMAT_R8G8_SINT: 1301bf215546Sopenharmony_ci /* TODO: this one should be able to work? */ 1302bf215546Sopenharmony_ci case PIPE_FORMAT_Z24_UNORM_S8_UINT: 1303bf215546Sopenharmony_ci return false; 1304bf215546Sopenharmony_ci default: 1305bf215546Sopenharmony_ci break; 1306bf215546Sopenharmony_ci } 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_ci return true; 1309bf215546Sopenharmony_ci} 1310bf215546Sopenharmony_ci 1311bf215546Sopenharmony_cistatic bool 1312bf215546Sopenharmony_cineeds_resolve(struct pipe_surface *psurf) 1313bf215546Sopenharmony_ci{ 1314bf215546Sopenharmony_ci return psurf->nr_samples && 1315bf215546Sopenharmony_ci (psurf->nr_samples != psurf->texture->nr_samples); 1316bf215546Sopenharmony_ci} 1317bf215546Sopenharmony_ci 1318bf215546Sopenharmony_ci/** 1319bf215546Sopenharmony_ci * Returns the UNKNOWN_8C01 value for handling partial depth/stencil 1320bf215546Sopenharmony_ci * clear/stores to Z24S8. 1321bf215546Sopenharmony_ci */ 1322bf215546Sopenharmony_cistatic uint32_t 1323bf215546Sopenharmony_cifd6_unknown_8c01(enum pipe_format format, unsigned buffers) 1324bf215546Sopenharmony_ci{ 1325bf215546Sopenharmony_ci if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) { 1326bf215546Sopenharmony_ci if (buffers == FD_BUFFER_DEPTH) 1327bf215546Sopenharmony_ci return 0x08000041; 1328bf215546Sopenharmony_ci else if (buffers == FD_BUFFER_STENCIL) 1329bf215546Sopenharmony_ci return 0x00084001; 1330bf215546Sopenharmony_ci } 1331bf215546Sopenharmony_ci return 0; 1332bf215546Sopenharmony_ci} 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_cistatic void 1335bf215546Sopenharmony_ciemit_resolve_blit(struct fd_batch *batch, struct fd_ringbuffer *ring, 1336bf215546Sopenharmony_ci uint32_t base, struct pipe_surface *psurf, 1337bf215546Sopenharmony_ci unsigned buffer) assert_dt 1338bf215546Sopenharmony_ci{ 1339bf215546Sopenharmony_ci uint32_t info = 0; 1340bf215546Sopenharmony_ci bool stencil = false; 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci if (!fd_resource(psurf->texture)->valid) 1343bf215546Sopenharmony_ci return; 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci /* if we need to resolve, but cannot with BLIT event, we instead need 1346bf215546Sopenharmony_ci * to generate per-tile CP_BLIT (r2d) commands: 1347bf215546Sopenharmony_ci * 1348bf215546Sopenharmony_ci * The separate-stencil is a special case, we might need to use CP_BLIT 1349bf215546Sopenharmony_ci * for depth, but we can still resolve stencil with a BLIT event 1350bf215546Sopenharmony_ci */ 1351bf215546Sopenharmony_ci if (needs_resolve(psurf) && !blit_can_resolve(psurf->format) && 1352bf215546Sopenharmony_ci (buffer != FD_BUFFER_STENCIL)) { 1353bf215546Sopenharmony_ci /* We could potentially use fd6_unknown_8c01() to handle partial z/s 1354bf215546Sopenharmony_ci * resolve to packed z/s, but we would need a corresponding ability in the 1355bf215546Sopenharmony_ci * !resolve case below, so batch_draw_tracking_for_dirty_bits() has us 1356bf215546Sopenharmony_ci * just do a restore of the other channel for partial packed z/s writes. 1357bf215546Sopenharmony_ci */ 1358bf215546Sopenharmony_ci fd6_resolve_tile(batch, ring, base, psurf, 0); 1359bf215546Sopenharmony_ci return; 1360bf215546Sopenharmony_ci } 1361bf215546Sopenharmony_ci 1362bf215546Sopenharmony_ci switch (buffer) { 1363bf215546Sopenharmony_ci case FD_BUFFER_COLOR: 1364bf215546Sopenharmony_ci break; 1365bf215546Sopenharmony_ci case FD_BUFFER_STENCIL: 1366bf215546Sopenharmony_ci info |= A6XX_RB_BLIT_INFO_UNK0; 1367bf215546Sopenharmony_ci stencil = true; 1368bf215546Sopenharmony_ci break; 1369bf215546Sopenharmony_ci case FD_BUFFER_DEPTH: 1370bf215546Sopenharmony_ci info |= A6XX_RB_BLIT_INFO_DEPTH; 1371bf215546Sopenharmony_ci break; 1372bf215546Sopenharmony_ci } 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_ci if (util_format_is_pure_integer(psurf->format) || 1375bf215546Sopenharmony_ci util_format_is_depth_or_stencil(psurf->format)) 1376bf215546Sopenharmony_ci info |= A6XX_RB_BLIT_INFO_SAMPLE_0; 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1); 1379bf215546Sopenharmony_ci OUT_RING(ring, info); 1380bf215546Sopenharmony_ci 1381bf215546Sopenharmony_ci emit_blit(batch, ring, base, psurf, stencil); 1382bf215546Sopenharmony_ci} 1383bf215546Sopenharmony_ci 1384bf215546Sopenharmony_ci/* 1385bf215546Sopenharmony_ci * transfer from gmem to system memory (ie. normal RAM) 1386bf215546Sopenharmony_ci */ 1387bf215546Sopenharmony_ci 1388bf215546Sopenharmony_cistatic void 1389bf215546Sopenharmony_ciprepare_tile_fini_ib(struct fd_batch *batch) assert_dt 1390bf215546Sopenharmony_ci{ 1391bf215546Sopenharmony_ci const struct fd_gmem_stateobj *gmem = batch->gmem_state; 1392bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 1393bf215546Sopenharmony_ci struct fd_ringbuffer *ring; 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci batch->tile_fini = 1396bf215546Sopenharmony_ci fd_submit_new_ringbuffer(batch->submit, 0x1000, FD_RINGBUFFER_STREAMING); 1397bf215546Sopenharmony_ci ring = batch->tile_fini; 1398bf215546Sopenharmony_ci 1399bf215546Sopenharmony_ci set_blit_scissor(batch, ring); 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci if (batch->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) { 1402bf215546Sopenharmony_ci struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture); 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci if (!rsc->stencil || (batch->resolve & FD_BUFFER_DEPTH)) { 1405bf215546Sopenharmony_ci emit_resolve_blit(batch, ring, gmem->zsbuf_base[0], pfb->zsbuf, 1406bf215546Sopenharmony_ci FD_BUFFER_DEPTH); 1407bf215546Sopenharmony_ci } 1408bf215546Sopenharmony_ci if (rsc->stencil && (batch->resolve & FD_BUFFER_STENCIL)) { 1409bf215546Sopenharmony_ci emit_resolve_blit(batch, ring, gmem->zsbuf_base[1], pfb->zsbuf, 1410bf215546Sopenharmony_ci FD_BUFFER_STENCIL); 1411bf215546Sopenharmony_ci } 1412bf215546Sopenharmony_ci } 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci if (batch->resolve & FD_BUFFER_COLOR) { 1415bf215546Sopenharmony_ci unsigned i; 1416bf215546Sopenharmony_ci for (i = 0; i < pfb->nr_cbufs; i++) { 1417bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 1418bf215546Sopenharmony_ci continue; 1419bf215546Sopenharmony_ci if (!(batch->resolve & (PIPE_CLEAR_COLOR0 << i))) 1420bf215546Sopenharmony_ci continue; 1421bf215546Sopenharmony_ci emit_resolve_blit(batch, ring, gmem->cbuf_base[i], pfb->cbufs[i], 1422bf215546Sopenharmony_ci FD_BUFFER_COLOR); 1423bf215546Sopenharmony_ci } 1424bf215546Sopenharmony_ci } 1425bf215546Sopenharmony_ci} 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_cistatic void 1428bf215546Sopenharmony_cifd6_emit_tile(struct fd_batch *batch, const struct fd_tile *tile) 1429bf215546Sopenharmony_ci{ 1430bf215546Sopenharmony_ci if (!use_hw_binning(batch)) { 1431bf215546Sopenharmony_ci fd6_emit_ib(batch->gmem, batch->draw); 1432bf215546Sopenharmony_ci } else { 1433bf215546Sopenharmony_ci emit_conditional_ib(batch, tile, batch->draw); 1434bf215546Sopenharmony_ci } 1435bf215546Sopenharmony_ci 1436bf215546Sopenharmony_ci if (batch->epilogue) 1437bf215546Sopenharmony_ci fd6_emit_ib(batch->gmem, batch->epilogue); 1438bf215546Sopenharmony_ci} 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_cistatic void 1441bf215546Sopenharmony_cifd6_emit_tile_gmem2mem(struct fd_batch *batch, const struct fd_tile *tile) 1442bf215546Sopenharmony_ci{ 1443bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 1444bf215546Sopenharmony_ci 1445bf215546Sopenharmony_ci if (use_hw_binning(batch)) { 1446bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MARKER, 1); 1447bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_ENDVIS)); 1448bf215546Sopenharmony_ci } 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_DRAW_STATE, 3); 1451bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__0_COUNT(0) | 1452bf215546Sopenharmony_ci CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS | 1453bf215546Sopenharmony_ci CP_SET_DRAW_STATE__0_GROUP_ID(0)); 1454bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__1_ADDR_LO(0)); 1455bf215546Sopenharmony_ci OUT_RING(ring, CP_SET_DRAW_STATE__2_ADDR_HI(0)); 1456bf215546Sopenharmony_ci 1457bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_LOCAL, 1); 1458bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 1459bf215546Sopenharmony_ci 1460bf215546Sopenharmony_ci emit_marker6(ring, 7); 1461bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MARKER, 1); 1462bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_RESOLVE)); 1463bf215546Sopenharmony_ci emit_marker6(ring, 7); 1464bf215546Sopenharmony_ci 1465bf215546Sopenharmony_ci trace_start_resolve(&batch->trace, batch->gmem); 1466bf215546Sopenharmony_ci if (batch->fast_cleared || !use_hw_binning(batch)) { 1467bf215546Sopenharmony_ci fd6_emit_ib(batch->gmem, batch->tile_fini); 1468bf215546Sopenharmony_ci } else { 1469bf215546Sopenharmony_ci emit_conditional_ib(batch, tile, batch->tile_fini); 1470bf215546Sopenharmony_ci } 1471bf215546Sopenharmony_ci trace_end_resolve(&batch->trace, batch->gmem); 1472bf215546Sopenharmony_ci} 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_cistatic void 1475bf215546Sopenharmony_cifd6_emit_tile_fini(struct fd_batch *batch) 1476bf215546Sopenharmony_ci{ 1477bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 1478bf215546Sopenharmony_ci 1479bf215546Sopenharmony_ci emit_common_fini(batch); 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_CNTL, 1); 1482bf215546Sopenharmony_ci OUT_RING(ring, A6XX_GRAS_LRZ_CNTL_ENABLE); 1483bf215546Sopenharmony_ci 1484bf215546Sopenharmony_ci fd6_emit_lrz_flush(ring); 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci fd6_event_write(batch, ring, PC_CCU_RESOLVE_TS, true); 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci if (use_hw_binning(batch)) { 1489bf215546Sopenharmony_ci check_vsc_overflow(batch->ctx); 1490bf215546Sopenharmony_ci } 1491bf215546Sopenharmony_ci} 1492bf215546Sopenharmony_ci 1493bf215546Sopenharmony_cistatic void 1494bf215546Sopenharmony_ciemit_sysmem_clears(struct fd_batch *batch, struct fd_ringbuffer *ring) assert_dt 1495bf215546Sopenharmony_ci{ 1496bf215546Sopenharmony_ci struct fd_context *ctx = batch->ctx; 1497bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 1498bf215546Sopenharmony_ci 1499bf215546Sopenharmony_ci uint32_t buffers = batch->fast_cleared; 1500bf215546Sopenharmony_ci 1501bf215546Sopenharmony_ci if (!buffers) 1502bf215546Sopenharmony_ci return; 1503bf215546Sopenharmony_ci 1504bf215546Sopenharmony_ci trace_start_clear_restore(&batch->trace, ring, buffers); 1505bf215546Sopenharmony_ci 1506bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR) { 1507bf215546Sopenharmony_ci for (int i = 0; i < pfb->nr_cbufs; i++) { 1508bf215546Sopenharmony_ci union pipe_color_union color = batch->clear_color[i]; 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_ci if (!pfb->cbufs[i]) 1511bf215546Sopenharmony_ci continue; 1512bf215546Sopenharmony_ci 1513bf215546Sopenharmony_ci if (!(buffers & (PIPE_CLEAR_COLOR0 << i))) 1514bf215546Sopenharmony_ci continue; 1515bf215546Sopenharmony_ci 1516bf215546Sopenharmony_ci fd6_clear_surface(ctx, ring, pfb->cbufs[i], pfb->width, pfb->height, 1517bf215546Sopenharmony_ci &color, 0); 1518bf215546Sopenharmony_ci } 1519bf215546Sopenharmony_ci } 1520bf215546Sopenharmony_ci if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) { 1521bf215546Sopenharmony_ci union pipe_color_union value = {}; 1522bf215546Sopenharmony_ci 1523bf215546Sopenharmony_ci const bool has_depth = pfb->zsbuf; 1524bf215546Sopenharmony_ci struct pipe_resource *separate_stencil = 1525bf215546Sopenharmony_ci has_depth && fd_resource(pfb->zsbuf->texture)->stencil 1526bf215546Sopenharmony_ci ? &fd_resource(pfb->zsbuf->texture)->stencil->b.b 1527bf215546Sopenharmony_ci : NULL; 1528bf215546Sopenharmony_ci 1529bf215546Sopenharmony_ci if ((buffers & PIPE_CLEAR_DEPTH) || (!separate_stencil && (buffers & PIPE_CLEAR_STENCIL))) { 1530bf215546Sopenharmony_ci value.f[0] = batch->clear_depth; 1531bf215546Sopenharmony_ci value.ui[1] = batch->clear_stencil; 1532bf215546Sopenharmony_ci fd6_clear_surface(ctx, ring, pfb->zsbuf, pfb->width, pfb->height, 1533bf215546Sopenharmony_ci &value, fd6_unknown_8c01(pfb->zsbuf->format, buffers)); 1534bf215546Sopenharmony_ci } 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci if (separate_stencil && (buffers & PIPE_CLEAR_STENCIL)) { 1537bf215546Sopenharmony_ci value.ui[0] = batch->clear_stencil; 1538bf215546Sopenharmony_ci 1539bf215546Sopenharmony_ci struct pipe_surface stencil_surf = *pfb->zsbuf; 1540bf215546Sopenharmony_ci stencil_surf.format = PIPE_FORMAT_S8_UINT; 1541bf215546Sopenharmony_ci stencil_surf.texture = separate_stencil; 1542bf215546Sopenharmony_ci 1543bf215546Sopenharmony_ci fd6_clear_surface(ctx, ring, &stencil_surf, pfb->width, pfb->height, 1544bf215546Sopenharmony_ci &value, 0); 1545bf215546Sopenharmony_ci } 1546bf215546Sopenharmony_ci } 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_ci fd6_event_write(batch, ring, PC_CCU_FLUSH_COLOR_TS, true); 1549bf215546Sopenharmony_ci fd_wfi(batch, ring); 1550bf215546Sopenharmony_ci 1551bf215546Sopenharmony_ci trace_end_clear_restore(&batch->trace, ring); 1552bf215546Sopenharmony_ci} 1553bf215546Sopenharmony_ci 1554bf215546Sopenharmony_cistatic void 1555bf215546Sopenharmony_cifd6_emit_sysmem_prep(struct fd_batch *batch) assert_dt 1556bf215546Sopenharmony_ci{ 1557bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 1558bf215546Sopenharmony_ci struct fd_screen *screen = batch->ctx->screen; 1559bf215546Sopenharmony_ci 1560bf215546Sopenharmony_ci fd6_emit_restore(batch, ring); 1561bf215546Sopenharmony_ci fd6_emit_lrz_flush(ring); 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_ci if (batch->prologue) { 1564bf215546Sopenharmony_ci if (!batch->nondraw) { 1565bf215546Sopenharmony_ci trace_start_prologue(&batch->trace, ring); 1566bf215546Sopenharmony_ci } 1567bf215546Sopenharmony_ci fd6_emit_ib(ring, batch->prologue); 1568bf215546Sopenharmony_ci if (!batch->nondraw) { 1569bf215546Sopenharmony_ci trace_end_prologue(&batch->trace, ring); 1570bf215546Sopenharmony_ci } 1571bf215546Sopenharmony_ci } 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_ci /* remaining setup below here does not apply to blit/compute: */ 1574bf215546Sopenharmony_ci if (batch->nondraw) 1575bf215546Sopenharmony_ci return; 1576bf215546Sopenharmony_ci 1577bf215546Sopenharmony_ci struct pipe_framebuffer_state *pfb = &batch->framebuffer; 1578bf215546Sopenharmony_ci 1579bf215546Sopenharmony_ci if (pfb->width > 0 && pfb->height > 0) 1580bf215546Sopenharmony_ci set_scissor(ring, 0, 0, pfb->width - 1, pfb->height - 1); 1581bf215546Sopenharmony_ci else 1582bf215546Sopenharmony_ci set_scissor(ring, 0, 0, 0, 0); 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_ci set_window_offset(ring, 0, 0); 1585bf215546Sopenharmony_ci 1586bf215546Sopenharmony_ci set_bin_size(ring, 0, 0, 0xc00000); /* 0xc00000 = BYPASS? */ 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_ci emit_sysmem_clears(batch, ring); 1589bf215546Sopenharmony_ci 1590bf215546Sopenharmony_ci emit_marker6(ring, 7); 1591bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_MARKER, 1); 1592bf215546Sopenharmony_ci OUT_RING(ring, A6XX_CP_SET_MARKER_0_MODE(RM6_BYPASS)); 1593bf215546Sopenharmony_ci emit_marker6(ring, 7); 1594bf215546Sopenharmony_ci 1595bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1); 1596bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 1597bf215546Sopenharmony_ci 1598bf215546Sopenharmony_ci /* blob controls "local" in IB2, but I think that is not required */ 1599bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_LOCAL, 1); 1600bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 1601bf215546Sopenharmony_ci 1602bf215546Sopenharmony_ci fd6_event_write(batch, ring, PC_CCU_INVALIDATE_COLOR, false); 1603bf215546Sopenharmony_ci fd6_cache_inv(batch, ring); 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ci fd_wfi(batch, ring); 1606bf215546Sopenharmony_ci OUT_REG(ring, A6XX_RB_CCU_CNTL(.color_offset = screen->ccu_offset_bypass)); 1607bf215546Sopenharmony_ci 1608bf215546Sopenharmony_ci /* enable stream-out, with sysmem there is only one pass: */ 1609bf215546Sopenharmony_ci OUT_REG(ring, A6XX_VPC_SO_DISABLE(false)); 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SET_VISIBILITY_OVERRIDE, 1); 1612bf215546Sopenharmony_ci OUT_RING(ring, 0x1); 1613bf215546Sopenharmony_ci 1614bf215546Sopenharmony_ci emit_zs(ring, pfb->zsbuf, NULL); 1615bf215546Sopenharmony_ci emit_mrt(ring, pfb, NULL); 1616bf215546Sopenharmony_ci emit_msaa(ring, pfb->samples); 1617bf215546Sopenharmony_ci patch_fb_read_sysmem(batch); 1618bf215546Sopenharmony_ci 1619bf215546Sopenharmony_ci update_render_cntl(batch, pfb, false); 1620bf215546Sopenharmony_ci 1621bf215546Sopenharmony_ci emit_common_init(batch); 1622bf215546Sopenharmony_ci} 1623bf215546Sopenharmony_ci 1624bf215546Sopenharmony_cistatic void 1625bf215546Sopenharmony_cifd6_emit_sysmem_fini(struct fd_batch *batch) assert_dt 1626bf215546Sopenharmony_ci{ 1627bf215546Sopenharmony_ci struct fd_ringbuffer *ring = batch->gmem; 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci emit_common_fini(batch); 1630bf215546Sopenharmony_ci 1631bf215546Sopenharmony_ci if (batch->epilogue) 1632bf215546Sopenharmony_ci fd6_emit_ib(batch->gmem, batch->epilogue); 1633bf215546Sopenharmony_ci 1634bf215546Sopenharmony_ci OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1); 1635bf215546Sopenharmony_ci OUT_RING(ring, 0x0); 1636bf215546Sopenharmony_ci 1637bf215546Sopenharmony_ci fd6_emit_lrz_flush(ring); 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_ci fd6_event_write(batch, ring, PC_CCU_FLUSH_COLOR_TS, true); 1640bf215546Sopenharmony_ci fd6_event_write(batch, ring, PC_CCU_FLUSH_DEPTH_TS, true); 1641bf215546Sopenharmony_ci fd_wfi(batch, ring); 1642bf215546Sopenharmony_ci} 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_civoid 1645bf215546Sopenharmony_cifd6_gmem_init(struct pipe_context *pctx) disable_thread_safety_analysis 1646bf215546Sopenharmony_ci{ 1647bf215546Sopenharmony_ci struct fd_context *ctx = fd_context(pctx); 1648bf215546Sopenharmony_ci 1649bf215546Sopenharmony_ci ctx->emit_tile_init = fd6_emit_tile_init; 1650bf215546Sopenharmony_ci ctx->emit_tile_prep = fd6_emit_tile_prep; 1651bf215546Sopenharmony_ci ctx->emit_tile_mem2gmem = fd6_emit_tile_mem2gmem; 1652bf215546Sopenharmony_ci ctx->emit_tile_renderprep = fd6_emit_tile_renderprep; 1653bf215546Sopenharmony_ci ctx->emit_tile = fd6_emit_tile; 1654bf215546Sopenharmony_ci ctx->emit_tile_gmem2mem = fd6_emit_tile_gmem2mem; 1655bf215546Sopenharmony_ci ctx->emit_tile_fini = fd6_emit_tile_fini; 1656bf215546Sopenharmony_ci ctx->emit_sysmem_prep = fd6_emit_sysmem_prep; 1657bf215546Sopenharmony_ci ctx->emit_sysmem_fini = fd6_emit_sysmem_fini; 1658bf215546Sopenharmony_ci} 1659