freedreno/ir3: fix constlen with relative addressing
authorRob Clark <robclark@freedesktop.org>
Thu, 4 Sep 2014 17:48:05 +0000 (13:48 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 5 Sep 2014 02:28:50 +0000 (22:28 -0400)
We can't rely on the value from the assembler if relative addressing is
used.  So instead use the max of declared-consts (which does not include
compiler immediates) and what we get from the assembler (which does).

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/ir3/ir3_compiler.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c

index 78c71d42e3940c7923fc53a4434eaffb4d52c762..1cf95a722a6e93c44cc398a05cfdc78d9b1f564c 100644 (file)
@@ -248,7 +248,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
                        A3XX_SP_VS_CTRL_REG0_LENGTH(vp->instrlen));
        OUT_RING(ring, A3XX_SP_VS_CTRL_REG1_CONSTLENGTH(vp->constlen) |
                        A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(vp->total_in) |
-                       A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(MAX2(vsi->max_const, 0)));
+                       A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(MAX2(vp->constlen + 1, 0)));
        OUT_RING(ring, A3XX_SP_VS_PARAM_REG_POSREGID(pos_regid) |
                        A3XX_SP_VS_PARAM_REG_PSIZEREGID(psize_regid) |
                        A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(align(fp->total_in, 4) / 4));
@@ -326,7 +326,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
                                A3XX_SP_FS_CTRL_REG0_LENGTH(fp->instrlen));
                OUT_RING(ring, A3XX_SP_FS_CTRL_REG1_CONSTLENGTH(fp->constlen) |
                                A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING(fp->total_in) |
-                               A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(MAX2(fsi->max_const, 0)) |
+                               A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(MAX2(fp->constlen + 1, 0)) |
                                A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET(63));
                OUT_PKT0(ring, REG_A3XX_SP_FS_OBJ_OFFSET_REG, 2);
                OUT_RING(ring, A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(128) |
index e23dcdbc2c719da0d8abb7ba78a9decfee13a003..aa3773e9e987a628040ff765edf85b54e0e3e706 100644 (file)
@@ -175,6 +175,13 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
        if (info->indirect_files & (FM(TEMPORARY) | FM(INPUT) | FM(OUTPUT)))
                return TGSI_PARSE_ERROR;
 
+       /* NOTE: if relative addressing is used, we set constlen in
+        * the compiler (to worst-case value) since we don't know in
+        * the assembler what the max addr reg value can be:
+        */
+       if (info->indirect_files & FM(CONSTANT))
+               so->constlen = 4 * (ctx->info.file_max[TGSI_FILE_CONSTANT] + 1);
+
        /* Immediates go after constants: */
        so->first_immediate = info->file_max[TGSI_FILE_CONSTANT] + 1;
        ctx->immediate_idx = 4 * (ctx->info.file_max[TGSI_FILE_IMMEDIATE] + 1);
index 04de532f4998bc26567d8e854b1ddb6b452b88f8..4c06770d6274cc827b2e7a78d1f2226b33c4171b 100644 (file)
@@ -69,7 +69,12 @@ assemble_variant(struct ir3_shader_variant *v)
        free(bin);
 
        v->instrlen = v->info.sizedwords / 8;
-       v->constlen = v->info.max_const + 1;
+
+       /* NOTE: if relative addressing is used, we set constlen in
+        * the compiler (to worst-case value) since we don't know in
+        * the assembler what the max addr reg value can be:
+        */
+       v->constlen = MAX2(v->constlen, v->info.max_const + 1);
 
        /* no need to keep the ir around beyond this point: */
        ir3_destroy(v->ir);