r300g: implement ARR opcode
authorDavid Heidelberg <david@ixit.cz>
Fri, 19 Dec 2014 13:11:21 +0000 (14:11 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 21 Dec 2014 19:34:19 +0000 (20:34 +0100)
Same as ARL, just has extra rounding.
Useful for st/nine.

Tested-by: Pavel Ondračka <pavel.ondracka@email.cz>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r300/compiler/r3xx_vertprog.c
src/gallium/drivers/r300/compiler/radeon_opcodes.c
src/gallium/drivers/r300/compiler/radeon_opcodes.h
src/gallium/drivers/r300/r300_tgsi_to_rc.c

index fd4f6f4045e25e5ac26bfcd37a6a64f145170f45..2ff6db54637c51a90a5e4a8b50395a23e1ff8ad3 100644 (file)
@@ -405,6 +405,7 @@ static void translate_vertex_program(struct radeon_compiler *c, void *user)
                switch (vpi->Opcode) {
                case RC_OPCODE_ADD: ei_vector2(compiler->code, VE_ADD, vpi, inst); break;
                case RC_OPCODE_ARL: ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst); break;
+               case RC_OPCODE_ARR: ei_vector1(compiler->code, VE_FLT2FIX_DX_RND, vpi, inst); break;
                case RC_OPCODE_COS: ei_math1(compiler->code, ME_COS, vpi, inst); break;
                case RC_OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break;
                case RC_OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break;
@@ -798,7 +799,7 @@ static void transform_negative_addressing(struct r300_vertex_program_compiler *c
        struct rc_instruction *inst, *add;
        unsigned const_swizzle;
 
-       /* Transform ARL */
+       /* Transform ARL/ARR */
        add = rc_insert_new_instruction(&c->Base, arl->Prev);
        add->U.I.Opcode = RC_OPCODE_ADD;
        add->U.I.DstReg.File = RC_FILE_TEMPORARY;
@@ -833,7 +834,7 @@ static void rc_emulate_negative_addressing(struct radeon_compiler *compiler, voi
        for (inst = c->Base.Program.Instructions.Next; inst != &c->Base.Program.Instructions; inst = inst->Next) {
                const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
 
-               if (inst->U.I.Opcode == RC_OPCODE_ARL) {
+               if (inst->U.I.Opcode == RC_OPCODE_ARL || inst->U.I.Opcode == RC_OPCODE_ARR) {
                        if (lastARL != NULL && min_offset < 0)
                                transform_negative_addressing(c, lastARL, inst, min_offset);
 
@@ -847,7 +848,7 @@ static void rc_emulate_negative_addressing(struct radeon_compiler *compiler, voi
                            inst->U.I.SrcReg[i].Index < 0) {
                                /* ARL must precede any indirect addressing. */
                                if (lastARL == NULL) {
-                                       rc_error(&c->Base, "Vertex shader: Found relative addressing without ARL.");
+                                       rc_error(&c->Base, "Vertex shader: Found relative addressing without ARL/ARR.");
                                        return;
                                }
 
index 916baa236086ce29ae5d62cca581ed52433f1926..a251bbe45d0efab0e563383547b21261ae0163a9 100644 (file)
@@ -59,6 +59,12 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
                .NumSrcRegs = 1,
                .HasDstReg = 1
        },
+       {
+               .Opcode = RC_OPCODE_ARR,
+               .Name = "ARR",
+               .NumSrcRegs = 1,
+               .HasDstReg = 1
+       },
        {
                .Opcode = RC_OPCODE_CEIL,
                .Name = "CEIL",
@@ -546,6 +552,7 @@ void rc_compute_sources_for_writemask(
        } else {
                switch(opcode->Opcode) {
                case RC_OPCODE_ARL:
+               case RC_OPCODE_ARR:
                        srcmasks[0] |= RC_MASK_X;
                        break;
                case RC_OPCODE_DP2:
index 0a70901a82f9bd0ff91d05fb321ff8cc81379002..1c425050727e2c1f607926a92e9d621e16484978 100644 (file)
@@ -47,6 +47,10 @@ typedef enum {
         * dst.x = floor(src.x), where dst must be an address register */
        RC_OPCODE_ARL,
 
+       /** special instruction: load address register with round
+        * dst.x = round(src.x), where dst must be an address register */
+       RC_OPCODE_ARR,
+
        /** vec4 instruction: dst.c = ceil(src0.c) */
        RC_OPCODE_CEIL,
 
index b82cb3e2684d94f4d8c38501d0b972f2195ce4bb..4d94941b75d6bc654718e54ecb68c58858a8bdc4 100644 (file)
@@ -82,7 +82,7 @@ static unsigned translate_opcode(unsigned opcode)
      /* case TGSI_OPCODE_UP2US: return RC_OPCODE_UP2US; */
      /* case TGSI_OPCODE_UP4B: return RC_OPCODE_UP4B; */
      /* case TGSI_OPCODE_UP4UB: return RC_OPCODE_UP4UB; */
-     /* case TGSI_OPCODE_ARR: return RC_OPCODE_ARR; */
+        case TGSI_OPCODE_ARR: return RC_OPCODE_ARR;
      /* case TGSI_OPCODE_CAL: return RC_OPCODE_CAL; */
      /* case TGSI_OPCODE_RET: return RC_OPCODE_RET; */
         case TGSI_OPCODE_SSG: return RC_OPCODE_SSG;