/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
* All Rights Reserved.
* Copyright 2008-2010 VMware, Inc. All rights reserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
}
}
+
+/*
+ * Here's the complete logic (HOLY CRAP) for finding next face and doing the
+ * corresponding coord wrapping, implemented by get_next_face,
+ * get_next_xcoord, get_next_ycoord.
+ * Read like that (first line):
+ * If face is +x and s coord is below zero, then
+ * new face is +z, new s is max , new t is old t
+ * (max is always cube size - 1).
+ *
+ * +x s- -> +z: s = max, t = t
+ * +x s+ -> -z: s = 0, t = t
+ * +x t- -> +y: s = max, t = max-s
+ * +x t+ -> -y: s = max, t = s
+ *
+ * -x s- -> -z: s = max, t = t
+ * -x s+ -> +z: s = 0, t = t
+ * -x t- -> +y: s = 0, t = s
+ * -x t+ -> -y: s = 0, t = max-s
+ *
+ * +y s- -> -x: s = t, t = 0
+ * +y s+ -> +x: s = max-t, t = 0
+ * +y t- -> -z: s = max-s, t = 0
+ * +y t+ -> +z: s = s, t = 0
+ *
+ * -y s- -> -x: s = max-t, t = max
+ * -y s+ -> +x: s = t, t = max
+ * -y t- -> +z: s = s, t = max
+ * -y t+ -> -z: s = max-s, t = max
+
+ * +z s- -> -x: s = max, t = t
+ * +z s+ -> +x: s = 0, t = t
+ * +z t- -> +y: s = s, t = max
+ * +z t+ -> -y: s = s, t = 0
+
+ * -z s- -> +x: s = max, t = t
+ * -z s+ -> -x: s = 0, t = t
+ * -z t- -> +y: s = max-s, t = 0
+ * -z t+ -> -y: s = max-s, t = max
+ */
+
+
/*
* seamless cubemap neighbour array.
* this array is used to find the adjacent face in each of 4 directions,
/* pos X first then neg X is Z different, Y the same */
/* PIPE_TEX_FACE_POS_X,*/
{ PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z,
- PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_POS_Y },
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
/* PIPE_TEX_FACE_NEG_X */
{ PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z,
- PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_POS_Y },
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
/* pos Y first then neg Y is X different, X the same */
/* PIPE_TEX_FACE_POS_Y */
{ PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
- PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z },
+ PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z },
/* PIPE_TEX_FACE_NEG_Y */
{ PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
- PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_Z },
+ PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z },
/* pos Z first then neg Y is X different, X the same */
/* PIPE_TEX_FACE_POS_Z */
{ PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_POS_X,
- PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_POS_Y },
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y },
/* PIPE_TEX_FACE_NEG_Z */
{ PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_NEG_X,
- PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_POS_Y }
+ PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_NEG_Y }
};
static INLINE unsigned
-get_next_face(unsigned face, int x, int y)
+get_next_face(unsigned face, int idx)
{
- int idx = 0;
+ return face_array[face][idx];
+}
- if (x == 0 && y == 0)
- return face;
- if (x == -1)
- idx = 0;
- else if (x == 1)
- idx = 1;
- else if (y == -1)
- idx = 2;
- else if (y == 1)
- idx = 3;
+/*
+ * return a new xcoord based on old face, old coords, cube size
+ * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
+ */
+static INLINE int
+get_next_xcoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
+{
+ if ((face == 0 && fall_off_index != 1) ||
+ (face == 1 && fall_off_index == 0) ||
+ (face == 4 && fall_off_index == 0) ||
+ (face == 5 && fall_off_index == 0)) {
+ return max;
+ }
+ if ((face == 1 && fall_off_index != 0) ||
+ (face == 0 && fall_off_index == 1) ||
+ (face == 4 && fall_off_index == 1) ||
+ (face == 5 && fall_off_index == 1)) {
+ return 0;
+ }
+ if ((face == 4 && fall_off_index >= 2) ||
+ (face == 2 && fall_off_index == 3) ||
+ (face == 3 && fall_off_index == 2)) {
+ return xc;
+ }
+ if ((face == 5 && fall_off_index >= 2) ||
+ (face == 2 && fall_off_index == 2) ||
+ (face == 3 && fall_off_index == 3)) {
+ return max - xc;
+ }
+ if ((face == 2 && fall_off_index == 0) ||
+ (face == 3 && fall_off_index == 1)) {
+ return yc;
+ }
+ /* (face == 2 && fall_off_index == 1) ||
+ (face == 3 && fall_off_index == 0)) */
+ return max - yc;
+}
- return face_array[face][idx];
+/*
+ * return a new ycoord based on old face, old coords, cube size
+ * and fall_off_index (0 for x-, 1 for x+, 2 for y-, 3 for y+)
+ */
+static INLINE int
+get_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
+{
+ if ((fall_off_index <= 1) && (face <= 1 || face >= 4)) {
+ return yc;
+ }
+ if (face == 2 ||
+ (face == 4 && fall_off_index == 3) ||
+ (face == 5 && fall_off_index == 2)) {
+ return 0;
+ }
+ if (face == 3 ||
+ (face == 4 && fall_off_index == 2) ||
+ (face == 5 && fall_off_index == 3)) {
+ return max;
+ }
+ if ((face == 0 && fall_off_index == 3) ||
+ (face == 1 && fall_off_index == 2)) {
+ return xc;
+ }
+ /* (face == 0 && fall_off_index == 2) ||
+ (face == 1 && fall_off_index == 3) */
+ return max - xc;
}
+
static INLINE const float *
get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
union tex_tile_address addr, int x, int y,
const struct pipe_resource *texture = sp_sview->base.texture;
unsigned level = addr.bits.level;
unsigned face = addr.bits.face;
- int new_x, new_y;
- int max_x, max_y;
- int c;
+ int new_x, new_y, max_x;
max_x = (int) u_minify(texture->width0, level);
- max_y = (int) u_minify(texture->height0, level);
+
+ assert(texture->width0 == texture->height0);
new_x = x;
new_y = y;
- /* the corner case */
- if ((x < 0 || x >= max_x) &&
- (y < 0 || y >= max_y)) {
- const float *c1, *c2, *c3;
- int fx = x < 0 ? 0 : max_x - 1;
- int fy = y < 0 ? 0 : max_y - 1;
- c1 = get_texel_2d_no_border( sp_sview, addr, fx, fy);
- addr.bits.face = get_next_face(face, (x < 0) ? -1 : 1, 0);
- c2 = get_texel_2d_no_border( sp_sview, addr, (x < 0) ? max_x - 1 : 0, fy);
- addr.bits.face = get_next_face(face, 0, (y < 0) ? -1 : 1);
- c3 = get_texel_2d_no_border( sp_sview, addr, fx, (y < 0) ? max_y - 1 : 0);
- for (c = 0; c < TGSI_QUAD_SIZE; c++)
- corner[c] = CLAMP((c1[c] + c2[c] + c3[c]), 0.0F, 1.0F) / 3;
-
- return corner;
- }
/* change the face */
if (x < 0) {
- new_x = max_x - 1;
- face = get_next_face(face, -1, 0);
+ /*
+ * Cheat with corners. They are difficult and I believe because we don't get
+ * per-pixel faces we can actually have multiple corner texels per pixel,
+ * which screws things up majorly in any case (as the per spec behavior is
+ * to average the 3 remaining texels, which we might not have).
+ * Hence just make sure that the 2nd coord is clamped, will simply pick the
+ * sample which would have fallen off the x coord, but not y coord.
+ * So the filter weight of the samples will be wrong, but at least this
+ * ensures that only valid texels near the corner are used.
+ */
+ if (y < 0 || y >= max_x) {
+ y = CLAMP(y, 0, max_x - 1);
+ }
+ new_x = get_next_xcoord(face, 0, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 0, max_x -1, x, y);
+ face = get_next_face(face, 0);
} else if (x >= max_x) {
- new_x = 0;
- face = get_next_face(face, 1, 0);
+ if (y < 0 || y >= max_x) {
+ y = CLAMP(y, 0, max_x - 1);
+ }
+ new_x = get_next_xcoord(face, 1, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 1, max_x -1, x, y);
+ face = get_next_face(face, 1);
} else if (y < 0) {
- new_y = max_y - 1;
- face = get_next_face(face, 0, -1);
- } else if (y >= max_y) {
- new_y = 0;
- face = get_next_face(face, 0, 1);
+ new_x = get_next_xcoord(face, 2, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 2, max_x -1, x, y);
+ face = get_next_face(face, 2);
+ } else if (y >= max_x) {
+ new_x = get_next_xcoord(face, 3, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 3, max_x -1, x, y);
+ face = get_next_face(face, 3);
}
addr.bits.face = face;
{
unsigned xpot = pot_level_size(sp_sview->xpot, level);
unsigned ypot = pot_level_size(sp_sview->ypot, level);
- unsigned xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
- unsigned ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
+ int xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
+ int ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
union tex_tile_address addr;
int c;
x0 = util_ifloor(u);
if (x0 < 0)
x0 = 0;
- else if (x0 > xpot - 1)
+ else if (x0 > (int) xpot - 1)
x0 = xpot - 1;
y0 = util_ifloor(v);
if (y0 < 0)
y0 = 0;
- else if (y0 > ypot - 1)
+ else if (y0 > (int) ypot - 1)
y0 = ypot - 1;
out = get_texel_2d_no_border(sp_sview, addr, x0, y0);
wrap_nearest_clamp_to_edge(s, width, &x);
wrap_nearest_clamp_to_edge(t, height, &y);
} else {
+ /* Would probably make sense to ignore mode and just do edge clamp */
sp_samp->nearest_texcoord_s(s, width, &x);
sp_samp->nearest_texcoord_t(t, height, &y);
}
* always apply wrap mode CLAMP_TO_BORDER.
*/
if (sp_samp->base.seamless_cube_map) {
+ /* Note this is a bit overkill, actual clamping is not required */
wrap_linear_clamp_to_border(s, width, &x0, &x1, &xw);
wrap_linear_clamp_to_border(t, height, &y0, &y1, &yw);
} else {
+ /* Would probably make sense to ignore mode and just do edge clamp */
sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
}
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
- const struct pipe_resource *texture = sp_sview->base.texture;
+ const struct pipe_sampler_view *psview = &sp_sview->base;
int j;
float lod[TGSI_QUAD_SIZE];
compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
- int level0 = sp_sview->base.u.tex.first_level + (int)lod[j];
+ int level0 = psview->u.tex.first_level + (int)lod[j];
if (lod[j] < 0.0)
mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
- sp_sview->base.u.tex.first_level,
+ psview->u.tex.first_level,
sp_sview->faces[j], &rgba[0][j]);
- else if (level0 >= texture->last_level)
- min_filter(sp_sview, sp_samp, s[j], t[j], p[j], texture->last_level,
+ else if (level0 >= (int) psview->u.tex.last_level)
+ min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level,
sp_sview->faces[j], &rgba[0][j]);
else {
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
- const struct pipe_resource *texture = sp_sview->base.texture;
+ const struct pipe_sampler_view *psview = &sp_sview->base;
float lod[TGSI_QUAD_SIZE];
int j;
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
if (lod[j] < 0.0)
mag_filter(sp_sview, sp_samp, s[j], t[j], p[j],
- sp_sview->base.u.tex.first_level,
+ psview->u.tex.first_level,
sp_sview->faces[j], &rgba[0][j]);
else {
- float level = sp_sview->base.u.tex.first_level + (int)(lod[j] + 0.5F) ;
- level = MIN2(level, (int)texture->last_level);
+ int level = psview->u.tex.first_level + (int)(lod[j] + 0.5F);
+ level = MIN2(level, (int)psview->u.tex.last_level);
min_filter(sp_sview, sp_samp, s[j], t[j], p[j],
level, sp_sview->faces[j], &rgba[0][j]);
}
float F = A*C-B*B/4.0f;
/* check if it is an ellipse */
- /* ASSERT(F > 0.0); */
+ /* assert(F > 0.0); */
/* Compute the ellipse's (u,v) bounding box in texture space */
float d = -B*B+4.0f*C*A;
- float box_u = 2.0f / d * sqrt(d*C*F); /* box_u -> half of bbox with */
- float box_v = 2.0f / d * sqrt(A*d*F); /* box_v -> half of bbox height */
+ float box_u = 2.0f / d * sqrtf(d*C*F); /* box_u -> half of bbox with */
+ float box_v = 2.0f / d * sqrtf(A*d*F); /* box_v -> half of bbox height */
float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
float s_buffer[TGSI_QUAD_SIZE];
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
const struct pipe_resource *texture = sp_sview->base.texture;
+ const struct pipe_sampler_view *psview = &sp_sview->base;
int level0;
float lambda;
float lod[TGSI_QUAD_SIZE];
- float s_to_u = u_minify(texture->width0, sp_sview->base.u.tex.first_level);
- float t_to_v = u_minify(texture->height0, sp_sview->base.u.tex.first_level);
+ float s_to_u = u_minify(texture->width0, psview->u.tex.first_level);
+ float t_to_v = u_minify(texture->height0, psview->u.tex.first_level);
float dudx = (s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]) * s_to_u;
float dudy = (s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]) * s_to_u;
float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v;
/* XXX: Take into account all lod values.
*/
lambda = lod[0];
- level0 = sp_sview->base.u.tex.first_level + (int)lambda;
+ level0 = psview->u.tex.first_level + (int)lambda;
/* If the ellipse covers the whole image, we can
* simply return the average of the whole image.
*/
- if (level0 >= (int) texture->last_level) {
+ if (level0 >= (int) psview->u.tex.last_level) {
int j;
for (j = 0; j < TGSI_QUAD_SIZE; j++)
- min_filter(sp_sview, sp_samp, s[j], t[j], p[j], texture->last_level,
+ min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level,
sp_sview->faces[j], &rgba[0][j]);
}
else {
enum tgsi_sampler_control control,
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
- const struct pipe_resource *texture = sp_sview->base.texture;
+ const struct pipe_sampler_view *psview = &sp_sview->base;
int j;
float lod[TGSI_QUAD_SIZE];
compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod);
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
- int level0 = sp_sview->base.u.tex.first_level + (int)lod[j];
+ int level0 = psview->u.tex.first_level + (int)lod[j];
/* Catches both negative and large values of level0:
*/
- if ((unsigned)level0 >= texture->last_level) {
+ if ((unsigned)level0 >= psview->u.tex.last_level) {
if (level0 < 0)
img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j],
- sp_sview->base.u.tex.first_level,
+ psview->u.tex.first_level,
sp_sview->faces[j], &rgba[0][j]);
else
img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j],
- sp_sview->base.texture->last_level,
+ psview->u.tex.last_level,
sp_sview->faces[j], &rgba[0][j]);
}
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
const struct pipe_sampler_state *sampler = &sp_samp->base;
- int j, k0, k1, k2, k3;
- float val;
- float pc0, pc1, pc2, pc3;
+ int j;
+ int k[4];
+ float pc[4];
+ const struct util_format_description *format_desc;
+ unsigned chan_type;
/**
* Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
if (sp_sview->base.texture->target == PIPE_TEXTURE_2D_ARRAY ||
sp_sview->base.texture->target == PIPE_TEXTURE_CUBE) {
- pc0 = CLAMP(c0[0], 0.0F, 1.0F);
- pc1 = CLAMP(c0[1], 0.0F, 1.0F);
- pc2 = CLAMP(c0[2], 0.0F, 1.0F);
- pc3 = CLAMP(c0[3], 0.0F, 1.0F);
+ pc[0] = c0[0];
+ pc[1] = c0[1];
+ pc[2] = c0[2];
+ pc[3] = c0[3];
} else if (sp_sview->base.texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
- pc0 = CLAMP(c1[0], 0.0F, 1.0F);
- pc1 = CLAMP(c1[1], 0.0F, 1.0F);
- pc2 = CLAMP(c1[2], 0.0F, 1.0F);
- pc3 = CLAMP(c1[3], 0.0F, 1.0F);
+ pc[0] = c1[0];
+ pc[1] = c1[1];
+ pc[2] = c1[2];
+ pc[3] = c1[3];
} else {
- pc0 = CLAMP(p[0], 0.0F, 1.0F);
- pc1 = CLAMP(p[1], 0.0F, 1.0F);
- pc2 = CLAMP(p[2], 0.0F, 1.0F);
- pc3 = CLAMP(p[3], 0.0F, 1.0F);
+ pc[0] = p[0];
+ pc[1] = p[1];
+ pc[2] = p[2];
+ pc[3] = p[3];
+ }
+
+ format_desc = util_format_description(sp_sview->base.format);
+ /* not entirely sure we couldn't end up with non-valid swizzle here */
+ chan_type = format_desc->swizzle[0] <= UTIL_FORMAT_SWIZZLE_W ?
+ format_desc->channel[format_desc->swizzle[0]].type :
+ UTIL_FORMAT_TYPE_FLOAT;
+ if (chan_type != UTIL_FORMAT_TYPE_FLOAT) {
+ /*
+ * clamping is a result of conversion to texture format, hence
+ * doesn't happen with floats. Technically also should do comparison
+ * in texture format (quantization!).
+ */
+ pc[0] = CLAMP(pc[0], 0.0F, 1.0F);
+ pc[1] = CLAMP(pc[1], 0.0F, 1.0F);
+ pc[2] = CLAMP(pc[2], 0.0F, 1.0F);
+ pc[3] = CLAMP(pc[3], 0.0F, 1.0F);
}
+
/* compare four texcoords vs. four texture samples */
switch (sampler->compare_func) {
case PIPE_FUNC_LESS:
- k0 = pc0 < rgba[0][0];
- k1 = pc1 < rgba[0][1];
- k2 = pc2 < rgba[0][2];
- k3 = pc3 < rgba[0][3];
+ k[0] = pc[0] < rgba[0][0];
+ k[1] = pc[1] < rgba[0][1];
+ k[2] = pc[2] < rgba[0][2];
+ k[3] = pc[3] < rgba[0][3];
break;
case PIPE_FUNC_LEQUAL:
- k0 = pc0 <= rgba[0][0];
- k1 = pc1 <= rgba[0][1];
- k2 = pc2 <= rgba[0][2];
- k3 = pc3 <= rgba[0][3];
+ k[0] = pc[0] <= rgba[0][0];
+ k[1] = pc[1] <= rgba[0][1];
+ k[2] = pc[2] <= rgba[0][2];
+ k[3] = pc[3] <= rgba[0][3];
break;
case PIPE_FUNC_GREATER:
- k0 = pc0 > rgba[0][0];
- k1 = pc1 > rgba[0][1];
- k2 = pc2 > rgba[0][2];
- k3 = pc3 > rgba[0][3];
+ k[0] = pc[0] > rgba[0][0];
+ k[1] = pc[1] > rgba[0][1];
+ k[2] = pc[2] > rgba[0][2];
+ k[3] = pc[3] > rgba[0][3];
break;
case PIPE_FUNC_GEQUAL:
- k0 = pc0 >= rgba[0][0];
- k1 = pc1 >= rgba[0][1];
- k2 = pc2 >= rgba[0][2];
- k3 = pc3 >= rgba[0][3];
+ k[0] = pc[0] >= rgba[0][0];
+ k[1] = pc[1] >= rgba[0][1];
+ k[2] = pc[2] >= rgba[0][2];
+ k[3] = pc[3] >= rgba[0][3];
break;
case PIPE_FUNC_EQUAL:
- k0 = pc0 == rgba[0][0];
- k1 = pc1 == rgba[0][1];
- k2 = pc2 == rgba[0][2];
- k3 = pc3 == rgba[0][3];
+ k[0] = pc[0] == rgba[0][0];
+ k[1] = pc[1] == rgba[0][1];
+ k[2] = pc[2] == rgba[0][2];
+ k[3] = pc[3] == rgba[0][3];
break;
case PIPE_FUNC_NOTEQUAL:
- k0 = pc0 != rgba[0][0];
- k1 = pc1 != rgba[0][1];
- k2 = pc2 != rgba[0][2];
- k3 = pc3 != rgba[0][3];
+ k[0] = pc[0] != rgba[0][0];
+ k[1] = pc[1] != rgba[0][1];
+ k[2] = pc[2] != rgba[0][2];
+ k[3] = pc[3] != rgba[0][3];
break;
case PIPE_FUNC_ALWAYS:
- k0 = k1 = k2 = k3 = 1;
+ k[0] = k[1] = k[2] = k[3] = 1;
break;
case PIPE_FUNC_NEVER:
- k0 = k1 = k2 = k3 = 0;
+ k[0] = k[1] = k[2] = k[3] = 0;
break;
default:
- k0 = k1 = k2 = k3 = 0;
+ k[0] = k[1] = k[2] = k[3] = 0;
assert(0);
break;
}
- if (sampler->mag_img_filter == PIPE_TEX_FILTER_LINEAR) {
- /* convert four pass/fail values to an intensity in [0,1] */
- /*
- * XXX this doesn't actually make much sense.
- * We just average the result of four _pixels_ and output the same
- * value for all of the four pixels of the quad.
- * This really needs to work on the _samples_ i.e. inside the img filter.
- */
- val = 0.25F * (k0 + k1 + k2 + k3);
-
- /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
- for (j = 0; j < 4; j++) {
- rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
- rgba[3][j] = 1.0F;
- }
- } else {
- for (j = 0; j < 4; j++) {
- rgba[0][j] = k0;
- rgba[1][j] = k1;
- rgba[2][j] = k2;
- rgba[3][j] = 1.0F;
- }
+ for (j = 0; j < TGSI_QUAD_SIZE; j++) {
+ rgba[0][j] = k[j];
+ rgba[1][j] = k[j];
+ rgba[2][j] = k[j];
+ rgba[3][j] = 1.0F;
}
}
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return wrap_nearest_unorm_clamp_to_border;
default:
- assert(0);
+ debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
return wrap_nearest_unorm_clamp;
}
}
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
return wrap_linear_unorm_clamp_to_border;
default:
- assert(0);
+ debug_printf("illegal wrap mode %d with non-normalized coords\n", mode);
return wrap_linear_unorm_clamp;
}
}
const struct pipe_sampler_view *view = &sp_sview->base;
const struct pipe_resource *texture = view->texture;
+ if (texture->target == PIPE_BUFFER) {
+ dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
+ /* the other values are undefined, but let's avoid potential valgrind
+ * warnings.
+ */
+ dims[1] = dims[2] = dims[3] = 0;
+ return;
+ }
+
/* undefined according to EXT_gpu_program */
level += view->u.tex.first_level;
if (level > view->u.tex.last_level)
return;
+ dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
dims[0] = u_minify(texture->width0, level);
switch(texture->target) {
dims[1] = u_minify(texture->height0, level);
dims[2] = (view->u.tex.last_layer - view->u.tex.first_layer + 1) / 6;
break;
- case PIPE_BUFFER:
- dims[0] /= util_format_get_blocksize(view->format);
- return;
default:
assert(!"unexpected texture target in sp_get_dims()");
return;
struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
- /* TODO should have defined behavior if no texture is bound. */
+ /* always have a view here but texture is NULL if no sampler view was set. */
+ if (!sp_samp->sp_sview[sview_index].base.texture) {
+ dims[0] = dims[1] = dims[2] = dims[3] = 0;
+ return;
+ }
sp_get_dims(&sp_samp->sp_sview[sview_index], level, dims);
}
assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
assert(sampler_index < PIPE_MAX_SAMPLERS);
assert(sp_samp->sp_sampler[sampler_index]);
- /* FIXME should have defined behavior if no texture is bound. */
- assert(sp_samp->sp_sview[sview_index].get_samples);
+ /* always have a view here but texture is NULL if no sampler view was set. */
+ if (!sp_samp->sp_sview[sview_index].base.texture) {
+ int i, j;
+ for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ rgba[j][i] = 0.0f;
+ }
+ }
+ return;
+ }
sp_samp->sp_sview[sview_index].get_samples(&sp_samp->sp_sview[sview_index],
sp_samp->sp_sampler[sampler_index],
s, t, p, c0, lod, control, rgba);
struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler;
assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
- /* FIXME should have defined behavior if no texture is bound. */
- assert(sp_samp->sp_sview[sview_index].base.texture);
+ /* always have a view here but texture is NULL if no sampler view was set. */
+ if (!sp_samp->sp_sview[sview_index].base.texture) {
+ int i, j;
+ for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
+ for (i = 0; i < TGSI_QUAD_SIZE; i++) {
+ rgba[j][i] = 0.0f;
+ }
+ }
+ return;
+ }
sp_get_texels(&sp_samp->sp_sview[sview_index], i, j, k, lod, offset, rgba);
}