Merge remote-tracking branch 'origin/master' into pipe-video
[mesa.git] / src / gallium / drivers / r600 / r600_shader.c
index 0fe689e2716156b5c7e0a5d8bb43d83ef0b803bd..845d41ace0278be86cca714b9eb62b41f125ec7d 100644 (file)
@@ -21,6 +21,7 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_info.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_dump.h"
@@ -33,6 +34,7 @@
 #include "r600d.h"
 #include <stdio.h>
 #include <errno.h>
+#include <byteswap.h>
 
 int r600_find_vs_semantic_index(struct r600_shader *vs,
                                struct r600_shader *ps, int id)
@@ -52,7 +54,8 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_shader *rshader = &shader->shader;
-       void *ptr;
+       uint32_t *ptr;
+       int     i;
 
        /* copy new shader */
        if (shader->bo == NULL) {
@@ -60,8 +63,14 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
                if (shader->bo == NULL) {
                        return -ENOMEM;
                }
-               ptr = r600_bo_map(rctx->radeon, shader->bo, 0, NULL);
-               memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * 4);
+               ptr = (uint32_t*)r600_bo_map(rctx->radeon, shader->bo, 0, NULL);
+               if (R600_BIG_ENDIAN) {
+                       for (i = 0; i < rshader->bc.ndw; ++i) {
+                               ptr[i] = bswap_32(rshader->bc.bytecode[i]);
+                       }
+               } else {
+                       memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * sizeof(*ptr));
+               }
                r600_bo_unmap(rctx->radeon, shader->bo);
        }
        /* build state */
@@ -467,6 +476,7 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int offset
        vtx.num_format_all = 2;         /* NUM_FORMAT_SCALED */
        vtx.format_comp_all = 1;        /* FORMAT_COMP_SIGNED */
        vtx.srf_mode_all = 1;           /* SRF_MODE_NO_ZERO */
+       vtx.endian = r600_endian_swap(32);
 
        if ((r = r600_bc_add_vtx(ctx->bc, &vtx)))
                return r;
@@ -815,7 +825,8 @@ out_err:
 
 static int tgsi_unsupported(struct r600_shader_ctx *ctx)
 {
-       R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode);
+       R600_ERR("%s tgsi opcode unsupported\n",
+                tgsi_get_opcode_name(ctx->inst_info->tgsi_opcode));
        return -EINVAL;
 }
 
@@ -896,6 +907,8 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap)
                        break;
                case TGSI_OPCODE_ABS:
                        alu.src[0].abs = 1;
+                       if (alu.src[0].neg)
+                         alu.src[0].neg = 0;
                        break;
                default:
                        break;
@@ -1526,10 +1539,12 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
        unsigned src_gpr;
        int r, i;
        int opcode;
-       /* Texture fetch instructions can only use gprs as source. */
+       /* Texture fetch instructions can only use gprs as source.
+        * Also they cannot negate the source or take the absolute value */
        const boolean src_requires_loading =
-               inst->Src[0].Register.File != TGSI_FILE_TEMPORARY &&
-               inst->Src[0].Register.File != TGSI_FILE_INPUT;
+               (inst->Src[0].Register.File != TGSI_FILE_TEMPORARY &&
+               inst->Src[0].Register.File != TGSI_FILE_INPUT) ||
+               ctx->src[0].neg || ctx->src[0].abs;
        boolean src_loaded = FALSE;
 
        src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
@@ -1704,6 +1719,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
                tex.src_sel_y = ctx->src[0].swizzle[1];
                tex.src_sel_z = ctx->src[0].swizzle[2];
                tex.src_sel_w = ctx->src[0].swizzle[3];
+               tex.src_rel = ctx->src[0].rel;
        }
 
        if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) {
@@ -1979,9 +1995,11 @@ static int tgsi_exp(struct r600_shader_ctx *ctx)
                r600_bc_src(&alu.src[0], &ctx->src[0], 0);
 
                alu.dst.sel = ctx->temp_reg;
-//             r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
-//             if (r)
-//                     return r;
+#if 0
+               r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+               if (r)
+                       return r;
+#endif
                alu.dst.write = 1;
                alu.dst.chan = 1;