From 3ffd529ff19bf8dd7b022a267bf2afe44c7f0f65 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 17 Dec 2008 18:59:58 -0700 Subject: softpipe: fix vertex shader texture sampling Need to disable/bypass lambda calculation since derivatives of texcoords are meaningless for adjacent vertices. --- src/gallium/drivers/softpipe/sp_context.c | 25 +++++++--- src/gallium/drivers/softpipe/sp_context.h | 6 ++- src/gallium/drivers/softpipe/sp_quad_fs.c | 16 ++---- src/gallium/drivers/softpipe/sp_tex_sample.c | 74 ++++++++++++++++++++++------ src/gallium/drivers/softpipe/sp_tex_sample.h | 20 +++++--- 5 files changed, 98 insertions(+), 43 deletions(-) (limited to 'src/gallium/drivers/softpipe') 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 */ -- cgit v1.2.3