diff options
Diffstat (limited to 'src/gallium/auxiliary/gallivm')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c | 130 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 132 |
3 files changed, 210 insertions, 53 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index bddff2c4a13..16d57189ed4 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -64,9 +64,11 @@ * for scaled integer texcoords. * \param block_length is the length of the pixel block along the * coordinate axis - * \param coord the incoming texcoord (s,t,r or q) scaled to the texture size + * \param coord the incoming texcoord (s,t or r) scaled to the texture size + * \param coord_f the incoming texcoord (s,t or r) as float vec * \param length the texture size along one dimension * \param stride pixel stride along the coordinate axis (in bytes) + * \param offset the texel offset along the coord axis * \param is_pot if TRUE, length is a power of two * \param wrap_mode one of PIPE_TEX_WRAP_x * \param out_offset byte offset for the wrapped coordinate @@ -79,6 +81,7 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld, LLVMValueRef coord_f, LLVMValueRef length, LLVMValueRef stride, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode, LLVMValueRef *out_offset, @@ -97,6 +100,11 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld, else { struct lp_build_context *coord_bld = &bld->coord_bld; LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length); + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length_f); + coord_f = lp_build_add(coord_bld, coord_f, offset); + } coord = lp_build_fract_safe(coord_bld, coord_f); coord = lp_build_mul(coord_bld, coord, length_f); coord = lp_build_itrunc(coord_bld, coord); @@ -126,8 +134,9 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld, /** * Build LLVM code for texture coord wrapping, for nearest filtering, * for float texcoords. - * \param coord the incoming texcoord (s,t,r or q) + * \param coord the incoming texcoord (s,t or r) * \param length the texture size along one dimension + * \param offset the texel offset along the coord axis * \param is_pot if TRUE, length is a power of two * \param wrap_mode one of PIPE_TEX_WRAP_x * \param icoord the texcoord after wrapping, as int @@ -136,6 +145,7 @@ static void lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld, LLVMValueRef coord, LLVMValueRef length, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode, LLVMValueRef *icoord) @@ -145,6 +155,12 @@ lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld, switch(wrap_mode) { case PIPE_TEX_WRAP_REPEAT: + if (offset) { + /* this is definitely not ideal for POT case */ + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length); + coord = lp_build_add(coord_bld, coord, offset); + } /* take fraction, unnormalize */ coord = lp_build_fract_safe(coord_bld, coord); coord = lp_build_mul(coord_bld, coord, length); @@ -156,6 +172,10 @@ lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld, /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_minus_one); *icoord = lp_build_itrunc(coord_bld, coord); @@ -178,9 +198,11 @@ lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld, * for scaled integer texcoords. * \param block_length is the length of the pixel block along the * coordinate axis - * \param coord0 the incoming texcoord (s,t,r or q) scaled to the texture size + * \param coord0 the incoming texcoord (s,t or r) scaled to the texture size + * \param coord_f the incoming texcoord (s,t or r) as float vec * \param length the texture size along one dimension * \param stride pixel stride along the coordinate axis (in bytes) + * \param offset the texel offset along the coord axis * \param is_pot if TRUE, length is a power of two * \param wrap_mode one of PIPE_TEX_WRAP_x * \param offset0 resulting relative offset for coord0 @@ -196,6 +218,7 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld, LLVMValueRef coord_f, LLVMValueRef length, LLVMValueRef stride, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode, LLVMValueRef *offset0, @@ -230,6 +253,11 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld, LLVMValueRef mask; LLVMValueRef weight; LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld, length); + if (offset) { + offset = lp_build_int_to_float(&bld->coord_bld, offset); + offset = lp_build_div(&bld->coord_bld, offset, length_f); + coord_f = lp_build_add(&bld->coord_bld, coord_f, offset); + } lp_build_coord_repeat_npot_linear(bld, coord_f, length, length_f, &coord0, &weight); @@ -282,6 +310,11 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld, else { LLVMValueRef weight; LLVMValueRef length_f = lp_build_int_to_float(&bld->coord_bld, length); + if (offset) { + offset = lp_build_int_to_float(&bld->coord_bld, offset); + offset = lp_build_div(&bld->coord_bld, offset, length_f); + coord_f = lp_build_add(&bld->coord_bld, coord_f, offset); + } lp_build_coord_repeat_npot_linear(bld, coord_f, length, length_f, &coord0, &weight); @@ -340,8 +373,9 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld, * for float texcoords. * \param block_length is the length of the pixel block along the * coordinate axis - * \param coord the incoming texcoord (s,t,r or q) + * \param coord the incoming texcoord (s,t or r) * \param length the texture size along one dimension + * \param offset the texel offset along the coord axis * \param is_pot if TRUE, length is a power of two * \param wrap_mode one of PIPE_TEX_WRAP_x * \param coord0 the first texcoord after wrapping, as int @@ -354,6 +388,7 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld, unsigned block_length, LLVMValueRef coord, LLVMValueRef length, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode, LLVMValueRef *coord0, @@ -372,6 +407,10 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld, if (is_pot) { /* mul by size and subtract 0.5 */ coord = lp_build_mul(coord_bld, coord, length); + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } if (!force_nearest) coord = lp_build_sub(coord_bld, coord, half); *coord1 = lp_build_add(coord_bld, coord, coord_bld->one); @@ -385,6 +424,11 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld, } else { LLVMValueRef mask; + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length); + coord = lp_build_add(coord_bld, coord, offset); + } /* wrap with normalized floats is just fract */ coord = lp_build_fract(coord_bld, coord); /* unnormalize */ @@ -411,6 +455,10 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld, /* mul by tex size */ coord = lp_build_mul(coord_bld, coord, length); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } /* subtract 0.5 */ if (!force_nearest) { coord = lp_build_sub(coord_bld, coord, half); @@ -520,6 +568,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef *colors_lo, LLVMValueRef *colors_hi) { @@ -584,6 +633,17 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, if (dims >= 3) r_ipart = LLVMBuildAShr(builder, r, i32_c8, ""); + /* add texel offsets */ + if (offsets[0]) { + s_ipart = lp_build_add(&i32, s_ipart, offsets[0]); + if (dims >= 2) { + t_ipart = lp_build_add(&i32, t_ipart, offsets[1]); + if (dims >= 3) { + r_ipart = lp_build_add(&i32, r_ipart, offsets[2]); + } + } + } + /* get pixel, row, image strides */ x_stride = lp_build_const_vec(bld->gallivm, bld->int_coord_bld.type, @@ -593,7 +653,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, lp_build_sample_wrap_nearest_int(bld, bld->format_desc->block.width, s_ipart, s_float, - width_vec, x_stride, + width_vec, x_stride, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s, &x_offset, &x_subcoord); @@ -603,7 +663,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, lp_build_sample_wrap_nearest_int(bld, bld->format_desc->block.height, t_ipart, t_float, - height_vec, row_stride_vec, + height_vec, row_stride_vec, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t, &y_offset, &y_subcoord); @@ -613,7 +673,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, lp_build_sample_wrap_nearest_int(bld, 1, /* block length (depth) */ r_ipart, r_float, - depth_vec, img_stride_vec, + depth_vec, img_stride_vec, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r, &z_offset, &z_subcoord); @@ -655,6 +715,7 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef *colors_lo, LLVMValueRef *colors_hi) { @@ -677,21 +738,21 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld, /* Do texcoord wrapping */ lp_build_sample_wrap_nearest_float(bld, - s, width_vec, + s, width_vec, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s, &x_icoord); if (dims >= 2) { lp_build_sample_wrap_nearest_float(bld, - t, height_vec, + t, height_vec, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t, &y_icoord); if (dims >= 3) { lp_build_sample_wrap_nearest_float(bld, - r, depth_vec, + r, depth_vec, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r, &z_icoord); @@ -982,6 +1043,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef *colors_lo, LLVMValueRef *colors_hi) { @@ -1063,6 +1125,17 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, if (dims >= 3) r_ipart = LLVMBuildAShr(builder, r, i32_c8, ""); + /* add texel offsets */ + if (offsets[0]) { + s_ipart = lp_build_add(&i32, s_ipart, offsets[0]); + if (dims >= 2) { + t_ipart = lp_build_add(&i32, t_ipart, offsets[1]); + if (dims >= 3) { + r_ipart = lp_build_add(&i32, r_ipart, offsets[2]); + } + } + } + /* compute fractional part (AND with 0xff) */ i32_c255 = lp_build_const_int_vec(bld->gallivm, i32.type, 255); s_fpart = LLVMBuildAnd(builder, s, i32_c255, ""); @@ -1081,7 +1154,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, lp_build_sample_wrap_linear_int(bld, bld->format_desc->block.width, s_ipart, &s_fpart, s_float, - width_vec, x_stride, + width_vec, x_stride, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s, &x_offset0, &x_offset1, @@ -1113,7 +1186,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, lp_build_sample_wrap_linear_int(bld, bld->format_desc->block.height, t_ipart, &t_fpart, t_float, - height_vec, y_stride, + height_vec, y_stride, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t, &y_offset0, &y_offset1, @@ -1133,7 +1206,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, lp_build_sample_wrap_linear_int(bld, bld->format_desc->block.height, r_ipart, &r_fpart, r_float, - depth_vec, z_stride, + depth_vec, z_stride, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r, &z_offset0, &z_offset1, @@ -1171,6 +1244,7 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef *colors_lo, LLVMValueRef *colors_hi) { @@ -1204,7 +1278,7 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld, /* do texcoord wrapping and compute texel offsets */ lp_build_sample_wrap_linear_float(bld, bld->format_desc->block.width, - s, width_vec, + s, width_vec, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s, &x_icoord0, &x_icoord1, @@ -1214,7 +1288,7 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld, if (dims >= 2) { lp_build_sample_wrap_linear_float(bld, bld->format_desc->block.height, - t, height_vec, + t, height_vec, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t, &y_icoord0, &y_icoord1, @@ -1224,7 +1298,7 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld, if (dims >= 3) { lp_build_sample_wrap_linear_float(bld, bld->format_desc->block.height, - r, depth_vec, + r, depth_vec, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r, &z_icoord0, &z_icoord1, @@ -1339,6 +1413,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef ilevel0, LLVMValueRef ilevel1, LLVMValueRef lod_fpart, @@ -1377,7 +1452,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest_afloat(bld, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, &colors0_lo, &colors0_hi); } else { @@ -1385,7 +1460,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_linear_afloat(bld, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, &colors0_lo, &colors0_hi); } } @@ -1394,7 +1469,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest(bld, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, &colors0_lo, &colors0_hi); } else { @@ -1402,7 +1477,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_linear(bld, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, &colors0_lo, &colors0_hi); } } @@ -1472,14 +1547,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest_afloat(bld, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, &colors1_lo, &colors1_hi); } else { lp_build_sample_image_linear_afloat(bld, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, &colors1_lo, &colors1_hi); } } @@ -1488,14 +1563,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest(bld, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, &colors1_lo, &colors1_hi); } else { lp_build_sample_image_linear(bld, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, &colors1_lo, &colors1_hi); } } @@ -1574,6 +1649,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef lod_ipart, LLVMValueRef lod_fpart, LLVMValueRef ilevel0, @@ -1612,7 +1688,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* no need to distinguish between minification and magnification */ lp_build_sample_mipmap(bld, min_filter, mip_filter, - s, t, r, + s, t, r, offsets, ilevel0, ilevel1, lod_fpart, packed_lo, packed_hi); } @@ -1645,7 +1721,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* Use the minification filter */ lp_build_sample_mipmap(bld, min_filter, mip_filter, - s, t, r, + s, t, r, offsets, ilevel0, ilevel1, lod_fpart, packed_lo, packed_hi); } @@ -1654,7 +1730,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* Use the magnification filter */ lp_build_sample_mipmap(bld, mag_filter, PIPE_TEX_MIPFILTER_NONE, - s, t, r, + s, t, r, offsets, ilevel0, NULL, NULL, packed_lo, packed_hi); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h index 6590e8ce090..6fce9712a48 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h @@ -46,6 +46,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef lod_ipart, LLVMValueRef lod_fpart, LLVMValueRef ilevel0, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 50ccd2a1741..8aa41662d67 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -277,6 +277,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, LLVMValueRef coord, LLVMValueRef length, LLVMValueRef length_f, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode, LLVMValueRef *x0_out, @@ -296,6 +297,10 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, /* mul by size and subtract 0.5 */ coord = lp_build_mul(coord_bld, coord, length_f); coord = lp_build_sub(coord_bld, coord, half); + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } /* convert to int, compute lerp weight */ lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight); coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one); @@ -305,6 +310,11 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, } else { LLVMValueRef mask; + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length_f); + coord = lp_build_add(coord_bld, coord, offset); + } lp_build_coord_repeat_npot_linear(bld, coord, length, length_f, &coord0, &weight); @@ -321,6 +331,10 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } /* clamp to [0, length] */ coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f); @@ -341,6 +355,11 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, /* mul by tex size */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + /* clamp to length max */ coord = lp_build_min(coord_bld, coord, length_f); /* subtract 0.5 */ @@ -360,6 +379,10 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } /* was: clamp to [-0.5, length + 0.5], then sub 0.5 */ /* can skip clamp (though might not work for very large coord values */ coord = lp_build_sub(coord_bld, coord, half); @@ -375,6 +398,10 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); coord = lp_build_sub(coord_bld, coord, half); + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } /* convert to int, compute lerp weight */ lp_build_ifloor_fract(coord_bld, coord, &coord0, &weight); @@ -387,12 +414,15 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, break; case PIPE_TEX_WRAP_MIRROR_CLAMP: - coord = lp_build_abs(coord_bld, coord); - if (bld->static_sampler_state->normalized_coords) { /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + coord = lp_build_abs(coord_bld, coord); /* clamp to [0, length] */ coord = lp_build_min(coord_bld, coord, length_f); @@ -409,12 +439,16 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, LLVMValueRef min, max; struct lp_build_context abs_coord_bld = bld->coord_bld; abs_coord_bld.type.sign = FALSE; - coord = lp_build_abs(coord_bld, coord); if (bld->static_sampler_state->normalized_coords) { /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + coord = lp_build_abs(coord_bld, coord); /* clamp to [0.5, length - 0.5] */ min = half; @@ -431,12 +465,15 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: { - coord = lp_build_abs(coord_bld, coord); - if (bld->static_sampler_state->normalized_coords) { /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + coord = lp_build_abs(coord_bld, coord); /* was: clamp to [-0.5, length + 0.5] then sub 0.5 */ /* skip clamp - always positive, and other side @@ -466,6 +503,8 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld, * Build LLVM code for texture wrap mode for nearest filtering. * \param coord the incoming texcoord (nominally in [0,1]) * \param length the texture size along one dimension, as int vector + * \param length_f the texture size along one dimension, as float vector + * \param offset texel offset along one dimension (as int vector) * \param is_pot if TRUE, length is a power of two * \param wrap_mode one of PIPE_TEX_WRAP_x */ @@ -474,6 +513,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, LLVMValueRef coord, LLVMValueRef length, LLVMValueRef length_f, + LLVMValueRef offset, boolean is_pot, unsigned wrap_mode) { @@ -488,9 +528,17 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, if (is_pot) { coord = lp_build_mul(coord_bld, coord, length_f); icoord = lp_build_ifloor(coord_bld, coord); + if (offset) { + icoord = lp_build_add(int_coord_bld, icoord, offset); + } icoord = LLVMBuildAnd(builder, icoord, length_minus_one, ""); } else { + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length_f); + coord = lp_build_add(coord_bld, coord, offset); + } /* take fraction, unnormalize */ coord = lp_build_fract_safe(coord_bld, coord); coord = lp_build_mul(coord_bld, coord, length_f); @@ -508,6 +556,9 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, /* floor */ /* use itrunc instead since we clamp to 0 anyway */ icoord = lp_build_itrunc(coord_bld, coord); + if (offset) { + icoord = lp_build_add(int_coord_bld, icoord, offset); + } /* clamp to [0, length - 1]. */ icoord = lp_build_clamp(int_coord_bld, icoord, int_coord_bld->zero, @@ -521,9 +572,17 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, } /* no clamp necessary, border masking will handle this */ icoord = lp_build_ifloor(coord_bld, coord); + if (offset) { + icoord = lp_build_add(int_coord_bld, icoord, offset); + } break; case PIPE_TEX_WRAP_MIRROR_REPEAT: + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + offset = lp_build_div(coord_bld, offset, length_f); + coord = lp_build_add(coord_bld, coord, offset); + } /* compute mirror function */ coord = lp_build_coord_mirror(bld, coord); @@ -540,12 +599,15 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_MIRROR_CLAMP: case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - coord = lp_build_abs(coord_bld, coord); - if (bld->static_sampler_state->normalized_coords) { /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + coord = lp_build_abs(coord_bld, coord); /* itrunc == ifloor here */ icoord = lp_build_itrunc(coord_bld, coord); @@ -555,12 +617,15 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld, break; case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - coord = lp_build_abs(coord_bld, coord); - if (bld->static_sampler_state->normalized_coords) { /* scale coord to length */ coord = lp_build_mul(coord_bld, coord, length_f); } + if (offset) { + offset = lp_build_int_to_float(coord_bld, offset); + coord = lp_build_add(coord_bld, coord, offset); + } + coord = lp_build_abs(coord_bld, coord); /* itrunc == ifloor here */ icoord = lp_build_itrunc(coord_bld, coord); @@ -590,6 +655,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef colors_out[4]) { const unsigned dims = bld->dims; @@ -619,19 +685,19 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld, /* * Compute integer texcoords. */ - x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec, + x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s); lp_build_name(x, "tex.x.wrapped"); if (dims >= 2) { - y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec, + y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t); lp_build_name(y, "tex.y.wrapped"); if (dims == 3) { - z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec, + z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r); lp_build_name(z, "tex.z.wrapped"); @@ -670,6 +736,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef colors_out[4]) { const unsigned dims = bld->dims; @@ -702,7 +769,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, /* * Compute integer texcoords. */ - lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec, + lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec, offsets[0], bld->static_texture_state->pot_width, bld->static_sampler_state->wrap_s, &x0, &x1, &s_fpart); @@ -710,7 +777,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, lp_build_name(x1, "tex.x1.wrapped"); if (dims >= 2) { - lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec, + lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec, offsets[1], bld->static_texture_state->pot_height, bld->static_sampler_state->wrap_t, &y0, &y1, &t_fpart); @@ -718,7 +785,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld, lp_build_name(y1, "tex.y1.wrapped"); if (dims == 3) { - lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec, + lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec, offsets[2], bld->static_texture_state->pot_depth, bld->static_sampler_state->wrap_r, &z0, &z1, &r_fpart); @@ -851,6 +918,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef ilevel0, LLVMValueRef ilevel1, LLVMValueRef lod_fpart, @@ -886,7 +954,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest(bld, sampler_unit, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, colors0); } else { @@ -894,7 +962,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_linear(bld, sampler_unit, size0, row_stride0_vec, img_stride0_vec, - data_ptr0, mipoff0, s, t, r, + data_ptr0, mipoff0, s, t, r, offsets, colors0); } @@ -950,14 +1018,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld, lp_build_sample_image_nearest(bld, sampler_unit, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, colors1); } else { lp_build_sample_image_linear(bld, sampler_unit, size1, row_stride1_vec, img_stride1_vec, - data_ptr1, mipoff1, s, t, r, + data_ptr1, mipoff1, s, t, r, offsets, colors1); } @@ -1120,6 +1188,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, LLVMValueRef s, LLVMValueRef t, LLVMValueRef r, + const LLVMValueRef *offsets, LLVMValueRef lod_ipart, LLVMValueRef lod_fpart, LLVMValueRef ilevel0, @@ -1147,7 +1216,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, /* no need to distinguish between minification and magnification */ lp_build_sample_mipmap(bld, sampler_unit, min_filter, mip_filter, - s, t, r, + s, t, r, offsets, ilevel0, ilevel1, lod_fpart, texels); } @@ -1180,7 +1249,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, /* Use the minification filter */ lp_build_sample_mipmap(bld, sampler_unit, min_filter, mip_filter, - s, t, r, + s, t, r, offsets, ilevel0, ilevel1, lod_fpart, texels); } @@ -1189,7 +1258,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld, /* Use the magnification filter */ lp_build_sample_mipmap(bld, sampler_unit, mag_filter, PIPE_TEX_MIPFILTER_NONE, - s, t, r, + s, t, r, offsets, ilevel0, NULL, NULL, texels); } @@ -1605,7 +1674,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm, if (use_aos) { /* do sampling/filtering with fixed pt arithmetic */ lp_build_sample_aos(&bld, sampler_index, - s, t, r, + s, t, r, offsets, lod_ipart, lod_fpart, ilevel0, ilevel1, texel_out); @@ -1613,7 +1682,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm, else { lp_build_sample_general(&bld, sampler_index, - s, t, r, + s, t, r, offsets, lod_ipart, lod_fpart, ilevel0, ilevel1, texel_out); @@ -1681,10 +1750,21 @@ lp_build_sample_soa(struct gallivm_state *gallivm, LLVMValueRef lod_iparts, lod_fparts = NULL; LLVMValueRef ilevel0s, ilevel1s = NULL; LLVMValueRef indexi = lp_build_const_int32(gallivm, i); + LLVMValueRef offsets4[4] = { NULL }; s4 = lp_build_extract_range(gallivm, s, 4*i, 4); t4 = lp_build_extract_range(gallivm, t, 4*i, 4); r4 = lp_build_extract_range(gallivm, r, 4*i, 4); + + if (offsets[0]) { + offsets4[0] = lp_build_extract_range(gallivm, offsets[0], 4*i, 4); + if (dims > 1) { + offsets4[1] = lp_build_extract_range(gallivm, offsets[1], 4*i, 4); + if (dims > 2) { + offsets4[2] = lp_build_extract_range(gallivm, offsets[2], 4*i, 4); + } + } + } lod_iparts = LLVMBuildExtractElement(builder, lod_ipart, indexi, ""); ilevel0s = LLVMBuildExtractElement(builder, ilevel0, indexi, ""); if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) { @@ -1695,7 +1775,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm, if (use_aos) { /* do sampling/filtering with fixed pt arithmetic */ lp_build_sample_aos(&bld4, sampler_index, - s4, t4, r4, + s4, t4, r4, offsets4, lod_iparts, lod_fparts, ilevel0s, ilevel1s, texelout4); @@ -1703,7 +1783,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm, else { lp_build_sample_general(&bld4, sampler_index, - s4, t4, r4, + s4, t4, r4, offsets4, lod_iparts, lod_fparts, ilevel0s, ilevel1s, texelout4); |