Przeglądaj źródła

gallivm: don't use URem/UDiv when calculating offsets for blocks

While it's true that llvm can and will indeed replace this with bit
arithmetic (since block height/width is POT), it does so (llvm 2.7) by element
and hence extracts/shifts/reinserts each element individually.
This costs about 16 instructions (and extract is not really fast) vs. 1...
tags/snb-magic
Roland Scheidegger 15 lat temu
rodzic
commit
46d05d4ef9
1 zmienionych plików z 11 dodań i 1 usunięć
  1. 11
    1
      src/gallium/auxiliary/gallivm/lp_bld_sample.c

+ 11
- 1
src/gallium/auxiliary/gallivm/lp_bld_sample.c Wyświetl plik

@@ -655,11 +655,21 @@ lp_build_sample_partial_offset(struct lp_build_context *bld,
* Pixel blocks have power of two dimensions. LLVM should convert the
* rem/div to bit arithmetic.
* TODO: Verify this.
* It does indeed BUT it does transform it to scalar (and back) when doing so
* (using roughly extract, shift/and, mov, unpack) (llvm 2.7).
* The generated code looks seriously unfunny and is quite expensive.
*/

#if 0
LLVMValueRef block_width = lp_build_const_int_vec(bld->type, block_length);
subcoord = LLVMBuildURem(bld->builder, coord, block_width, "");
coord = LLVMBuildUDiv(bld->builder, coord, block_width, "");
#else
unsigned logbase2 = util_unsigned_logbase2(block_length);
LLVMValueRef block_shift = lp_build_const_int_vec(bld->type, logbase2);
LLVMValueRef block_mask = lp_build_const_int_vec(bld->type, block_length - 1);
subcoord = LLVMBuildAnd(bld->builder, coord, block_mask, "");
coord = LLVMBuildLShr(bld->builder, coord, block_shift, "");
#endif
}

offset = lp_build_mul(bld, coord, stride);

Ładowanie…
Anuluj
Zapisz