summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2013-03-01 02:25:13 +0100
committerRoland Scheidegger <sroland@vmware.com>2013-03-02 02:54:30 +0100
commitb3b3b389fa7756869e7a8bc2755bce081c94945f (patch)
tree127e2e87e309c97dd503c55d2c94bf818cf55ec1
parenta99eb5c83fd64d64fee2b6d7f2bb3fea3264ce47 (diff)
gallivm: add support for texel offsets for ordinary texturing.
This was previously only handled for texelFetch (much easier). Depending on the wrap mode this works slightly differently (for somewhat efficient implementation), hence have to do that separately in all roughly 137 places - it is easy if we use fixed point coords for wrapping, however some wrapping modes are near impossible with fixed point (the repeat stuff) hence we have to normalize the offsets if we can't do the wrapping in unnormalized space (which is a division which is slow but should still be much better than the alternative, which would be integer modulo for wrapping which is just unusable). This should still give accurate results in all cases that really matter, though it might be not quite conformant behavior for some apis (but we have much worse problems there anyway even without using offsets). (Untested, no piglit test.) Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c130
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_aos.h1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c132
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
@@ -61,27 +61,30 @@
/**
* Build LLVM code for texture coord wrapping, for nearest filtering,
* 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
* \param out_i resulting sub-block pixel coordinate for coord0
*/
static void
lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld,
unsigned block_length,
LLVMValueRef coord,
LLVMValueRef coord_f,
LLVMValueRef length,
LLVMValueRef stride,
+ LLVMValueRef offset,
boolean is_pot,
unsigned wrap_mode,
LLVMValueRef *out_offset,
LLVMValueRef *out_i)
{
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
@@ -94,12 +97,17 @@ lp_build_sample_wrap_nearest_int(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_REPEAT:
if(is_pot)
coord = LLVMBuildAnd(builder, coord, length_minus_one, "");
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);
}
break;
@@ -123,42 +131,54 @@ 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
*/
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)
{
struct lp_build_context *coord_bld = &bld->coord_bld;
LLVMValueRef length_minus_one;
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);
*icoord = lp_build_itrunc(coord_bld, coord);
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
length_minus_one = lp_build_sub(coord_bld, length, coord_bld->one);
if (bld->static_sampler_state->normalized_coords) {
/* 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);
break;
case PIPE_TEX_WRAP_CLAMP:
@@ -175,15 +195,17 @@ lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld,
/**
* Build LLVM code for texture coord wrapping, for linear filtering,
* 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
* \param offset1 resulting relative offset for coord0 + 1
* \param i0 resulting sub-block pixel coordinate for coord0
* \param i1 resulting sub-block pixel coordinate for coord0 + 1
@@ -193,12 +215,13 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
unsigned block_length,
LLVMValueRef coord0,
LLVMValueRef *weight_i,
LLVMValueRef coord_f,
LLVMValueRef length,
LLVMValueRef stride,
+ LLVMValueRef offset,
boolean is_pot,
unsigned wrap_mode,
LLVMValueRef *offset0,
LLVMValueRef *offset1,
LLVMValueRef *i0,
LLVMValueRef *i1)
@@ -227,12 +250,17 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
coord1 = LLVMBuildAnd(builder, coord1, length_minus_one, "");
}
else {
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);
mask = lp_build_compare(bld->gallivm, int_coord_bld->type,
PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
coord1 = LLVMBuildAnd(builder,
@@ -279,12 +307,17 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
if (is_pot) {
coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
}
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);
weight = lp_build_mul_imm(&bld->coord_bld, weight, 256);
*weight_i = lp_build_itrunc(&bld->coord_bld, weight);
}
@@ -337,26 +370,28 @@ lp_build_sample_wrap_linear_int(struct lp_build_sample_context *bld,
/**
* Build LLVM code for texture coord wrapping, for linear filtering,
* 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
* \param coord1 the second texcoord after wrapping, as int
* \param weight the filter weight as int (0-255)
* \param force_nearest if this coord actually uses nearest filtering
*/
static void
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,
LLVMValueRef *coord1,
LLVMValueRef *weight,
unsigned force_nearest)
@@ -369,12 +404,16 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld,
switch(wrap_mode) {
case PIPE_TEX_WRAP_REPEAT:
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);
/* convert to int, compute lerp weight */
lp_build_ifloor_fract(coord_bld, coord, coord0, weight);
*coord1 = lp_build_ifloor(coord_bld, *coord1);
@@ -382,12 +421,17 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld,
length_minus_one = lp_build_itrunc(coord_bld, length_minus_one);
*coord0 = LLVMBuildAnd(builder, *coord0, length_minus_one, "");
*coord1 = LLVMBuildAnd(builder, *coord1, length_minus_one, "");
}
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 */
coord = lp_build_mul(coord_bld, coord, length);
/*
* we avoided the 0.5/length division, have to fix up wrong
@@ -408,12 +452,16 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld,
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
if (bld->static_sampler_state->normalized_coords) {
/* 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);
}
/* clamp to [0, length - 1] */
coord = lp_build_min(coord_bld, coord, length_minus_one);
@@ -517,12 +565,13 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef *colors_lo,
LLVMValueRef *colors_hi)
{
const unsigned dims = bld->dims;
LLVMBuilderRef builder = bld->gallivm->builder;
struct lp_build_context i32;
@@ -581,42 +630,53 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
if (dims >= 2)
t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
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,
bld->format_desc->block.bits/8);
/* Do texcoord wrapping, compute texel offset */
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);
offset = x_offset;
if (dims >= 2) {
LLVMValueRef y_offset;
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);
offset = lp_build_add(&bld->int_coord_bld, offset, y_offset);
if (dims >= 3) {
LLVMValueRef z_offset;
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);
offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
}
}
@@ -652,12 +712,13 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef *colors_lo,
LLVMValueRef *colors_hi)
{
const unsigned dims = bld->dims;
LLVMValueRef width_vec, height_vec, depth_vec;
LLVMValueRef offset;
@@ -674,27 +735,27 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld,
&width_vec,
&height_vec,
&depth_vec);
/* 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);
}
}
if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
@@ -979,12 +1040,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef *colors_lo,
LLVMValueRef *colors_hi)
{
const unsigned dims = bld->dims;
LLVMBuilderRef builder = bld->gallivm->builder;
struct lp_build_context i32;
@@ -1060,12 +1122,23 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
if (dims >= 2)
t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
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, "");
if (dims >= 2)
t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");
if (dims >= 3)
@@ -1078,13 +1151,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
z_stride = img_stride_vec;
/* do texcoord wrapping and compute texel offsets */
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,
&x_subcoord[0], &x_subcoord[1]);
/* add potential cube/array/mip offsets now as they are constant per pixel */
@@ -1110,13 +1183,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
}
if (dims >= 2) {
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,
&y_subcoord[0], &y_subcoord[1]);
for (z = 0; z < 2; z++) {
@@ -1130,13 +1203,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
}
if (dims >= 3) {
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,
&z_subcoord[0], &z_subcoord[1]);
for (y = 0; y < 2; y++) {
for (x = 0; x < 2; x++) {
@@ -1168,12 +1241,13 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef *colors_lo,
LLVMValueRef *colors_hi)
{
const unsigned dims = bld->dims;
LLVMValueRef width_vec, height_vec, depth_vec;
LLVMValueRef s_fpart;
@@ -1201,33 +1275,33 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld,
&height_vec,
&depth_vec);
/* 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,
&s_fpart,
bld->static_sampler_state->force_nearest_s);
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,
&t_fpart,
bld->static_sampler_state->force_nearest_t);
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,
&r_fpart, 0);
}
}
@@ -1336,12 +1410,13 @@ static void
lp_build_sample_mipmap(struct lp_build_sample_context *bld,
unsigned img_filter,
unsigned mip_filter,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef ilevel0,
LLVMValueRef ilevel1,
LLVMValueRef lod_fpart,
LLVMValueRef colors_lo_var,
LLVMValueRef colors_hi_var)
{
@@ -1374,38 +1449,38 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
if (util_cpu_caps.has_avx && bld->coord_type.length > 4) {
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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 {
assert(img_filter == PIPE_TEX_FILTER_LINEAR);
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);
}
}
else {
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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 {
assert(img_filter == PIPE_TEX_FILTER_LINEAR);
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);
}
}
/* Store the first level's colors in the output variables */
LLVMBuildStore(builder, colors0_lo, colors_lo_var);
@@ -1469,36 +1544,36 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
if (util_cpu_caps.has_avx && bld->coord_type.length > 4) {
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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);
}
}
else {
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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);
}
}
/* interpolate samples from the two mipmap levels */
@@ -1571,12 +1646,13 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
void
lp_build_sample_aos(struct lp_build_sample_context *bld,
unsigned sampler_unit,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef lod_ipart,
LLVMValueRef lod_fpart,
LLVMValueRef ilevel0,
LLVMValueRef ilevel1,
LLVMValueRef texel_out[4])
{
@@ -1609,13 +1685,13 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
packed_hi = lp_build_alloca(bld->gallivm, h16_bld.vec_type, "packed_hi");
if (min_filter == mag_filter) {
/* 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);
}
else {
/* Emit conditional to choose min image filter or mag image filter
* depending on the lod being > 0 or <= 0, respectively.
@@ -1642,22 +1718,22 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
lp_build_if(&if_ctx, bld->gallivm, minify);
{
/* 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);
}
lp_build_else(&if_ctx);
{
/* 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);
}
lp_build_endif(&if_ctx);
}
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
@@ -43,12 +43,13 @@
void
lp_build_sample_aos(struct lp_build_sample_context *bld,
unsigned sampler_unit,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef lod_ipart,
LLVMValueRef lod_fpart,
LLVMValueRef ilevel0,
LLVMValueRef ilevel1,
LLVMValueRef texel_out[4]);
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
@@ -274,12 +274,13 @@ lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
*/
static void
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,
LLVMValueRef *x1_out,
LLVMValueRef *weight_out)
{
@@ -293,21 +294,30 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
switch(wrap_mode) {
case PIPE_TEX_WRAP_REPEAT:
if (is_pot) {
/* 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);
/* repeat wrap */
coord0 = LLVMBuildAnd(builder, coord0, length_minus_one, "");
coord1 = LLVMBuildAnd(builder, coord1, length_minus_one, "");
}
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);
mask = lp_build_compare(int_coord_bld->gallivm, int_coord_bld->type,
PIPE_FUNC_NOTEQUAL, coord0, length_minus_one);
coord1 = LLVMBuildAnd(builder,
@@ -318,12 +328,16 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_CLAMP:
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);
+ }
/* clamp to [0, length] */
coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f);
coord = lp_build_sub(coord_bld, coord, half);
@@ -338,12 +352,17 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
abs_coord_bld.type.sign = FALSE;
if (bld->static_sampler_state->normalized_coords) {
/* 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 */
coord = lp_build_sub(coord_bld, coord, half);
/* clamp to [0, length - 0.5] */
coord = lp_build_max(coord_bld, coord, coord_bld->zero);
@@ -357,12 +376,16 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
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);
+ }
/* 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);
/* 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);
@@ -372,30 +395,37 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
/* compute mirror function */
coord = lp_build_coord_mirror(bld, coord);
/* 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);
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
/* coord0 = max(coord0, 0) */
coord0 = lp_build_max(int_coord_bld, coord0, int_coord_bld->zero);
/* coord1 = min(coord1, length-1) */
coord1 = lp_build_min(int_coord_bld, coord1, length_minus_one);
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);
coord = lp_build_sub(coord_bld, coord, half);
@@ -406,18 +436,22 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
{
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;
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
@@ -428,18 +462,21 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
}
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);
/* was: clamp to [-0.5, length + 0.5] then sub 0.5 */
/* skip clamp - always positive, and other side
only potentially matters for very large coords */
coord = lp_build_sub(coord_bld, coord, half);
@@ -463,20 +500,23 @@ 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
*/
static LLVMValueRef
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)
{
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMBuilderRef builder = bld->gallivm->builder;
@@ -485,15 +525,23 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
switch(wrap_mode) {
case PIPE_TEX_WRAP_REPEAT:
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);
icoord = lp_build_itrunc(coord_bld, coord);
}
break;
@@ -505,12 +553,15 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
coord = lp_build_mul(coord_bld, coord, length_f);
}
/* 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,
length_minus_one);
break;
@@ -518,15 +569,23 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
if (bld->static_sampler_state->normalized_coords) {
/* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
/* 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);
/* scale coord to length */
assert(bld->static_sampler_state->normalized_coords);
coord = lp_build_mul(coord_bld, coord, length_f);
@@ -537,33 +596,39 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
/* clamp to [0, length - 1] */
icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
break;
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);
/* clamp to [0, length - 1] */
icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
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);
break;
default:
@@ -587,12 +652,13 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef colors_out[4])
{
const unsigned dims = bld->dims;
LLVMValueRef width_vec;
LLVMValueRef height_vec;
LLVMValueRef depth_vec;
@@ -616,25 +682,25 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
flt_size,
&flt_width_vec, &flt_height_vec, &flt_depth_vec);
/*
* 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");
}
}
if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
@@ -667,12 +733,13 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
LLVMValueRef img_stride_vec,
LLVMValueRef data_ptr,
LLVMValueRef mipoffsets,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef colors_out[4])
{
const unsigned dims = bld->dims;
LLVMValueRef width_vec;
LLVMValueRef height_vec;
LLVMValueRef depth_vec;
@@ -699,29 +766,29 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
flt_size,
&flt_width_vec, &flt_height_vec, &flt_depth_vec);
/*
* 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);
lp_build_name(x0, "tex.x0.wrapped");
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);
lp_build_name(y0, "tex.y0.wrapped");
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);
lp_build_name(z0, "tex.z0.wrapped");
lp_build_name(z1, "tex.z1.wrapped");
}
@@ -848,12 +915,13 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
unsigned sampler_unit,
unsigned img_filter,
unsigned mip_filter,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef ilevel0,
LLVMValueRef ilevel1,
LLVMValueRef lod_fpart,
LLVMValueRef *colors_out)
{
LLVMBuilderRef builder = bld->gallivm->builder;
@@ -883,21 +951,21 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
mipoff0 = lp_build_get_mip_offsets(bld, ilevel0);
}
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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 {
assert(img_filter == PIPE_TEX_FILTER_LINEAR);
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);
}
/* Store the first level's colors in the output variables */
for (chan = 0; chan < 4; chan++) {
LLVMBuildStore(builder, colors0[chan], colors_out[chan]);
@@ -947,20 +1015,20 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
mipoff1 = lp_build_get_mip_offsets(bld, ilevel1);
}
if (img_filter == PIPE_TEX_FILTER_NEAREST) {
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);
}
/* interpolate samples from the two mipmap levels */
lod_fpart = lp_build_unpack_broadcast_aos_scalars(bld->gallivm,
@@ -1117,12 +1185,13 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
static void
lp_build_sample_general(struct lp_build_sample_context *bld,
unsigned sampler_unit,
LLVMValueRef s,
LLVMValueRef t,
LLVMValueRef r,
+ const LLVMValueRef *offsets,
LLVMValueRef lod_ipart,
LLVMValueRef lod_fpart,
LLVMValueRef ilevel0,
LLVMValueRef ilevel1,
LLVMValueRef *colors_out)
{
@@ -1144,13 +1213,13 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
}
if (min_filter == mag_filter) {
/* 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);
}
else {
/* Emit conditional to choose min image filter or mag image filter
* depending on the lod being > 0 or <= 0, respectively.
@@ -1177,22 +1246,22 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
lp_build_if(&if_ctx, bld->gallivm, minify);
{
/* 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);
}
lp_build_else(&if_ctx);
{
/* 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);
}
lp_build_endif(&if_ctx);
}
@@ -1602,21 +1671,21 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
ilevel0 = LLVMBuildExtractElement(builder, ilevel0, index0, "");
}
}
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);
}
else {
lp_build_sample_general(&bld, sampler_index,
- s, t, r,
+ s, t, r, offsets,
lod_ipart, lod_fpart,
ilevel0, ilevel1,
texel_out);
}
}
else {
@@ -1678,35 +1747,46 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
for (i = 0; i < num_quads; i++) {
LLVMValueRef s4, t4, r4;
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) {
ilevel1s = LLVMBuildExtractElement(builder, ilevel1, indexi, "");
lod_fparts = LLVMBuildExtractElement(builder, lod_fpart, indexi, "");
}
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);
}
else {
lp_build_sample_general(&bld4, sampler_index,
- s4, t4, r4,
+ s4, t4, r4, offsets4,
lod_iparts, lod_fparts,
ilevel0s, ilevel1s,
texelout4);
}
for (j = 0; j < 4; j++) {
texelouttmp[j][i] = texelout4[j];