[Mesa-dev] [RFC 03/24] nvc0: bind images on compute shaders for Kepler
Ilia Mirkin
imirkin at alum.mit.edu
Wed Apr 13 01:38:11 UTC 2016
On Tue, Apr 12, 2016 at 7:56 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Old surfaces validation code will be removed once images are completely
> done for Fermi/Kepler, that explains why I only disable it for now.
>
> set_surface_info() which sticks surfaces information into the driver
> constant buffer needs to be updated because now we are dealing with
> pipe_image_view instead of pipe_surface.
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
> src/gallium/drivers/nouveau/nvc0/nvc0_context.h | 5 ++-
> src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 4 +-
> src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 54 +++++++++++++------------
> src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 37 ++++++++++++++++-
> 4 files changed, 72 insertions(+), 28 deletions(-)
>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
> index 17733f5..107b737 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
> @@ -130,6 +130,9 @@
> /* 32 user buffers, at 4 32-bits integers each */
> #define NVC0_CB_AUX_BUF_INFO(i) 0x200 + (i) * 4 * 4
> #define NVC0_CB_AUX_BUF_SIZE (NVC0_MAX_BUFFERS * 4 * 4)
> +/* 8 surfaces, at 16 32-bits integers each */
> +#define NVC0_CB_AUX_SU_INFO(i) 0x400 + (i) * 16 * 4
> +#define nVC0_CB_AUX_SU_SIZE (NVC0_MAX_IMAGES * 16 * 4)
> /* 4 32-bits floats for the vertex runout, put at the end */
> #define NVC0_CB_AUX_RUNOUT_INFO NVC0_CB_USR_SIZE + NVC0_CB_AUX_SIZE
>
> @@ -324,7 +327,7 @@ void nvc0_validate_textures(struct nvc0_context *);
> void nvc0_validate_samplers(struct nvc0_context *);
> void nve4_set_tex_handles(struct nvc0_context *);
> void nvc0_validate_surfaces(struct nvc0_context *);
> -void nve4_set_surface_info(struct nouveau_pushbuf *, struct pipe_surface *,
> +void nve4_set_surface_info(struct nouveau_pushbuf *, struct pipe_image_view *,
> struct nvc0_screen *);
>
> struct pipe_sampler_view *
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> index d3024f9..ced8130 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
> @@ -551,11 +551,13 @@ nvc0_program_translate(struct nvc0_program *prog, uint16_t chipset,
> info->io.texBindBase = NVC0_CB_AUX_TEX_INFO(0);
> info->prop.cp.gridInfoBase = NVC0_CB_AUX_GRID_INFO;
> info->io.uboInfoBase = NVC0_CB_AUX_UBO_INFO(0);
> + info->io.suInfoBase = NVC0_CB_AUX_SU_INFO(0);
> + } else {
> + info->io.suInfoBase = 0; /* TODO */
> }
> info->io.msInfoCBSlot = 0;
> info->io.msInfoBase = NVC0_CB_AUX_MS_INFO;
> info->io.bufInfoBase = NVC0_CB_AUX_BUF_INFO(0);
> - info->io.suInfoBase = 0; /* TODO */
> } else {
> if (chipset >= NVISA_GK104_CHIPSET) {
> info->io.texBindBase = NVC0_CB_AUX_TEX_INFO(0);
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> index 647c2a6..585b1e5 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> @@ -745,21 +745,21 @@ static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
>
> void
> nve4_set_surface_info(struct nouveau_pushbuf *push,
> - struct pipe_surface *psf,
> + struct pipe_image_view *view,
> struct nvc0_screen *screen)
> {
> - struct nv50_surface *sf = nv50_surface(psf);
> struct nv04_resource *res;
> uint64_t address;
> uint32_t *const info = push->cur;
> + int width, height, depth;
> uint8_t log2cpp;
>
> - if (psf && !nve4_su_format_map[psf->format])
> + if (view && !nve4_su_format_map[view->format])
> NOUVEAU_ERR("unsupported surface format, try is_format_supported() !\n");
>
> push->cur += 16;
>
> - if (!psf || !nve4_su_format_map[psf->format]) {
> + if (!view || !nve4_su_format_map[view->format]) {
> memset(info, 0, 16 * sizeof(*info));
>
> info[0] = 0xbadf0000;
> @@ -768,13 +768,17 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
> screen->lib_code->start;
> return;
> }
> - res = nv04_resource(sf->base.texture);
> + res = nv04_resource(view->resource);
>
> - address = res->address + sf->offset;
> + address = res->address;
>
> - info[8] = sf->width;
> - info[9] = sf->height;
> - info[10] = sf->depth;
> + width = u_minify(view->resource->width0, view->u.tex.level);
You never check that it's a texture... if it's a buffer, this is
undefined. AFAIK you have some later patch which rectifies this...
perhaps fold this in?
> + height = u_minify(view->resource->height0, view->u.tex.level);
> + depth = u_minify(view->resource->depth0, view->u.tex.level);
> +
> + info[8] = width;
> + info[9] = height;
> + info[10] = depth;
> switch (res->base.target) {
> case PIPE_TEXTURE_1D_ARRAY:
> info[11] = 1;
> @@ -795,17 +799,17 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
> info[11] = 0;
> break;
> }
> - log2cpp = (0xf000 & nve4_su_format_aux_map[sf->base.format]) >> 12;
> + log2cpp = (0xf000 & nve4_su_format_aux_map[view->format]) >> 12;
>
> - info[12] = nve4_suldp_lib_offset[sf->base.format] + screen->lib_code->start;
> + info[12] = nve4_suldp_lib_offset[view->format] + screen->lib_code->start;
>
> /* limit in bytes for raw access */
> - info[13] = (0x06 << 22) | ((sf->width << log2cpp) - 1);
> + info[13] = (0x06 << 22) | ((width << log2cpp) - 1);
>
> - info[1] = nve4_su_format_map[sf->base.format];
> + info[1] = nve4_su_format_map[view->format];
>
> #if 0
> - switch (util_format_get_blocksizebits(sf->base.format)) {
> + switch (util_format_get_blocksizebits(view->format)) {
> case 16: info[1] |= 1 << 16; break;
> case 32: info[1] |= 2 << 16; break;
> case 64: info[1] |= 3 << 16; break;
> @@ -816,13 +820,13 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
> #else
> info[1] |= log2cpp << 16;
> info[1] |= 0x4000;
> - info[1] |= (0x0f00 & nve4_su_format_aux_map[sf->base.format]);
> + info[1] |= (0x0f00 & nve4_su_format_aux_map[view->format]);
> #endif
>
> if (res->base.target == PIPE_BUFFER) {
> info[0] = address >> 8;
> - info[2] = sf->width - 1;
> - info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
> + info[2] = width - 1;
> + info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
> info[3] = 0;
> info[4] = 0;
> info[5] = 0;
> @@ -832,28 +836,28 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
> info[15] = 0;
> } else {
> struct nv50_miptree *mt = nv50_miptree(&res->base);
> - struct nv50_miptree_level *lvl = &mt->level[sf->base.u.tex.level];
> - const unsigned z = sf->base.u.tex.first_layer;
> + struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level];
> + const unsigned z = view->u.tex.first_layer;
>
> if (z) {
> if (mt->layout_3d) {
> - address += nvc0_mt_zslice_offset(mt, psf->u.tex.level, z);
> + address += nvc0_mt_zslice_offset(mt, view->u.tex.level, z);
> /* doesn't work if z passes z-tile boundary */
> - assert(sf->depth == 1);
> + assert(depth == 1);
> } else {
> address += mt->layer_stride * z;
> }
> }
> info[0] = address >> 8;
> - info[2] = sf->width - 1;
> + info[2] = width - 1;
> /* NOTE: this is really important: */
> - info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
> + info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
> info[3] = (0x88 << 24) | (lvl->pitch / 64);
> - info[4] = sf->height - 1;
> + info[4] = height - 1;
> info[4] |= (lvl->tile_mode & 0x0f0) << 25;
> info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22;
> info[5] = mt->layer_stride >> 8;
> - info[6] = sf->depth - 1;
> + info[6] = depth - 1;
> info[6] |= (lvl->tile_mode & 0xf00) << 21;
> info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22;
> info[7] = 0;
> diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
> index 0bb9069..ca9485d 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
> @@ -186,7 +186,42 @@ nve4_screen_compute_setup(struct nvc0_screen *screen,
> return 0;
> }
>
> +static void
> +nve4_compute_validate_surfaces(struct nvc0_context *nvc0)
> +{
> + struct nouveau_pushbuf *push = nvc0->base.pushbuf;
> + struct nvc0_screen *screen = nvc0->screen;
> + uint64_t address;
> + const int s = 5;
> + int i, j;
> +
> + address = nvc0->screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s);
>
> + BEGIN_NVC0(push, NVE4_CP(UPLOAD_DST_ADDRESS_HIGH), 2);
> + PUSH_DATAh(push, address + NVC0_CB_AUX_SU_INFO(0));
> + PUSH_DATA (push, address + NVC0_CB_AUX_SU_INFO(0));
> + BEGIN_NVC0(push, NVE4_CP(UPLOAD_LINE_LENGTH_IN), 2);
> + PUSH_DATA (push, 16 * NVC0_MAX_IMAGES * 4);
> + PUSH_DATA (push, 0x1);
> + BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + 16 * NVC0_MAX_IMAGES);
> + PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x20 << 1));
> +
> + for (i = 0; i < NVC0_MAX_IMAGES; ++i) {
> + struct pipe_image_view *view = &nvc0->images[s][i];
> + if (view->resource) {
> + struct nv04_resource *res = nv04_resource(view->resource);
> +
> + nve4_set_surface_info(push, view, screen);
> + BCTX_REFN(nvc0->bufctx_cp, CP_SUF, res, RDWR);
> + } else {
> + for (j = 0; j < 16; j++)
> + PUSH_DATA(push, 0);
> + }
> + }
> +}
> +
> +/* Will be removed once images are completely done. */
> +#if 0
> static void
> nve4_compute_validate_surfaces(struct nvc0_context *nvc0)
> {
> @@ -253,7 +288,7 @@ nve4_compute_validate_surfaces(struct nvc0_context *nvc0)
>
> nvc0->surfaces_dirty[t] = 0;
> }
> -
> +#endif
>
> /* Thankfully, textures with samplers follow the normal rules. */
> static void
> --
> 2.8.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list