summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-08-20 18:36:57 +0100
committerKeith Whitwell <[email protected]>2009-08-20 18:36:57 +0100
commit00c835918259f8d41c3f74eca679a972713b11b2 (patch)
treef2dc09454abd960fdcc12451181d97b6978d6e09 /src/gallium
parent0d9979d9ec5b931856d29c4ec44edb1f4931d1ac (diff)
softpipe: allow the existing sampler routines to be hooked up directly
Let eg. sp_get_samples_rect be hooked directly in as the tgsi sampler routine. Add a field to determine whether this is a vertex or fragment sampling call, and massage parameters to match the tgsi call.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c193
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h21
4 files changed, 94 insertions, 129 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index e35c6b3aec7..a0196955c87 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -230,14 +230,16 @@ softpipe_create( struct pipe_screen *screen )
/* vertex shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex;
+ softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples;
+ softpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;
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].base.get_samples = sp_get_samples;
+ softpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT;
softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];
softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];
}
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 3ed1de7e178..1f6e2ccb836 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -202,13 +202,14 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
softpipe->tgsi.vert_samplers[i].sampler = softpipe->sampler[i];
softpipe->tgsi.vert_samplers[i].texture = softpipe->texture[i];
+ softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples;
}
/* fragment shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
softpipe->tgsi.frag_samplers[i].sampler = softpipe->sampler[i];
softpipe->tgsi.frag_samplers[i].texture = softpipe->texture[i];
- softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment;
+ softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples;
}
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 2987548fb34..6c75158d598 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -41,6 +41,7 @@
#include "sp_tile_cache.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -521,15 +522,20 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
* This is only done for fragment shaders, not vertex shaders.
*/
static float
-compute_lambda(const struct pipe_texture *tex,
- const struct pipe_sampler_state *sampler,
+compute_lambda(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
float lodbias)
{
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
float rho, lambda;
+ if (samp->processor == TGSI_PROCESSOR_VERTEX)
+ return lodbias;
+
assert(sampler->normalized_coords);
assert(s);
@@ -538,7 +544,7 @@ compute_lambda(const struct pipe_texture *tex,
float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT];
dsdx = fabsf(dsdx);
dsdy = fabsf(dsdy);
- rho = MAX2(dsdx, dsdy) * tex->width[0];
+ rho = MAX2(dsdx, dsdy) * texture->width[0];
}
if (t) {
float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -546,7 +552,7 @@ compute_lambda(const struct pipe_texture *tex,
float max;
dtdx = fabsf(dtdx);
dtdy = fabsf(dtdy);
- max = MAX2(dtdx, dtdy) * tex->height[0];
+ max = MAX2(dtdx, dtdy) * texture->height[0];
rho = MAX2(rho, max);
}
if (p) {
@@ -555,7 +561,7 @@ compute_lambda(const struct pipe_texture *tex,
float max;
dpdx = fabsf(dpdx);
dpdy = fabsf(dpdy);
- max = MAX2(dpdx, dpdy) * tex->depth[0];
+ max = MAX2(dpdx, dpdy) * texture->depth[0];
rho = MAX2(rho, max);
}
@@ -579,16 +585,18 @@ compute_lambda(const struct pipe_texture *tex,
* \param imgFilter Returns either the min or mag filter, depending on lambda
*/
static void
-choose_mipmap_levels(const struct pipe_texture *texture,
- const struct pipe_sampler_state *sampler,
+choose_mipmap_levels(struct tgsi_sampler *tgsi_sampler,
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)
{
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+
if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
/* no mipmap selection needed */
*level0 = *level1 = CLAMP((int) sampler->min_lod,
@@ -598,7 +606,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
/* non-mipmapped texture, but still need to determine if doing
* minification or magnification.
*/
- float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
+ float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
if (lambda <= 0.0) {
*imgFilter = sampler->mag_img_filter;
}
@@ -611,14 +619,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
}
}
else {
- float lambda;
-
- if (computeLambda)
- /* fragment shader */
- lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
- else
- /* vertex shader */
- lambda = lodbias; /* not really a bias, but absolute LOD */
+ float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
if (lambda <= 0.0) { /* XXX threshold depends on the filter */
/* magnifying */
@@ -1028,11 +1029,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler
{
struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
int level0;
float lambda;
- lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
+ lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
level0 = (int)lambda;
if (lambda < 0.0) {
@@ -1072,11 +1072,10 @@ sp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler
* Could probably extend for 3D...
*/
static void
-sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
+sp_get_samples_2d_common(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])
@@ -1088,7 +1087,8 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
int width, height;
float levelBlend;
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
+ choose_mipmap_levels(tgsi_sampler, s, t, p,
+ lodbias,
&level0, &level1, &levelBlend, &imgFilter);
assert(sampler->normalized_coords);
@@ -1199,42 +1199,39 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
static INLINE void
-sp_get_samples_1d(const struct tgsi_sampler *sampler,
+sp_get_samples_1d(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,
- computeLambda, lodbias, rgba, faces);
+ lodbias, rgba, faces);
}
static INLINE void
-sp_get_samples_2d(const struct tgsi_sampler *sampler,
+sp_get_samples_2d(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,
- computeLambda, lodbias, rgba, faces);
+ lodbias, rgba, faces);
}
static INLINE void
-sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
+sp_get_samples_3d(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])
{
@@ -1247,7 +1244,8 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
float levelBlend;
const uint face = 0;
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
+ choose_mipmap_levels(tgsi_sampler, s, t, p,
+ lodbias,
&level0, &level1, &levelBlend, &imgFilter);
assert(sampler->normalized_coords);
@@ -1356,11 +1354,10 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
static void
-sp_get_samples_cube(const struct tgsi_sampler *sampler,
+sp_get_samples_cube(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])
{
@@ -1370,16 +1367,15 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,
faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
}
sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
- computeLambda, lodbias, rgba, faces);
+ lodbias, rgba, faces);
}
static void
-sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
+sp_get_samples_rect(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])
{
@@ -1391,7 +1387,8 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
int width, height;
float levelBlend;
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
+ choose_mipmap_levels(tgsi_sampler, s, t, p,
+ lodbias,
&level0, &level1, &levelBlend, &imgFilter);
/* texture RECTS cannot be mipmapped */
@@ -1447,90 +1444,77 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
/**
- * Common code for vertex/fragment program texture sampling.
+ * Error condition handler
*/
static INLINE void
+sp_get_samples_null(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])
+{
+ int i,j;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ rgba[i][j] = 1.0;
+}
+
+/**
+ * Called via tgsi_sampler::get_samples() when using a sampler for the
+ * first time. Determine the actual sampler function, link it in and
+ * call it.
+ */
+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])
{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
const struct pipe_texture *texture = samp->texture;
const struct pipe_sampler_state *sampler = samp->sampler;
- if (!texture)
- return;
+ /* Default to the 'undefined' case:
+ */
+ tgsi_sampler->get_samples = sp_get_samples_null;
+
+ if (!texture) {
+ assert(0); /* is this legal?? */
+ goto out;
+ }
+
+ if (!sampler->normalized_coords) {
+ assert (texture->target == PIPE_TEXTURE_2D);
+ tgsi_sampler->get_samples = sp_get_samples_rect;
+ goto out;
+ }
switch (texture->target) {
case PIPE_TEXTURE_1D:
- assert(sampler->normalized_coords);
- sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
+ tgsi_sampler->get_samples = sp_get_samples_1d;
break;
case PIPE_TEXTURE_2D:
- if (sampler->normalized_coords)
- sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- else
- sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
+ tgsi_sampler->get_samples = sp_get_samples_2d;
break;
case PIPE_TEXTURE_3D:
- assert(sampler->normalized_coords);
- sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
+ tgsi_sampler->get_samples = sp_get_samples_3d;
break;
case PIPE_TEXTURE_CUBE:
- assert(sampler->normalized_coords);
- sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
+ tgsi_sampler->get_samples = sp_get_samples_cube;
break;
default:
assert(0);
+ break;
}
-#if 0 /* DEBUG */
- {
- int i;
- printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
- for (i = 0; i < 4; i++) {
- printf("Frag %d: %f %f %f %f\n", i,
- rgba[0][i],
- rgba[1][i],
- rgba[2][i],
- rgba[3][i]);
- }
- }
-#endif
-}
-
-static void
-sp_get_samples_fallback(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 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])
-{
- struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
-
- tgsi_sampler->get_samples = sp_get_samples_fallback;
+ /* Do this elsewhere:
+ */
+ samp->xpot = util_unsigned_logbase2( samp->texture->width[0] );
+ samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );
/* Try to hook in a faster sampler. Ultimately we'll have to
* code-generate these. Luckily most of this looks like it is
@@ -1542,9 +1526,6 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
sampler->compare_mode == FALSE &&
sampler->normalized_coords)
{
- samp->xpot = util_unsigned_logbase2( samp->texture->width[0] );
- samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );
-
if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
samp->level = CLAMP((int) sampler->min_lod,
0, (int) texture->last_level);
@@ -1593,21 +1574,7 @@ sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
sampler->normalized_coords, TRUE);
}
+out:
tgsi_sampler->get_samples( tgsi_sampler, s, t, p, 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 0650c7830b9..c73ae441314 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -39,6 +39,8 @@ struct sp_shader_sampler
{
struct tgsi_sampler base; /**< base class */
+ unsigned processor;
+
/* For sp_get_samples_2d_linear_POT:
*/
unsigned xpot;
@@ -60,21 +62,14 @@ sp_shader_sampler(const struct tgsi_sampler *sampler)
}
-extern 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]);
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]);
+sp_get_samples(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 */