diff options
Diffstat (limited to 'mesalib/src/gallium')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.c | 168 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.h | 26 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_dump_state.c | 9 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_format_zs.c | 2 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_inlines.h | 18 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surface.c | 55 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_surface.h | 6 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_tile.c | 38 |
8 files changed, 190 insertions, 132 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index 7c7e06219..95224020c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -127,6 +127,10 @@ struct blitter_context_priv void (*delete_fs_state)(struct pipe_context *, void *); }; +static struct pipe_surface * +util_blitter_get_next_surface_layer(struct pipe_context *pipe, + struct pipe_surface *surf); + struct blitter_context *util_blitter_create(struct pipe_context *pipe) { struct blitter_context_priv *ctx; @@ -143,6 +147,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->base.pipe = pipe; ctx->base.draw_rectangle = util_blitter_draw_rectangle; + ctx->base.get_next_surface_layer = util_blitter_get_next_surface_layer; ctx->bind_fs_state = pipe->bind_fs_state; ctx->delete_fs_state = pipe->delete_fs_state; @@ -681,6 +686,11 @@ static void blitter_set_texcoords(struct blitter_context_priv *ctx, } break; + case PIPE_TEXTURE_CUBE_ARRAY: + for (i = 0; i < 4; i++) + ctx->vertices[i][1][3] = (float) (layer / 6); /*w*/ + break; + case PIPE_TEXTURE_2D: for (i = 0; i < 4; i++) { ctx->vertices[i][1][2] = (float) sample; /*r*/ @@ -1056,14 +1066,28 @@ void util_blitter_custom_clear_depth(struct blitter_context *blitter, void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, struct pipe_resource *dst, unsigned dstlevel, - unsigned dstz, - const struct pipe_box *srcbox) + unsigned dstz) { memset(dst_templ, 0, sizeof(*dst_templ)); dst_templ->format = util_format_linear(dst->format); dst_templ->u.tex.level = dstlevel; dst_templ->u.tex.first_layer = dstz; - dst_templ->u.tex.last_layer = dstz + srcbox->depth - 1; + dst_templ->u.tex.last_layer = dstz; +} + +static struct pipe_surface * +util_blitter_get_next_surface_layer(struct pipe_context *pipe, + struct pipe_surface *surf) +{ + struct pipe_surface dst_templ; + + memset(&dst_templ, 0, sizeof(dst_templ)); + dst_templ.format = surf->format; + dst_templ.u.tex.level = surf->u.tex.level; + dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1; + dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1; + + return pipe->create_surface(pipe, surf->texture, &dst_templ); } void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, @@ -1176,12 +1200,16 @@ void util_blitter_copy_texture(struct blitter_context *blitter, struct pipe_context *pipe = ctx->base.pipe; struct pipe_surface *dst_view, dst_templ; struct pipe_sampler_view src_templ, *src_view; + struct pipe_box dstbox; assert(dst && src); assert(src->target < PIPE_MAX_TEXTURE_TYPES); + u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height), + abs(srcbox->depth), &dstbox); + /* Initialize the surface. */ - util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, srcbox); + util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); dst_view = pipe->create_surface(pipe, dst, &dst_templ); /* Initialize the sampler view. */ @@ -1189,8 +1217,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, src_view = pipe->create_sampler_view(pipe, src, &src_templ); /* Copy. */ - util_blitter_blit_generic(blitter, dst_view, dstx, dsty, - abs(srcbox->width), abs(srcbox->height), + util_blitter_blit_generic(blitter, dst_view, &dstbox, src_view, srcbox, src->width0, src->height0, mask, PIPE_TEX_FILTER_NEAREST, NULL, copy_all_samples); @@ -1201,8 +1228,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, void util_blitter_blit_generic(struct blitter_context *blitter, struct pipe_surface *dst, - int dstx, int dsty, - unsigned dst_width, unsigned dst_height, + const struct pipe_box *dstbox, struct pipe_sampler_view *src, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, @@ -1214,6 +1240,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, struct pipe_context *pipe = ctx->base.pipe; struct pipe_framebuffer_state fb_state; enum pipe_texture_target src_target = src->texture->target; + unsigned src_samples = src->texture->nr_samples; boolean has_depth, has_stencil, has_color; boolean blit_stencil, blit_depth, blit_color; void *sampler_state; @@ -1238,9 +1265,6 @@ void util_blitter_blit_generic(struct blitter_context *blitter, return; } - /* XXX should handle 3d regions */ - assert(srcbox->depth == 1); - /* Check whether the states are properly saved. */ blitter_set_running_flag(ctx); blitter_check_saved_vertex_states(ctx); @@ -1252,6 +1276,9 @@ void util_blitter_blit_generic(struct blitter_context *blitter, /* Initialize framebuffer state. */ fb_state.width = dst->width; fb_state.height = dst->height; + fb_state.nr_cbufs = blit_depth || blit_stencil ? 0 : 1; + fb_state.cbufs[0] = NULL; + fb_state.zsbuf = NULL; if (blit_depth || blit_stencil) { pipe->bind_blend_state(pipe, ctx->blend[0]); @@ -1260,41 +1287,36 @@ void util_blitter_blit_generic(struct blitter_context *blitter, pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_depthstencil(ctx, src->texture->target, - src->texture->nr_samples)); + blitter_get_fs_texfetch_depthstencil(ctx, src_target, + src_samples)); } else if (blit_depth) { pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_depth(ctx, src->texture->target, - src->texture->nr_samples)); + blitter_get_fs_texfetch_depth(ctx, src_target, + src_samples)); } else { /* is_stencil */ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_stencil(ctx, src->texture->target, - src->texture->nr_samples)); + blitter_get_fs_texfetch_stencil(ctx, src_target, + src_samples)); } - fb_state.nr_cbufs = 0; - fb_state.zsbuf = dst; } else { pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_col(ctx, src->texture->target, - src->texture->nr_samples)); - - fb_state.nr_cbufs = 1; - fb_state.cbufs[0] = dst; - fb_state.zsbuf = 0; + blitter_get_fs_texfetch_col(ctx, src_target, + src_samples)); } /* Set the linear filter only for scaled color non-MSAA blits. */ if (filter == PIPE_TEX_FILTER_LINEAR && !blit_depth && !blit_stencil && - src->texture->nr_samples <= 1 && - (dst_width != abs(srcbox->width) || dst_height != abs(srcbox->height))) { + src_samples <= 1 && + (dstbox->width != abs(srcbox->width) || + dstbox->height != abs(srcbox->height))) { sampler_state = ctx->sampler_state_linear; } else { sampler_state = ctx->sampler_state; @@ -1339,8 +1361,6 @@ void util_blitter_blit_generic(struct blitter_context *blitter, } pipe->bind_vertex_elements_state(pipe, ctx->velem_state); - pipe->set_framebuffer_state(pipe, &fb_state); - if (scissor) { pipe->set_scissor_state(pipe, scissor); } @@ -1351,7 +1371,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, if ((src_target == PIPE_TEXTURE_1D || src_target == PIPE_TEXTURE_2D || src_target == PIPE_TEXTURE_RECT) && - src->texture->nr_samples <= 1) { + src_samples <= 1) { /* Draw the quad with the draw_rectangle callback. */ /* Set texture coordinates. - use a pipe color union @@ -1363,35 +1383,72 @@ void util_blitter_blit_generic(struct blitter_context *blitter, get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f); + /* Set framebuffer state. */ + if (blit_depth || blit_stencil) { + fb_state.zsbuf = dst; + } else { + fb_state.cbufs[0] = dst; + } + pipe->set_framebuffer_state(pipe, &fb_state); + /* Draw. */ pipe->set_sample_mask(pipe, ~0); - blitter->draw_rectangle(blitter, dstx, dsty, - dstx+dst_width, dsty+dst_height, 0, + blitter->draw_rectangle(blitter, dstbox->x, dstbox->y, + dstbox->x + dstbox->width, + dstbox->y + dstbox->height, 0, UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); } else { /* Draw the quad with the generic codepath. */ - if (copy_all_samples && - src->texture->nr_samples == dst->texture->nr_samples && - dst->texture->nr_samples > 1) { - /* MSAA copy. */ - unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1; - - for (i = 0; i <= max_sample; i++) { - pipe->set_sample_mask(pipe, 1 << i); - blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, - i, srcbox->x, srcbox->y, + int z; + for (z = 0; z < dstbox->depth; z++) { + struct pipe_surface *old; + + /* Set framebuffer state. */ + if (blit_depth || blit_stencil) { + fb_state.zsbuf = dst; + } else { + fb_state.cbufs[0] = dst; + } + pipe->set_framebuffer_state(pipe, &fb_state); + + /* See if we need to blit a multisample or singlesample buffer. */ + if (copy_all_samples && + src_samples == dst->texture->nr_samples && + dst->texture->nr_samples > 1) { + unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1; + + for (i = 0; i <= max_sample; i++) { + pipe->set_sample_mask(pipe, 1 << i); + blitter_set_texcoords(ctx, src, src_width0, src_height0, + srcbox->z + z, + i, srcbox->x, srcbox->y, + srcbox->x + srcbox->width, + srcbox->y + srcbox->height); + blitter_draw(ctx, dstbox->x, dstbox->y, + dstbox->x + dstbox->width, + dstbox->y + dstbox->height, 0); + } + } else { + pipe->set_sample_mask(pipe, ~0); + blitter_set_texcoords(ctx, src, src_width0, src_height0, + srcbox->z + z, 0, + srcbox->x, srcbox->y, srcbox->x + srcbox->width, srcbox->y + srcbox->height); - blitter_draw(ctx, dstx, dsty, - dstx+dst_width, dsty+dst_height, 0); + blitter_draw(ctx, dstbox->x, dstbox->y, + dstbox->x + dstbox->width, + dstbox->y + dstbox->height, 0); + } + + /* Get the next surface or (if this is the last iteration) + * just unreference the last one. */ + old = dst; + if (z < dstbox->depth-1) { + dst = ctx->base.get_next_surface_layer(ctx->base.pipe, dst); + } + if (z) { + pipe_surface_reference(&old, NULL); } - } else { - pipe->set_sample_mask(pipe, ~0); - blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, 0, - srcbox->x, srcbox->y, - srcbox->x + srcbox->width, - srcbox->y + srcbox->height); - blitter_draw(ctx, dstx, dsty, dstx+dst_width, dsty+dst_height, 0); } } @@ -1419,7 +1476,7 @@ util_blitter_blit(struct blitter_context *blitter, /* Initialize the surface. */ util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level, - info->dst.box.z, &info->src.box); + info->dst.box.z); dst_templ.format = info->dst.format; dst_view = pipe->create_surface(pipe, dst, &dst_templ); @@ -1429,9 +1486,7 @@ util_blitter_blit(struct blitter_context *blitter, src_view = pipe->create_sampler_view(pipe, src, &src_templ); /* Copy. */ - util_blitter_blit_generic(blitter, dst_view, - info->dst.box.x, info->dst.box.y, - info->dst.box.width, info->dst.box.height, + util_blitter_blit_generic(blitter, dst_view, &info->dst.box, src_view, &info->src.box, src->width0, src->height0, info->mask, info->filter, info->scissor_enable ? &info->scissor : NULL, TRUE); @@ -1761,7 +1816,8 @@ void util_blitter_custom_color(struct blitter_context *blitter, blitter_disable_render_cond(ctx); /* bind states */ - pipe->bind_blend_state(pipe, custom_blend); + pipe->bind_blend_state(pipe, custom_blend ? custom_blend + : ctx->blend[PIPE_MASK_RGBA]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index 0b5e4aa45..20e69ed5b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -83,6 +83,15 @@ struct blitter_context enum blitter_attrib_type type, const union pipe_color_union *color); + /** + * Get the next surface layer for the pipe surface, i.e. make a copy + * of the surface and increment the first and last layer by 1. + * + * This callback is exposed, so that drivers can override it if needed. + */ + struct pipe_surface *(*get_next_surface_layer)(struct pipe_context *pipe, + struct pipe_surface *surf); + /* Whether the blitter is running. */ boolean running; @@ -217,14 +226,15 @@ void util_blitter_copy_texture(struct blitter_context *blitter, boolean copy_all_samples); /** - * Same as util_blitter_copy_texture with the capabilities of util_blitter_blit, - * but dst and src are pipe_surface and pipe_sampler_view, respectively. - * The mipmap level and dstz are part of the views. + * This is a generic implementation of pipe->blit, which accepts + * sampler/surface views instead of resources. + * + * The layer and mipmap level are specified by the views. * * Drivers can use this to change resource properties (like format, width, * height) by changing how the views interpret them, instead of changing - * pipe_resource directly. This is usually needed to accelerate copying of - * compressed formats. + * pipe_resource directly. This is used to blit resources of formats which + * are not renderable. * * src_width0 and src_height0 are sampler_view-private properties that * override pipe_resource. The blitter uses them for computation of texture @@ -236,8 +246,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, */ void util_blitter_blit_generic(struct blitter_context *blitter, struct pipe_surface *dst, - int dstx, int dsty, - unsigned dst_width, unsigned dst_height, + const struct pipe_box *dstbox, struct pipe_sampler_view *src, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, @@ -255,8 +264,7 @@ void util_blitter_blit(struct blitter_context *blitter, void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, struct pipe_resource *dst, unsigned dstlevel, - unsigned dstz, - const struct pipe_box *srcbox); + unsigned dstz); /** * Helper function to initialize a view for copy_texture_view. diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c index 09faffe73..d7df5b495 100644 --- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c +++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c @@ -681,13 +681,14 @@ util_dump_transfer(FILE *stream, const struct pipe_transfer *state) util_dump_struct_begin(stream, "pipe_transfer"); util_dump_member(stream, ptr, state, resource); - /*util_dump_member(stream, uint, state, box);*/ - + util_dump_member(stream, uint, state, level); + util_dump_member(stream, uint, state, usage); + util_dump_member_begin(stream, "box"); + util_dump_box(stream, &state->box); + util_dump_member_end(stream); util_dump_member(stream, uint, state, stride); util_dump_member(stream, uint, state, layer_stride); - /*util_dump_member(stream, ptr, state, data);*/ - util_dump_struct_end(stream); } diff --git a/mesalib/src/gallium/auxiliary/util/u_format_zs.c b/mesalib/src/gallium/auxiliary/util/u_format_zs.c index 816ef1420..ed45c52f9 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_zs.c +++ b/mesalib/src/gallium/auxiliary/util/u_format_zs.c @@ -72,7 +72,7 @@ static INLINE uint16_t z32_float_to_z16_unorm(float z) { const float scale = 0xffff; - return (uint16_t)(z * scale); + return (uint16_t)(z * scale + 0.5f); } static INLINE float diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index 582aacdca..2ff90c982 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -421,6 +421,24 @@ pipe_transfer_map(struct pipe_context *context, &box, transfer); } +static INLINE void * +pipe_transfer_map_3d(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, unsigned z, + unsigned w, unsigned h, unsigned d, + struct pipe_transfer **transfer) +{ + struct pipe_box box; + u_box_3d(x, y, z, w, h, d, &box); + return context->transfer_map(context, + resource, + level, + usage, + &box, transfer); +} + static INLINE void pipe_transfer_unmap( struct pipe_context *context, struct pipe_transfer *transfer ) diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c index 5e771c950..37f48154f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.c +++ b/mesalib/src/gallium/auxiliary/util/u_surface.c @@ -56,61 +56,6 @@ u_surface_default_template(struct pipe_surface *surf, surf->format = texture->format; } -/** - * Helper to quickly create an RGBA rendering surface of a certain size. - * \param textureOut returns the new texture - * \param surfaceOut returns the new surface - * \return TRUE for success, FALSE if failure - */ -boolean -util_create_rgba_texture(struct pipe_context *pipe, - uint width, uint height, uint bind, - struct pipe_resource **textureOut) -{ - static const enum pipe_format rgbaFormats[] = { - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_A8B8G8R8_UNORM, - PIPE_FORMAT_NONE - }; - const uint target = PIPE_TEXTURE_2D; - enum pipe_format format = PIPE_FORMAT_NONE; - struct pipe_resource templ; - struct pipe_surface surf_templ; - struct pipe_screen *screen = pipe->screen; - uint i; - - /* Choose surface format */ - for (i = 0; rgbaFormats[i]; i++) { - if (screen->is_format_supported(screen, rgbaFormats[i], - target, 0, bind)) { - format = rgbaFormats[i]; - break; - } - } - if (format == PIPE_FORMAT_NONE) - return FALSE; /* unable to get an rgba format!?! */ - - /* create texture */ - memset(&templ, 0, sizeof(templ)); - templ.target = target; - templ.format = format; - templ.last_level = 0; - templ.width0 = width; - templ.height0 = height; - templ.depth0 = 1; - templ.array_size = 1; - templ.bind = bind; - - *textureOut = screen->resource_create(screen, &templ); - if (!*textureOut) - return FALSE; - - /* create surface */ - u_surface_default_template(&surf_templ, *textureOut); - return TRUE; -} - /** * Copy 2D rect from one place to another. diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.h b/mesalib/src/gallium/auxiliary/util/u_surface.h index fe950c818..d6184acbd 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.h +++ b/mesalib/src/gallium/auxiliary/util/u_surface.h @@ -44,12 +44,6 @@ extern void u_surface_default_template(struct pipe_surface *view, const struct pipe_resource *texture); -extern boolean -util_create_rgba_texture(struct pipe_context *ctx, - uint width, uint height, uint bind, - struct pipe_resource **textureOut); - - extern void util_copy_rect(ubyte * dst, enum pipe_format format, unsigned dst_stride, unsigned dst_x, unsigned dst_y, diff --git a/mesalib/src/gallium/auxiliary/util/u_tile.c b/mesalib/src/gallium/auxiliary/util/u_tile.c index f4b5cad0e..6c618a674 100644 --- a/mesalib/src/gallium/auxiliary/util/u_tile.c +++ b/mesalib/src/gallium/auxiliary/util/u_tile.c @@ -678,6 +678,28 @@ pipe_get_tile_z(struct pipe_transfer *pt, } } break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + { + const float *ptrc = (const float *)(map + y * pt->stride + x*8); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert float Z to 32-bit Z */ + if (ptrc[j] <= 0.0) { + pDest[j*2] = 0; + } + else if (ptrc[j] >= 1.0) { + pDest[j*2] = 0xffffffff; + } + else { + double z = ptrc[j] * 0xffffffff; + pDest[j*2] = (uint) z; + } + } + pDest += dstStride; + ptrc += pt->stride/4; + } + } + break; default: assert(0); } @@ -779,7 +801,7 @@ pipe_put_tile_z(struct pipe_transfer *pt, break; case PIPE_FORMAT_Z32_FLOAT: { - float *pDest = (float *) (map + y * pt->stride + x*2); + float *pDest = (float *) (map + y * pt->stride + x*4); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit integer Z to float Z */ @@ -791,6 +813,20 @@ pipe_put_tile_z(struct pipe_transfer *pt, } } break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + { + float *pDest = (float *) (map + y * pt->stride + x*8); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit integer Z to float Z */ + const double scale = 1.0 / 0xffffffffU; + pDest[j*2] = ptrc[j] * scale; + } + pDest += pt->stride/4; + ptrc += srcStride; + } + } + break; default: assert(0); } |