/* emit texture state for mem->gmem restore operation.. eventually it would * be good to get rid of this and use normal CSO/etc state for more of these * special cases.. */ void fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf) { struct fd_resource *rsc = fd_resource(psurf->texture); unsigned lvl = psurf->u.tex.level; struct fd_resource_slice *slice = fd_resource_slice(rsc, lvl); uint32_t offset = fd_resource_offset(rsc, lvl, psurf->u.tex.first_layer); enum pipe_format format = fd4_gmem_restore_format(psurf->format); debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer); /* output sampler state: */ OUT_PKT3(ring, CP_LOAD_STATE, 4); OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) | CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | CP_LOAD_STATE_0_STATE_BLOCK(SB_FRAG_TEX) | CP_LOAD_STATE_0_NUM_UNIT(1)); OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) | CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); OUT_RING(ring, A4XX_TEX_SAMP_0_XY_MAG(A4XX_TEX_NEAREST) | A4XX_TEX_SAMP_0_XY_MIN(A4XX_TEX_NEAREST) | A4XX_TEX_SAMP_0_WRAP_S(A4XX_TEX_CLAMP_TO_EDGE) | A4XX_TEX_SAMP_0_WRAP_T(A4XX_TEX_CLAMP_TO_EDGE) | A4XX_TEX_SAMP_0_WRAP_R(A4XX_TEX_REPEAT)); OUT_RING(ring, 0x00000000); /* emit texture state: */ OUT_PKT3(ring, CP_LOAD_STATE, 10); OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(0) | CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) | CP_LOAD_STATE_0_STATE_BLOCK(SB_FRAG_TEX) | CP_LOAD_STATE_0_NUM_UNIT(1)); OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) | CP_LOAD_STATE_1_EXT_SRC_ADDR(0)); OUT_RING(ring, A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(format)) | A4XX_TEX_CONST_0_TYPE(A4XX_TEX_2D) | fd4_tex_swiz(format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA)); OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(psurf->width) | A4XX_TEX_CONST_1_HEIGHT(psurf->height)); OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(slice->pitch * rsc->cpp)); OUT_RING(ring, 0x00000000); OUT_RELOC(ring, rsc->bo, offset, 0, 0); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000); }
static void * fd4_sampler_state_create(struct pipe_context *pctx, const struct pipe_sampler_state *cso) { struct fd4_sampler_stateobj *so = CALLOC_STRUCT(fd4_sampler_stateobj); unsigned aniso = util_last_bit(MIN2(cso->max_anisotropy >> 1, 8)); bool miplinear = false; if (!so) return NULL; if (cso->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) miplinear = true; so->base = *cso; so->texsamp0 = COND(miplinear, A4XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) | A4XX_TEX_SAMP_0_XY_MAG(tex_filter(cso->mag_img_filter, aniso)) | A4XX_TEX_SAMP_0_XY_MIN(tex_filter(cso->min_img_filter, aniso)) | A4XX_TEX_SAMP_0_ANISO(aniso) | A4XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s)) | A4XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t)) | A4XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r)); so->texsamp1 = // COND(miplinear, A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR) | COND(!cso->normalized_coords, A4XX_TEX_SAMP_1_UNNORM_COORDS); if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) { so->texsamp0 |= A4XX_TEX_SAMP_0_LOD_BIAS(cso->lod_bias); so->texsamp1 |= A4XX_TEX_SAMP_1_MIN_LOD(cso->min_lod) | A4XX_TEX_SAMP_1_MAX_LOD(cso->max_lod); } if (cso->compare_mode) so->texsamp1 |= A4XX_TEX_SAMP_1_COMPARE_FUNC(cso->compare_func); /* maps 1:1 */ return so; }