r600/sb: update last_cf if alu is the last clause
[mesa.git] / src / gallium / drivers / r600 / sb / sb_bc_finalize.cpp
index dadee456a1f2d2f7a8fd8aab81d14ef822278f35..2ec4db624a585518fae5b0af54463537031f9f5c 100644 (file)
@@ -266,6 +266,7 @@ void bc_finalizer::run_on(container_node* c) {
                                                }
                                        }
                                }
+                               last_cf = c;
                        } else if (n->is_fetch_inst()) {
                                finalize_fetch(static_cast<fetch_node*>(n));
                        } else if (n->is_cf_inst()) {
@@ -303,7 +304,8 @@ void bc_finalizer::finalize_alu_group(alu_group_node* g, node *prev_node) {
                        assert(fdst.chan() == slot || slot == SLOT_TRANS);
                }
 
-               n->bc.dst_gpr = fdst.sel();
+               if (!(n->bc.op_ptr->flags & AF_MOVA && ctx.is_cayman()))
+                       n->bc.dst_gpr = fdst.sel();
                n->bc.dst_chan = d ? fdst.chan() : slot < SLOT_TRANS ? slot : 0;
 
 
@@ -514,7 +516,7 @@ void bc_finalizer::copy_fetch_src(fetch_node &dst, fetch_node &src, unsigned arg
 
 void bc_finalizer::emit_set_grad(fetch_node* f) {
 
-       assert(f->src.size() == 12);
+       assert(f->src.size() == 12 || f->src.size() == 13);
        unsigned ops[2] = { FETCH_OP_SET_GRADIENTS_V, FETCH_OP_SET_GRADIENTS_H };
 
        unsigned arg_start = 0;
@@ -556,6 +558,8 @@ void bc_finalizer::finalize_fetch(fetch_node* f) {
 
        if (flags & FF_VTX) {
                src_count = 1;
+       } else if (flags & FF_GDS) {
+               src_count = 2;
        } else if (flags & FF_USEGRAD) {
                emit_set_grad(f);
        } else if (flags & FF_USE_TEXTURE_OFFSETS) {
@@ -660,6 +664,11 @@ void bc_finalizer::finalize_fetch(fetch_node* f) {
        for (unsigned i = 0; i < 4; ++i)
                f->bc.dst_sel[i] = dst_swz[i];
 
+       if ((flags & FF_GDS) && reg == -1) {
+               f->bc.dst_sel[0] = SEL_MASK;
+               f->bc.dst_gpr = 0;
+               return ;
+       }
        assert(reg >= 0);
 
        if (reg >= 0)
@@ -764,8 +773,6 @@ void bc_finalizer::finalize_cf(cf_node* c) {
                        mask |= (1 << chan);
                }
 
-               assert(reg >= 0 && mask);
-
                if (reg >= 0)
                        update_ngpr(reg);
 
@@ -811,8 +818,8 @@ void bc_finalizer::finalize_cf(cf_node* c) {
 }
 
 sel_chan bc_finalizer::translate_kcache(cf_node* alu, value* v) {
-       unsigned sel = v->select.sel();
-       unsigned bank = sel >> 12;
+       unsigned sel = v->select.kcache_sel();
+       unsigned bank = v->select.kcache_bank();
        unsigned chan = v->select.chan();
        static const unsigned kc_base[] = {128, 160, 256, 288};
 
@@ -934,6 +941,11 @@ void bc_finalizer::cf_peephole() {
                cf_node *c = static_cast<cf_node*>(*I);
 
                if (c->jump_after_target) {
+                       if (c->jump_target->next == NULL) {
+                               c->jump_target->insert_after(sh.create_cf(CF_OP_NOP));
+                               if (last_cf == c->jump_target)
+                                       last_cf = static_cast<cf_node*>(c->jump_target->next);
+                       }
                        c->jump_target = static_cast<cf_node*>(c->jump_target->next);
                        c->jump_after_target = false;
                }