From: Rob Clark Date: Sat, 31 Aug 2013 13:14:27 +0000 (-0400) Subject: freedreno: multi-slice resources (cubemap, mipmap, etc) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb9e07aa84ff2dd8492fd8a7064ff2539d7d40f9;p=mesa.git freedreno: multi-slice resources (cubemap, mipmap, etc) Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h b/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h index 35463864b95..140d3f4ae5f 100644 --- a/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h +++ b/src/gallium/drivers/freedreno/a2xx/a2xx.xml.h @@ -4,16 +4,16 @@ /* Autogenerated file, DO NOT EDIT manually! This file was generated by the rules-ng-ng headergen tool in this git repository: -http://0x04.net/cgit/index.cgi/rules-ng-ng -git clone git://0x04.net/rules-ng-ng +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48) - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36) -- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37) -- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05) +- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-06 12:50:15) +- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51536 bytes, from 2013-09-08 13:18:17) Copyright (C) 2013 by the following authors: - Rob Clark (robclark) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c index 89f5a4d5259..2c34b8af28a 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -71,7 +71,7 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base, OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL)); OUT_RING(ring, 0x00000000); /* RB_COPY_CONTROL */ OUT_RELOCW(ring, rsc->bo, 0, 0, 0); /* RB_COPY_DEST_BASE */ - OUT_RING(ring, rsc->pitch >> 5); /* RB_COPY_DEST_PITCH */ + OUT_RING(ring, rsc->slices[0].pitch >> 5); /* RB_COPY_DEST_PITCH */ OUT_RING(ring, /* RB_COPY_DEST_INFO */ A2XX_RB_COPY_DEST_INFO_FORMAT(fd2_pipe2color(psurf->format)) | A2XX_RB_COPY_DEST_INFO_LINEAR | @@ -197,7 +197,7 @@ emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base, OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) | - A2XX_SQ_TEX_0_PITCH(rsc->pitch)); + A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch)); OUT_RELOC(ring, rsc->bo, 0, fd2_pipe2surface(psurf->format) | 0x800, 0); OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) | diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c index c800a869868..870694c2a15 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_texture.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_texture.c @@ -120,7 +120,7 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, so->tex_resource = rsc; so->fmt = fd2_pipe2surface(cso->format); - so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->pitch); + so->tex0 = A2XX_SQ_TEX_0_PITCH(rsc->slices[0].pitch); so->tex2 = A2XX_SQ_TEX_2_HEIGHT(prsc->height0 - 1) | A2XX_SQ_TEX_2_WIDTH(prsc->width0 - 1); diff --git a/src/gallium/drivers/freedreno/a3xx/a3xx.xml.h b/src/gallium/drivers/freedreno/a3xx/a3xx.xml.h index d183516067b..834361b837d 100644 --- a/src/gallium/drivers/freedreno/a3xx/a3xx.xml.h +++ b/src/gallium/drivers/freedreno/a3xx/a3xx.xml.h @@ -4,16 +4,16 @@ /* Autogenerated file, DO NOT EDIT manually! This file was generated by the rules-ng-ng headergen tool in this git repository: -http://0x04.net/cgit/index.cgi/rules-ng-ng -git clone git://0x04.net/rules-ng-ng +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48) - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36) -- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37) -- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05) +- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-06 12:50:15) +- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51536 bytes, from 2013-09-08 13:18:17) Copyright (C) 2013 by the following authors: - Rob Clark (robclark) @@ -2074,6 +2074,7 @@ static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_op #define REG_A3XX_TP_PERFCOUNTER5_SELECT 0x00000f09 #define REG_A3XX_TEX_SAMP_0 0x00000000 +#define A3XX_TEX_SAMP_0_MIPFILTER_LINEAR 0x00000002 #define A3XX_TEX_SAMP_0_XY_MAG__MASK 0x0000000c #define A3XX_TEX_SAMP_0_XY_MAG__SHIFT 2 static inline uint32_t A3XX_TEX_SAMP_0_XY_MAG(enum a3xx_tex_filter val) @@ -2134,6 +2135,12 @@ static inline uint32_t A3XX_TEX_CONST_0_SWIZ_W(enum a3xx_tex_swiz val) { return ((val) << A3XX_TEX_CONST_0_SWIZ_W__SHIFT) & A3XX_TEX_CONST_0_SWIZ_W__MASK; } +#define A3XX_TEX_CONST_0_MIPLVLS__MASK 0x000f0000 +#define A3XX_TEX_CONST_0_MIPLVLS__SHIFT 16 +static inline uint32_t A3XX_TEX_CONST_0_MIPLVLS(uint32_t val) +{ + return ((val) << A3XX_TEX_CONST_0_MIPLVLS__SHIFT) & A3XX_TEX_CONST_0_MIPLVLS__MASK; +} #define A3XX_TEX_CONST_0_FMT__MASK 0x1fc00000 #define A3XX_TEX_CONST_0_FMT__SHIFT 22 static inline uint32_t A3XX_TEX_CONST_0_FMT(enum a3xx_tex_fmt val) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c index 51154113de6..994f71c0d2c 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c @@ -824,8 +824,10 @@ trans_samp(const struct instr_translater *t, break; } - if (tex == TGSI_TEXTURE_3D) + if ((tex == TGSI_TEXTURE_3D) || (tex == TGSI_TEXTURE_CUBE)) { + ir3_instr_create(ctx->ir, 0, OPC_NOP)->repeat = 2; // XXX ??? flags |= IR3_INSTR_3D; + } /* The texture sample instructions need to coord in successive * registers/components (ie. src.xy but not src.yx). And TXP diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index 5e586185ad9..66dc4a8d0bf 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -146,7 +146,7 @@ emit_constants(struct fd_ringbuffer *ring, #define VERT_TEX_OFF 0 #define FRAG_TEX_OFF 16 -#define BASETABLE_SZ 14 +#define BASETABLE_SZ A3XX_MAX_MIP_LEVELS static void emit_textures(struct fd_ringbuffer *ring, @@ -212,12 +212,15 @@ emit_textures(struct fd_ringbuffer *ring, for (i = 0; i < tex->num_textures; i++) { struct fd3_pipe_sampler_view *view = fd3_pipe_sampler_view(tex->textures[i]); - OUT_RELOC(ring, view->tex_resource->bo, 0, 0, 0); - /* I think each entry is a ptr to mipmap level.. for now, just - * pad w/ null's until I get around to actually implementing - * mipmap support.. - */ - for (j = 1; j < BASETABLE_SZ; j++) { + struct fd_resource *rsc = view->tex_resource; + + for (j = 0; j < view->mipaddrs; j++) { + struct fd_resource_slice *slice = fd_resource_slice(rsc, j); + OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0); + } + + /* pad the remaining entries w/ null: */ + for (; j < BASETABLE_SZ; j++) { OUT_RING(ring, 0x00000000); } } @@ -284,7 +287,7 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf OUT_RING(ring, A3XX_TEX_CONST_1_FETCHSIZE(TFETCH_DISABLE) | A3XX_TEX_CONST_1_WIDTH(psurf->width) | A3XX_TEX_CONST_1_HEIGHT(psurf->height)); - OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(rsc->pitch * rsc->cpp) | + OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp) | A3XX_TEX_CONST_2_INDX(0)); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index 8d2df47c72a..cdc880ed562 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -59,25 +59,27 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, for (i = 0; i < 4; i++) { enum a3xx_color_fmt format = 0; enum a3xx_color_swap swap = WZYX; - struct fd_resource *res = NULL; + struct fd_resource *rsc = NULL; + struct fd_resource_slice *slice = NULL; uint32_t stride = 0; uint32_t base = 0; if (i < nr_bufs) { struct pipe_surface *psurf = bufs[i]; - res = fd_resource(psurf->texture); + 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 * res->cpp; + stride = bin_w * rsc->cpp; if (bases) { - base = bases[i] * res->cpp; + base = bases[i] * rsc->cpp; } } else { - stride = res->pitch * res->cpp; + stride = slice->pitch * rsc->cpp; } } @@ -89,7 +91,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, if (bin_w || (i >= nr_bufs)) { OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base)); } else { - OUT_RELOCW(ring, res->bo, 0, 0, -1); + OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1); } OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1); @@ -111,13 +113,14 @@ emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base, struct pipe_surface *psurf) { struct fd_resource *rsc = fd_resource(psurf->texture); + struct fd_resource_slice *slice = &rsc->slices[psurf->u.tex.level]; 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_RELOCW(ring, rsc->bo, slice->offset, 0, -1); /* RB_COPY_DEST_BASE */ + OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(slice->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) | @@ -418,7 +421,7 @@ fd3_emit_sysmem_prep(struct fd_context *ctx) uint32_t pitch = 0; if (pfb->cbufs[0]) - pitch = fd_resource(pfb->cbufs[0]->texture)->pitch; + pitch = fd_resource(pfb->cbufs[0]->texture)->slices[0].pitch; fd3_emit_restore(ctx); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c index e56325ba1f1..a44ac46beb1 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c @@ -80,20 +80,34 @@ fd3_sampler_state_create(struct pipe_context *pctx, const struct pipe_sampler_state *cso) { struct fd3_sampler_stateobj *so = CALLOC_STRUCT(fd3_sampler_stateobj); + bool miplinear = false; if (!so) return NULL; + if (cso->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) + miplinear = true; + so->base = *cso; so->texsamp0 = COND(!cso->normalized_coords, A3XX_TEX_SAMP_0_UNNORM_COORDS) | + COND(miplinear, A3XX_TEX_SAMP_0_MIPFILTER_LINEAR) | A3XX_TEX_SAMP_0_XY_MAG(tex_filter(cso->mag_img_filter)) | A3XX_TEX_SAMP_0_XY_MIN(tex_filter(cso->min_img_filter)) | A3XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s)) | A3XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t)) | A3XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r)); - so->texsamp1 = 0x00000000; /* ??? */ + + /* when mip-map is not disabled, this gets set.. I guess possibly + * it is the LOD related params, but I think I need GLES3 blob driver + * to be able to tell.. + */ + if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) { + so->texsamp1 = 0x003ff000; + } else { + so->texsamp1 = 0x00000000; + } return so; } @@ -126,6 +140,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, { struct fd3_pipe_sampler_view *so = CALLOC_STRUCT(fd3_pipe_sampler_view); struct fd_resource *rsc = fd_resource(prsc); + unsigned miplevels = cso->u.tex.last_level - cso->u.tex.first_level; if (!so) return NULL; @@ -137,10 +152,12 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, so->base.context = pctx; so->tex_resource = rsc; + so->mipaddrs = 1 + miplevels; so->texconst0 = A3XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) | A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(cso->format)) | + A3XX_TEX_CONST_0_MIPLVLS(miplevels) | fd3_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g, cso->swizzle_b, cso->swizzle_a); so->texconst1 = @@ -149,7 +166,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc, A3XX_TEX_CONST_1_HEIGHT(prsc->height0); /* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */ so->texconst2 = - A3XX_TEX_CONST_2_PITCH(rsc->pitch * rsc->cpp); + A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp); so->texconst3 = 0x00000000; /* ??? */ return &so->base; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.h b/src/gallium/drivers/freedreno/a3xx/fd3_texture.h index a83f527366b..f7e5f0e650f 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.h @@ -51,6 +51,7 @@ fd3_sampler_stateobj(struct pipe_sampler_state *samp) struct fd3_pipe_sampler_view { struct pipe_sampler_view base; struct fd_resource *tex_resource; + uint32_t mipaddrs; uint32_t texconst0, texconst1, texconst2, texconst3; }; diff --git a/src/gallium/drivers/freedreno/adreno_common.xml.h b/src/gallium/drivers/freedreno/adreno_common.xml.h index 61979d458ac..b38537be505 100644 --- a/src/gallium/drivers/freedreno/adreno_common.xml.h +++ b/src/gallium/drivers/freedreno/adreno_common.xml.h @@ -4,16 +4,16 @@ /* Autogenerated file, DO NOT EDIT manually! This file was generated by the rules-ng-ng headergen tool in this git repository: -http://0x04.net/cgit/index.cgi/rules-ng-ng -git clone git://0x04.net/rules-ng-ng +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48) - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36) -- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37) -- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05) +- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-06 12:50:15) +- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51536 bytes, from 2013-09-08 13:18:17) Copyright (C) 2013 by the following authors: - Rob Clark (robclark) diff --git a/src/gallium/drivers/freedreno/adreno_pm4.xml.h b/src/gallium/drivers/freedreno/adreno_pm4.xml.h index 94c13f418e7..84339b13723 100644 --- a/src/gallium/drivers/freedreno/adreno_pm4.xml.h +++ b/src/gallium/drivers/freedreno/adreno_pm4.xml.h @@ -4,16 +4,16 @@ /* Autogenerated file, DO NOT EDIT manually! This file was generated by the rules-ng-ng headergen tool in this git repository: -http://0x04.net/cgit/index.cgi/rules-ng-ng -git clone git://0x04.net/rules-ng-ng +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 327 bytes, from 2013-07-05 19:21:12) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) - /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml ( 30005 bytes, from 2013-07-19 21:30:48) - /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml ( 8983 bytes, from 2013-07-24 01:38:36) -- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9712 bytes, from 2013-05-26 15:22:37) -- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51415 bytes, from 2013-08-03 14:26:05) +- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml ( 9759 bytes, from 2013-09-06 12:50:15) +- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml ( 51536 bytes, from 2013-09-08 13:18:17) Copyright (C) 2013 by the following authors: - Rob Clark (robclark) diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 3e051ea9882..3982ecd0f90 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -75,11 +75,13 @@ fd_resource_transfer_map(struct pipe_context *pctx, { struct fd_context *ctx = fd_context(pctx); struct fd_resource *rsc = fd_resource(prsc); - struct pipe_transfer *ptrans = util_slab_alloc(&ctx->transfer_pool); + struct fd_resource_slice *slice = fd_resource_slice(rsc, level); + struct pipe_transfer *ptrans; enum pipe_format format = prsc->format; uint32_t op = 0; char *buf; + ptrans = util_slab_alloc(&ctx->transfer_pool); if (!ptrans) return NULL; @@ -90,7 +92,7 @@ fd_resource_transfer_map(struct pipe_context *pctx, ptrans->level = level; ptrans->usage = usage; ptrans->box = *box; - ptrans->stride = rsc->pitch * rsc->cpp; + ptrans->stride = slice->pitch * rsc->cpp; ptrans->layer_stride = ptrans->stride; /* some state trackers (at least XA) don't do this.. */ @@ -114,9 +116,10 @@ fd_resource_transfer_map(struct pipe_context *pctx, *pptrans = ptrans; - return buf + + return buf + slice->offset + box->y / util_format_get_blockheight(format) * ptrans->stride + - box->x / util_format_get_blockwidth(format) * rsc->cpp; + box->x / util_format_get_blockwidth(format) * rsc->cpp + + box->z * slice->size0; } static void @@ -136,7 +139,7 @@ fd_resource_get_handle(struct pipe_screen *pscreen, struct fd_resource *rsc = fd_resource(prsc); return fd_screen_bo_get_handle(pscreen, rsc->bo, - rsc->pitch * rsc->cpp, handle); + rsc->slices[0].pitch * rsc->cpp, handle); } @@ -149,6 +152,33 @@ static const struct u_resource_vtbl fd_resource_vtbl = { .transfer_inline_write = u_default_transfer_inline_write, }; +static uint32_t +setup_slices(struct fd_resource *rsc) +{ + struct pipe_resource *prsc = &rsc->base.b; + uint32_t level, size = 0; + uint32_t width = prsc->width0; + uint32_t height = prsc->height0; + uint32_t depth = prsc->depth0; + + for (level = 0; level <= prsc->last_level; level++) { + struct fd_resource_slice *slice = fd_resource_slice(rsc, level); + uint32_t aligned_width = align(width, 32); + + slice->pitch = aligned_width; + slice->offset = size; + slice->size0 = slice->pitch * height * rsc->cpp; + + size += slice->size0 * depth * prsc->array_size; + + width = u_minify(width, 1); + height = u_minify(height, 1); + depth = u_minify(depth, 1); + } + + return size; +} + /** * Create a new texture object, using the given template info. */ @@ -161,7 +191,7 @@ fd_resource_create(struct pipe_screen *pscreen, struct pipe_resource *prsc = &rsc->base.b; uint32_t flags, size; - DBG("target=%d, format=%s, %ux%u@%u, array_size=%u, last_level=%u, " + DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " "nr_samples=%u, usage=%u, bind=%x, flags=%x", tmpl->target, util_format_name(tmpl->format), tmpl->width0, tmpl->height0, tmpl->depth0, @@ -177,12 +207,12 @@ fd_resource_create(struct pipe_screen *pscreen, prsc->screen = pscreen; rsc->base.vtbl = &fd_resource_vtbl; - rsc->pitch = align(tmpl->width0, 32); rsc->cpp = util_format_get_blocksize(tmpl->format); assert(rsc->cpp); - size = rsc->pitch * tmpl->height0 * rsc->cpp; + size = setup_slices(rsc); + flags = DRM_FREEDRENO_GEM_CACHE_WCOMBINE | DRM_FREEDRENO_GEM_TYPE_KMEM; /* TODO */ @@ -202,9 +232,10 @@ fd_resource_from_handle(struct pipe_screen *pscreen, struct winsys_handle *handle) { struct fd_resource *rsc = CALLOC_STRUCT(fd_resource); + struct fd_resource_slice *slice = &rsc->slices[0]; struct pipe_resource *prsc = &rsc->base.b; - DBG("target=%d, format=%s, %ux%u@%u, array_size=%u, last_level=%u, " + DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " "nr_samples=%u, usage=%u, bind=%x, flags=%x", tmpl->target, util_format_name(tmpl->format), tmpl->width0, tmpl->height0, tmpl->depth0, @@ -219,11 +250,11 @@ fd_resource_from_handle(struct pipe_screen *pscreen, pipe_reference_init(&prsc->reference, 1); prsc->screen = pscreen; - rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &rsc->pitch); + rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch); rsc->base.vtbl = &fd_resource_vtbl; rsc->cpp = util_format_get_blocksize(tmpl->format); - rsc->pitch /= rsc->cpp; + slice->pitch /= rsc->cpp; assert(rsc->cpp); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 575a143309f..7e10d7a6416 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -31,10 +31,25 @@ #include "util/u_transfer.h" +#include "freedreno_util.h" + +/* for mipmap, cubemap, etc, each level is represented by a slice. + * Currently all slices are part of same bo (just different offsets), + * this is at least how it needs to be for cubemaps, although mipmap + * can be different bo's (although, not sure if there is a strong + * advantage to doing that) + */ +struct fd_resource_slice { + uint32_t offset; /* offset of first layer in slice */ + uint32_t pitch; + uint32_t size0; /* size of first layer in slice */ +}; + struct fd_resource { struct u_resource base; struct fd_bo *bo; - uint32_t pitch, cpp; + uint32_t cpp; + struct fd_resource_slice slices[MAX_MIP_LEVELS]; uint32_t timestamp; bool dirty; }; @@ -45,6 +60,13 @@ fd_resource(struct pipe_resource *ptex) return (struct fd_resource *)ptex; } +static INLINE struct fd_resource_slice * +fd_resource_slice(struct fd_resource *rsc, unsigned level) +{ + assert(level <= rsc->base.b.last_level); + return &rsc->slices[level]; +} + void fd_resource_screen_init(struct pipe_screen *pscreen); void fd_resource_context_init(struct pipe_context *pctx); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 36ef8b0bc53..7412e3dca96 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -206,7 +206,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 14; + return MAX_MIP_LEVELS; case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: return 9192; case PIPE_CAP_MAX_COMBINED_SAMPLERS: diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 7bbbe8016b5..76f557d4835 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -48,6 +48,9 @@ enum adreno_rb_blend_opcode fd_blend_func(unsigned func); enum adreno_pa_su_sc_draw fd_polygon_mode(unsigned mode); enum adreno_stencil_op fd_stencil_op(unsigned op); +#define A3XX_MAX_MIP_LEVELS 14 +/* TBD if it is same on a2xx, but for now: */ +#define MAX_MIP_LEVELS A3XX_MAX_MIP_LEVELS #define FD_DBG_MSGS 0x01 #define FD_DBG_DISASM 0x02