summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-12-17 18:59:58 -0700
committerBrian Paul <brian.paul@tungstengraphics.com>2008-12-17 18:59:58 -0700
commit3ffd529ff19bf8dd7b022a267bf2afe44c7f0f65 (patch)
treee2e6059016cd83dd1af7d80a7cd6ca2965192617
parentd1c8af7c0a18340fdde45ade6f612939a3c8e62a (diff)
softpipe: fix vertex shader texture sampling
Need to disable/bypass lambda calculation since derivatives of texcoords are meaningless for adjacent vertices.
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c25
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c16
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c74
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h20
5 files changed, 98 insertions, 43 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 99b5274857..800f944838 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -221,12 +222,22 @@ softpipe_create( struct pipe_screen *screen,
softpipe->quad[i].output = sp_quad_output_stage(softpipe);
}
+ /* vertex shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- softpipe->tgsi.samplers[i].base.get_samples = sp_get_samples;
- softpipe->tgsi.samplers[i].unit = i;
- softpipe->tgsi.samplers[i].sp = softpipe;
- softpipe->tgsi.samplers[i].cache = softpipe->tex_cache[i];
- softpipe->tgsi.samplers_list[i] = &softpipe->tgsi.samplers[i];
+ softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex;
+ softpipe->tgsi.vert_samplers[i].unit = i;
+ softpipe->tgsi.vert_samplers[i].sp = softpipe;
+ softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i];
+ softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i];
+ }
+
+ /* fragment shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment;
+ softpipe->tgsi.frag_samplers[i].unit = i;
+ softpipe->tgsi.frag_samplers[i].sp = softpipe;
+ softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];
+ softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];
}
/*
@@ -237,7 +248,9 @@ softpipe_create( struct pipe_screen *screen,
goto fail;
draw_texture_samplers(softpipe->draw,
- PIPE_MAX_SAMPLERS, softpipe->tgsi.samplers_list);
+ PIPE_MAX_SAMPLERS,
+ (struct tgsi_sampler **)
+ softpipe->tgsi.vert_samplers_list);
softpipe->setup = sp_draw_render_stage(softpipe);
if (!softpipe->setup)
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 790143aecc..7ab12a6d70 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -142,8 +142,10 @@ struct softpipe_context {
/** TGSI exec things */
struct {
- struct sp_shader_sampler samplers[PIPE_MAX_SAMPLERS];
- struct sp_shader_sampler *samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
} tgsi;
/** The primitive drawing context */
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 963a2b44f5..40329a9562 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -51,8 +52,6 @@
struct quad_shade_stage
{
struct quad_stage stage; /**< base class */
- struct sp_shader_sampler samplers[PIPE_MAX_SAMPLERS];
- struct sp_shader_sampler *samplers_list[PIPE_MAX_SAMPLERS];
struct tgsi_exec_machine machine;
struct tgsi_exec_vector *inputs, *outputs;
};
@@ -151,7 +150,8 @@ static void shade_begin(struct quad_stage *qs)
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
- (struct tgsi_sampler **) qss->samplers_list );
+ (struct tgsi_sampler **)
+ softpipe->tgsi.frag_samplers_list );
qs->next->begin(qs->next);
}
@@ -184,16 +184,6 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
qss->stage.run = shade_quad;
qss->stage.destroy = shade_destroy;
- /* setup TGSI sampler state */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- assert(softpipe->tex_cache[i]);
- qss->samplers[i].base.get_samples = sp_get_samples;
- qss->samplers[i].unit = i;
- qss->samplers[i].sp = softpipe;
- qss->samplers[i].cache = softpipe->tex_cache[i];
- qss->samplers_list[i] = &qss->samplers[i];
- }
-
tgsi_exec_machine_init( &qss->machine );
return &qss->stage;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 631c60966c..32aa5025e4 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -40,11 +41,11 @@
#include "sp_tile_cache.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
-#include "tgsi/tgsi_exec.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+
/*
* Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
* see 1-pixel bands of improperly weighted linear-filtered textures.
@@ -583,6 +584,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
unsigned *level0, unsigned *level1, float *levelBlend,
unsigned *imgFilter)
@@ -611,7 +613,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
else {
float lambda;
- if (1)
+ if (computeLambda)
/* fragment shader */
lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
else
@@ -755,6 +757,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE],
const unsigned faces[4])
@@ -769,7 +772,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
int width, height;
float levelBlend;
- choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
assert(sampler->normalized_coords);
@@ -883,12 +886,14 @@ sp_get_samples_1d(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
static const unsigned faces[4] = {0, 0, 0, 0};
static const float tzero[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, s, tzero, NULL,
+ computeLambda, lodbias, rgba, faces);
}
@@ -897,11 +902,13 @@ sp_get_samples_2d(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
static const unsigned faces[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, s, t, p,
+ computeLambda, lodbias, rgba, faces);
}
@@ -910,6 +917,7 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
@@ -924,7 +932,7 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
float levelBlend;
const uint face = 0;
- choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
assert(sampler->normalized_coords);
@@ -1037,6 +1045,7 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
@@ -1045,7 +1054,8 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,
for (j = 0; j < QUAD_SIZE; j++) {
faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
}
- sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
+ computeLambda, lodbias, rgba, faces);
}
@@ -1054,6 +1064,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
@@ -1068,7 +1079,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
int width, height;
float levelBlend;
- choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
/* texture RECTS cannot be mipmapped */
@@ -1127,14 +1138,14 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
/**
- * Called via tgsi_sampler::get_samples()
- * Get four filtered RGBA values from the sampler's texture.
+ * Common code for vertex/fragment program texture sampling.
*/
-void
+static INLINE void
sp_get_samples(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
@@ -1150,21 +1161,21 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler,
switch (texture->target) {
case PIPE_TEXTURE_1D:
assert(sampler->normalized_coords);
- sp_get_samples_1d(tgsi_sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_2D:
if (sampler->normalized_coords)
- sp_get_samples_2d(tgsi_sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
else
- sp_get_samples_rect(tgsi_sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_3D:
assert(sampler->normalized_coords);
- sp_get_samples_3d(tgsi_sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_CUBE:
assert(sampler->normalized_coords);
- sp_get_samples_cube(tgsi_sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
default:
assert(0);
@@ -1185,3 +1196,34 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler,
#endif
}
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a fragment shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
+}
+
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a vertex shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
+}
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index f0a8a78778..40d8eb2c2a 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -54,12 +54,20 @@ sp_shader_sampler(const struct tgsi_sampler *sampler)
extern void
-sp_get_samples(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE]);
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
+
+extern void
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
#endif /* SP_TEX_SAMPLE_H */