summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-11-08 15:01:13 -0700
committerBrian <[email protected]>2007-11-08 15:01:13 -0700
commit3d8c05f7320151898dd224c1daaf3118e1f7ea34 (patch)
tree504874ea7e432c6bd8a9a2f3aa96a7ae90dd6db7
parenta7be1c5ac25fe86c4b217625976af1eb37e48a25 (diff)
Implement shadow comparisons.
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c
index e3e607d27c9..92958400fc5 100644
--- a/src/mesa/pipe/softpipe/sp_tex_sample.c
+++ b/src/mesa/pipe/softpipe/sp_tex_sample.c
@@ -553,6 +553,50 @@ get_texel(struct tgsi_sampler *sampler,
}
+/**
+ * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
+ * When we sampled the depth texture, the depth value was put into all
+ * RGBA channels. We look at the red channel here.
+ */
+static INLINE void
+shadow_compare(uint compare_func,
+ float rgba[NUM_CHANNELS][QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ uint j)
+{
+ int k;
+ switch (compare_func) {
+ case PIPE_FUNC_LESS:
+ k = p[j] < rgba[0][j];
+ break;
+ case PIPE_FUNC_LEQUAL:
+ k = p[j] <= rgba[0][j];
+ break;
+ case PIPE_FUNC_GREATER:
+ k = p[j] > rgba[0][j];
+ break;
+ case PIPE_FUNC_GEQUAL:
+ k = p[j] >= rgba[0][j];
+ break;
+ case PIPE_FUNC_EQUAL:
+ k = p[j] == rgba[0][j];
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ k = p[j] != rgba[0][j];
+ break;
+ case PIPE_FUNC_ALWAYS:
+ k = 1;
+ break;
+ case PIPE_FUNC_NEVER:
+ k = 0;
+ break;
+ default:
+ assert(0);
+ }
+
+ rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
+}
+
/**
* Common code for sampling 1D/2D/cube textures.
@@ -567,6 +611,7 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
float rgba[NUM_CHANNELS][QUAD_SIZE],
const unsigned faces[4])
{
+ const uint compare_func = sampler->state->compare_func;
unsigned level0, level1, j, imgFilter;
int width, height;
float levelBlend;
@@ -590,6 +635,9 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
+ if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ shadow_compare(compare_func, rgba, p, j);
+ }
if (level0 != level1) {
/* get texels from second mipmap level and blend */
@@ -598,6 +646,10 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
x = x / 2;
y = y / 2;
get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
+ if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
+ shadow_compare(compare_func, rgba2, p, j);
+ }
+
for (c = 0; c < NUM_CHANNELS; c++) {
rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
}
@@ -614,6 +666,13 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
+ if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ shadow_compare(compare_func, tx, p, 0);
+ shadow_compare(compare_func, tx, p, 1);
+ shadow_compare(compare_func, tx, p, 2);
+ shadow_compare(compare_func, tx, p, 3);
+ }
+
for (c = 0; c < 4; c++) {
rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
}
@@ -629,6 +688,13 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
+ if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
+ shadow_compare(compare_func, tx, p, 0);
+ shadow_compare(compare_func, tx, p, 1);
+ shadow_compare(compare_func, tx, p, 2);
+ shadow_compare(compare_func, tx, p, 3);
+ }
+
for (c = 0; c < 4; c++) {
rgba2[c][j] = lerp_2d(a, b,
tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
@@ -669,7 +735,7 @@ sp_get_samples_2d(struct tgsi_sampler *sampler,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
static const unsigned faces[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, t, NULL, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
}