[Mesa-dev] [PATCH] r600g: Fix access to constants > 31.

Jerome Glisse j.glisse at gmail.com
Sun Nov 21 08:07:03 PST 2010


On Sun, Nov 21, 2010 at 10:30 AM, Tilman Sauerbeck
<tilman at code-monkey.de> wrote:
> Signed-off-by: Tilman Sauerbeck <tilman at code-monkey.de>
> ---
>
> This is pretty ugly, but hopefully it will make a proper fix easier
> to implement :)
>
>  src/gallium/drivers/r600/r600_asm.c    |   30 +++++++++++++++++++++++++++++-
>  src/gallium/drivers/r600/r600_asm.h    |    1 +
>  src/gallium/drivers/r600/r600_shader.c |    7 ++++++-
>  3 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
> index ba1471e..fc85432 100644
> --- a/src/gallium/drivers/r600/r600_asm.c
> +++ b/src/gallium/drivers/r600/r600_asm.c
> @@ -410,6 +410,7 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
>  {
>        struct r600_bc_alu *nalu = r600_bc_alu();
>        struct r600_bc_alu *lalu;
> +       unsigned kcache1_addr = 0;
>        int i, r;
>
>        if (nalu == NULL)
> @@ -440,13 +441,37 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
>        }
>        /* number of gpr == the last gpr used in any alu */
>        for (i = 0; i < 3; i++) {
> +               unsigned const_index;
> +
>                if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) {
>                        bc->ngpr = alu->src[i].sel + 1;
>                }
> +
> +               if (alu->src[i].is_const) {
> +                       const_index = alu->src[i].sel - 128;
> +                       unsigned want_addr;
> +
> +                       /* Constants 0-31 will be read from the first
> +                        * set of constants (kcache0_*).
> +                        *
> +                        * Constants > 31 will be read from the second set
> +                        * of constants (kcache1_*).
> +                        */
> +                       if (const_index > 31) {
> +                               want_addr = (const_index / 32) * 2;
> +
> +                               if (!kcache1_addr || kcache1_addr == want_addr) {
> +                                       kcache1_addr = want_addr;
> +                                       nalu->src[i].sel = 160 + (const_index % 32);
> +                               } else
> +                                       fprintf(stderr, "kcache1_addr already in use (want_addr %i, is %i)\n", want_addr, kcache1_addr);

Here instead of printing and error you should add a new clause
r600_add_cf iirc and this should work. Also you might want to check if
want_addr is in [kache1_addr ; kcache1_addr+32] range in which case
you don't need a new cf.

> +                       }
> +               }
> +
>                /* compute how many literal are needed
>                 * either 2 or 4 literals
>                 */
> -               if (alu->src[i].sel == 253) {
> +               if (nalu->src[i].sel == 253) {
>                        if (((alu->src[i].chan + 2) & 0x6) > nalu->nliteral) {
>                                nalu->nliteral = (alu->src[i].chan + 2) & 0x6;
>                        }
> @@ -467,6 +492,9 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int
>        bc->ndw += 2;
>
>        bc->cf_last->kcache0_mode = 2;
> +       bc->cf_last->kcache1_mode = 2;
> +       bc->cf_last->kcache0_addr = 0;
> +       bc->cf_last->kcache1_addr = kcache1_addr;
>
>        /* process cur ALU instructions for bank swizzle */
>        if (alu->last) {
> diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
> index f2016af..50e5052 100644
> --- a/src/gallium/drivers/r600/r600_asm.h
> +++ b/src/gallium/drivers/r600/r600_asm.h
> @@ -34,6 +34,7 @@ struct r600_bc_alu_src {
>        unsigned                        neg;
>        unsigned                        abs;
>        unsigned                        rel;
> +       unsigned                        is_const;
>  };
>
>  struct r600_bc_alu_dst {
> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index c46658a..b733ddb 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -880,7 +880,10 @@ static int tgsi_src(struct r600_shader_ctx *ctx,
>        int index;
>        memset(r600_src, 0, sizeof(struct r600_bc_alu_src));
>        r600_src->sel = tgsi_src->Register.Index;
> -       if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
> +
> +       if (tgsi_src->Register.File == TGSI_FILE_CONSTANT) {
> +               r600_src->is_const = 1;
> +       } else if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
>                r600_src->sel = 0;
>                index = tgsi_src->Register.Index;
>                ctx->value[0] = ctx->literals[index * 4 + 0];
> @@ -953,6 +956,7 @@ static int tgsi_split_constant(struct r600_shader_ctx *ctx, struct r600_bc_alu_s
>                                memset(&alu, 0, sizeof(struct r600_bc_alu));
>                                alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
>                                alu.src[0].sel = r600_src[i].sel;
> +                               alu.src[0].is_const = 1;
>                                alu.src[0].chan = k;
>                                alu.src[0].rel = r600_src[i].rel;
>                                alu.dst.sel = treg;
> @@ -965,6 +969,7 @@ static int tgsi_split_constant(struct r600_shader_ctx *ctx, struct r600_bc_alu_s
>                                        return r;
>                        }
>                        r600_src[i].sel = treg;
> +                       r600_src[i].is_const = 0;
>                        r600_src[i].rel =0;
>                        j--;
>                }
> --
> 1.7.3.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>


More information about the mesa-dev mailing list