diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_tile_soa.py')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_tile_soa.py | 176 |
1 files changed, 84 insertions, 92 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py index 5d53689a3d..00b8d4fc38 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py @@ -45,10 +45,10 @@ sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), '../../auxiliary/u from u_format_access import * -def generate_format_read(format, dst_type, dst_native_type, dst_suffix): +def generate_format_read(format, dst_channel, dst_native_type, dst_suffix): '''Generate the function to read pixels from a particular format''' - name = short_name(format) + name = format.short_name() src_native_type = native_type(format) @@ -64,11 +64,11 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix): names = ['']*4 if format.colorspace == 'rgb': for i in range(4): - swizzle = format.out_swizzle[i] + swizzle = format.swizzles[i] if swizzle < 4: names[swizzle] += 'rgba'[i] elif format.colorspace == 'zs': - swizzle = format.out_swizzle[0] + swizzle = format.swizzles[0] if swizzle < 4: names[swizzle] = 'z' else: @@ -76,48 +76,49 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix): else: assert False - if format.layout == ARITH: - print ' %s pixel = *src_pixel++;' % src_native_type - shift = 0; - for i in range(4): - src_type = format.in_types[i] - width = src_type.size - if names[i]: - value = 'pixel' - mask = (1 << width) - 1 - if shift: - value = '(%s >> %u)' % (value, shift) - if shift + width < format.block_size(): - value = '(%s & 0x%x)' % (value, mask) - value = conversion_expr(src_type, dst_type, dst_native_type, value) - print ' %s %s = %s;' % (dst_native_type, names[i], value) - shift += width - elif format.layout == ARRAY: - for i in range(4): - src_type = format.in_types[i] - if names[i]: - value = '(*src_pixel++)' - value = conversion_expr(src_type, dst_type, dst_native_type, value) - print ' %s %s = %s;' % (dst_native_type, names[i], value) + if format.layout == PLAIN: + if not format.is_array(): + print ' %s pixel = *src_pixel++;' % src_native_type + shift = 0; + for i in range(4): + src_channel = format.channels[i] + width = src_channel.size + if names[i]: + value = 'pixel' + mask = (1 << width) - 1 + if shift: + value = '(%s >> %u)' % (value, shift) + if shift + width < format.block_size(): + value = '(%s & 0x%x)' % (value, mask) + value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False) + print ' %s %s = %s;' % (dst_native_type, names[i], value) + shift += width + else: + for i in range(4): + src_channel = format.channels[i] + if names[i]: + value = '(*src_pixel++)' + value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False) + print ' %s %s = %s;' % (dst_native_type, names[i], value) else: assert False for i in range(4): if format.colorspace == 'rgb': - swizzle = format.out_swizzle[i] + swizzle = format.swizzles[i] if swizzle < 4: value = names[swizzle] elif swizzle == SWIZZLE_0: value = '0' elif swizzle == SWIZZLE_1: - value = '1' + value = get_one(dst_channel) else: assert False elif format.colorspace == 'zs': if i < 3: value = 'z' else: - value = '1' + value = get_one(dst_channel) else: assert False print ' TILE_PIXEL(dst, x, y, %u) = %s; /* %s */' % (i, value, 'rgba'[i]) @@ -129,31 +130,16 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix): print -def compute_inverse_swizzle(format): - '''Return an array[4] of inverse swizzle terms''' - inv_swizzle = [None]*4 - if format.colorspace == 'rgb': - for i in range(4): - swizzle = format.out_swizzle[i] - if swizzle < 4: - inv_swizzle[swizzle] = i - elif format.colorspace == 'zs': - swizzle = format.out_swizzle[0] - if swizzle < 4: - inv_swizzle[swizzle] = 0 - return inv_swizzle - - -def pack_rgba(format, src_type, r, g, b, a): +def pack_rgba(format, src_channel, r, g, b, a): """Return an expression for packing r, g, b, a into a pixel of the given format. Ex: '(b << 24) | (g << 16) | (r << 8) | (a << 0)' """ assert format.colorspace == 'rgb' - inv_swizzle = compute_inverse_swizzle(format) + inv_swizzle = format.inv_swizzles() shift = 0 expr = None for i in range(4): - # choose r, g, b, or a depending on the inverse swizzle term + # choose r, g, b, or a depending on the inverse swizzle term if inv_swizzle[i] == 0: value = r elif inv_swizzle[i] == 1: @@ -166,25 +152,25 @@ def pack_rgba(format, src_type, r, g, b, a): value = None if value: - dst_type = format.in_types[i] + dst_channel = format.channels[i] dst_native_type = native_type(format) - value = conversion_expr(src_type, dst_type, dst_native_type, value) + value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False) term = "((%s) << %d)" % (value, shift) if expr: expr = expr + " | " + term else: expr = term - width = format.in_types[i].size + width = format.channels[i].size shift = shift + width return expr -def emit_unrolled_write_code(format, src_type): +def emit_unrolled_write_code(format, src_channel): '''Emit code for writing a block based on unrolled loops. This is considerably faster than the TILE_PIXEL-based code below. ''' - dst_native_type = native_type(format) + dst_native_type = 'uint%u_t' % format.block_size() print ' const unsigned dstpix_stride = dst_stride / %d;' % format.stride() print ' %s *dstpix = (%s *) dst;' % (dst_native_type, dst_native_type) print ' unsigned int qx, qy, i;' @@ -199,8 +185,8 @@ def emit_unrolled_write_code(format, src_type): print ' const uint8_t *a = src + 3 * TILE_C_STRIDE;' print ' (void) r; (void) g; (void) b; (void) a; /* silence warnings */' print ' for (i = 0; i < TILE_C_STRIDE; i += 2) {' - print ' const uint32_t pixel0 = %s;' % pack_rgba(format, src_type, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]") - print ' const uint32_t pixel1 = %s;' % pack_rgba(format, src_type, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]") + print ' const uint32_t pixel0 = %s;' % pack_rgba(format, src_channel, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]") + print ' const uint32_t pixel1 = %s;' % pack_rgba(format, src_channel, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]") print ' const unsigned offset = (py + tile_y_offset[i]) * dstpix_stride + (px + tile_x_offset[i]);' print ' dstpix[offset + 0] = pixel0;' print ' dstpix[offset + 1] = pixel1;' @@ -210,11 +196,11 @@ def emit_unrolled_write_code(format, src_type): print ' }' -def emit_tile_pixel_write_code(format, src_type): +def emit_tile_pixel_write_code(format, src_channel): '''Emit code for writing a block based on the TILE_PIXEL macro.''' dst_native_type = native_type(format) - inv_swizzle = compute_inverse_swizzle(format) + inv_swizzle = format.inv_swizzles() print ' unsigned x, y;' print ' uint8_t *dst_row = dst + y0*dst_stride;' @@ -222,27 +208,28 @@ def emit_tile_pixel_write_code(format, src_type): print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride()) print ' for (x = 0; x < w; ++x) {' - if format.layout == ARITH: - print ' %s pixel = 0;' % dst_native_type - shift = 0; - for i in range(4): - dst_type = format.in_types[i] - width = dst_type.size - if inv_swizzle[i] is not None: - value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i] - value = conversion_expr(src_type, dst_type, dst_native_type, value) - if shift: - value = '(%s << %u)' % (value, shift) - print ' pixel |= %s;' % value - shift += width - print ' *dst_pixel++ = pixel;' - elif format.layout == ARRAY: - for i in range(4): - dst_type = format.in_types[i] - if inv_swizzle[i] is not None: - value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i] - value = conversion_expr(src_type, dst_type, dst_native_type, value) - print ' *dst_pixel++ = %s;' % value + if format.layout == PLAIN: + if not format.is_array(): + print ' %s pixel = 0;' % dst_native_type + shift = 0; + for i in range(4): + dst_channel = format.channels[i] + width = dst_channel.size + if inv_swizzle[i] is not None: + value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i] + value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False) + if shift: + value = '(%s << %u)' % (value, shift) + print ' pixel |= %s;' % value + shift += width + print ' *dst_pixel++ = pixel;' + else: + for i in range(4): + dst_channel = format.channels[i] + if inv_swizzle[i] is not None: + value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i] + value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False) + print ' *dst_pixel++ = %s;' % value else: assert False @@ -251,28 +238,33 @@ def emit_tile_pixel_write_code(format, src_type): print ' }' -def generate_format_write(format, src_type, src_native_type, src_suffix): +def generate_format_write(format, src_channel, src_native_type, src_suffix): '''Generate the function to write pixels to a particular format''' - name = short_name(format) + name = format.short_name() print 'static void' print 'lp_tile_%s_write_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type) print '{' - if format.layout == ARITH and format.colorspace == 'rgb': - emit_unrolled_write_code(format, src_type) + if format.layout == PLAIN \ + and format.colorspace == 'rgb' \ + and format.block_size() <= 32 \ + and format.is_pot() \ + and not format.is_mixed() \ + and format.channels[0].type == UNSIGNED: + emit_unrolled_write_code(format, src_channel) else: - emit_tile_pixel_write_code(format, src_type) + emit_tile_pixel_write_code(format, src_channel) print '}' print -def generate_read(formats, dst_type, dst_native_type, dst_suffix): +def generate_read(formats, dst_channel, dst_native_type, dst_suffix): '''Generate the dispatch function to read pixels from any format''' for format in formats: if is_format_supported(format): - generate_format_read(format, dst_type, dst_native_type, dst_suffix) + generate_format_read(format, dst_channel, dst_native_type, dst_suffix) print 'void' print 'lp_tile_read_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type) @@ -282,7 +274,7 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix): for format in formats: if is_format_supported(format): print ' case %s:' % format.name - print ' func = &lp_tile_%s_read_%s;' % (short_name(format), dst_suffix) + print ' func = &lp_tile_%s_read_%s;' % (format.short_name(), dst_suffix) print ' break;' print ' default:' print ' debug_printf("unsupported format\\n");' @@ -293,12 +285,12 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix): print -def generate_write(formats, src_type, src_native_type, src_suffix): +def generate_write(formats, src_channel, src_native_type, src_suffix): '''Generate the dispatch function to write pixels to any format''' for format in formats: if is_format_supported(format): - generate_format_write(format, src_type, src_native_type, src_suffix) + generate_format_write(format, src_channel, src_native_type, src_suffix) print 'void' print 'lp_tile_write_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type) @@ -309,7 +301,7 @@ def generate_write(formats, src_type, src_native_type, src_suffix): for format in formats: if is_format_supported(format): print ' case %s:' % format.name - print ' func = &lp_tile_%s_write_%s;' % (short_name(format), src_suffix) + print ' func = &lp_tile_%s_write_%s;' % (format.short_name(), src_suffix) print ' break;' print ' default:' print ' debug_printf("unsupported format\\n");' @@ -359,12 +351,12 @@ def main(): generate_clamp() - type = Type(UNSIGNED, True, 8) + channel = Channel(UNSIGNED, True, 8) native_type = 'uint8_t' suffix = '4ub' - generate_read(formats, type, native_type, suffix) - generate_write(formats, type, native_type, suffix) + generate_read(formats, channel, native_type, suffix) + generate_write(formats, channel, native_type, suffix) if __name__ == '__main__': |