static void emit_gmem2mem_surf(struct fd_ringbuffer *ring, enum adreno_rb_copy_control_mode mode, uint32_t base, struct pipe_surface *psurf) { struct fd_resource *rsc = fd_resource(psurf->texture); OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4); OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) | A3XX_RB_COPY_CONTROL_MODE(mode) | A3XX_RB_COPY_CONTROL_GMEM_BASE(base)); OUT_RELOCW(ring, rsc->bo, 0, 0, -1); /* RB_COPY_DEST_BASE */ OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(rsc->pitch * rsc->cpp)); OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) | A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) | A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) | A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) | A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(psurf->format))); OUT_PKT3(ring, CP_DRAW_INDX, 3); OUT_RING(ring, 0x00000000); OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX, INDEX_SIZE_IGN, IGNORE_VISIBILITY)); OUT_RING(ring, 2); /* NumIndices */ }
static void emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w) { enum a3xx_tile_mode tile_mode; unsigned i; if (bin_w) { tile_mode = TILE_32X32; } else { tile_mode = LINEAR; } for (i = 0; i < 4; i++) { enum a3xx_color_fmt format = 0; enum a3xx_color_swap swap = WZYX; struct fd_resource *rsc = NULL; struct fd_resource_slice *slice = NULL; uint32_t stride = 0; uint32_t base = 0; if ((i < nr_bufs) && bufs[i]) { struct pipe_surface *psurf = bufs[i]; rsc = fd_resource(psurf->texture); slice = &rsc->slices[psurf->u.tex.level]; format = fd3_pipe2color(psurf->format); swap = fd3_pipe2swap(psurf->format); if (bin_w) { stride = bin_w * rsc->cpp; if (bases) { base = bases[i]; } } else { stride = slice->pitch * rsc->cpp; } } OUT_PKT0(ring, REG_A3XX_RB_MRT_BUF_INFO(i), 2); OUT_RING(ring, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) | A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) | A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) | A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap)); if (bin_w || (i >= nr_bufs)) { OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base)); } else { OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1); } OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1); OUT_RING(ring, A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(format)); } }
enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format) { if (util_format_is_srgb(format)) return RB_R16G16B16A16_FLOAT; switch (format) { case PIPE_FORMAT_R16_FLOAT: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R11G11B10_FLOAT: return RB_R16G16B16A16_FLOAT; case PIPE_FORMAT_L8_UNORM: return RB_R8G8B8A8_UNORM; default: return fd3_pipe2color(format); } }
static boolean fd3_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned usage) { unsigned retval = 0; if ((target >= PIPE_MAX_TEXTURE_TYPES) || (sample_count > 1) || /* TODO add MSAA */ !util_format_is_supported(format, usage)) { DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x", util_format_name(format), target, sample_count, usage); return FALSE; } if ((usage & PIPE_BIND_VERTEX_BUFFER) && (fd3_pipe2vtx(format) != (enum a3xx_vtx_fmt)~0)) { retval |= PIPE_BIND_VERTEX_BUFFER; } if ((usage & PIPE_BIND_SAMPLER_VIEW) && (fd3_pipe2tex(format) != (enum a3xx_tex_fmt)~0)) { retval |= PIPE_BIND_SAMPLER_VIEW; } if ((usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_BLENDABLE)) && (fd3_pipe2color(format) != (enum a3xx_color_fmt)~0) && (fd3_pipe2tex(format) != (enum a3xx_tex_fmt)~0)) { retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); if (!util_format_is_pure_integer(format)) retval |= usage & PIPE_BIND_BLENDABLE; } if ((usage & PIPE_BIND_DEPTH_STENCIL) && (fd_pipe2depth(format) != (enum adreno_rb_depth_format)~0) && (fd3_pipe2tex(format) != (enum a3xx_tex_fmt)~0)) { retval |= PIPE_BIND_DEPTH_STENCIL; } if ((usage & PIPE_BIND_INDEX_BUFFER) && (fd_pipe2index(format) != (enum pc_di_index_size)~0)) { retval |= PIPE_BIND_INDEX_BUFFER; } if (usage & PIPE_BIND_TRANSFER_READ) retval |= PIPE_BIND_TRANSFER_READ; if (usage & PIPE_BIND_TRANSFER_WRITE) retval |= PIPE_BIND_TRANSFER_WRITE; if (retval != usage) { DBG("not supported: format=%s, target=%d, sample_count=%d, " "usage=%x, retval=%x", util_format_name(format), target, sample_count, usage, retval); } return retval == usage; }