summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-04-22 18:38:37 -0600
committerBrian Paul <[email protected]>2008-04-22 18:43:05 -0600
commit33f3938d2d6340b31d758c96bd35f858c6c8267d (patch)
treeee9211f0d5733d33134936092b304ed86db758ea
parent1977fbff6010af0a5bd0bba7c0367b7713185a92 (diff)
gallium: fix some bitmap frag shader issues
If texturing happens to be enabled when glBitmap() is called, need to be careful about choosing a sampler unit, etc.
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c85
-rw-r--r--src/mesa/state_tracker/st_cb_program.c4
-rw-r--r--src/mesa/state_tracker/st_context.h3
-rw-r--r--src/mesa/state_tracker/st_program.h4
4 files changed, 62 insertions, 34 deletions
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 701d1e397e3..7752b40e8ba 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -105,7 +105,7 @@ struct bitmap_cache
* This program will be combined with the user's fragment program.
*/
static struct st_fragment_program *
-make_bitmap_fragment_program(GLcontext *ctx)
+make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex)
{
struct st_fragment_program *stfp;
struct gl_program *p;
@@ -130,7 +130,7 @@ make_bitmap_fragment_program(GLcontext *ctx)
p->Instructions[ic].DstReg.Index = 0;
p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
- p->Instructions[ic].TexSrcUnit = 0;
+ p->Instructions[ic].TexSrcUnit = samplerIndex;
p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
ic++;
@@ -148,7 +148,7 @@ make_bitmap_fragment_program(GLcontext *ctx)
p->InputsRead = FRAG_BIT_TEX0;
p->OutputsWritten = 0x0;
- p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */
+ p->SamplersUsed = (1 << samplerIndex);
stfp = (struct st_fragment_program *) p;
stfp->Base.UsesKill = GL_TRUE;
@@ -158,6 +158,19 @@ make_bitmap_fragment_program(GLcontext *ctx)
}
+static int
+find_free_bit(uint bitfield)
+{
+ int i;
+ for (i = 0; i < 32; i++) {
+ if ((bitfield & (1 << i)) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
/**
* Combine basic bitmap fragment program with the user-defined program.
*/
@@ -165,28 +178,26 @@ static struct st_fragment_program *
combined_bitmap_fragment_program(GLcontext *ctx)
{
struct st_context *st = ctx->st;
- struct st_fragment_program *stfp;
-
- if (!st->bitmap.program) {
- /* create the basic bitmap fragment program */
- st->bitmap.program = make_bitmap_fragment_program(ctx);
- }
+ struct st_fragment_program *stfp = st->fp;
- if (st->bitmap.user_prog_sn == st->fp->serialNo) {
- /* re-use */
- stfp = st->bitmap.combined_prog;
- }
- else {
- /* Concatenate the bitmap program with the current user-defined program.
+ if (!stfp->bitmap_program) {
+ /*
+ * Generate new program which is the user-defined program prefixed
+ * with the bitmap sampler/kill instructions.
*/
- stfp = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &st->bitmap.program->Base.Base,
- &st->fp->Base.Base);
+ struct st_fragment_program *bitmap_prog;
+ uint sampler;
+ sampler = find_free_bit(st->fp->Base.Base.SamplersUsed);
+ bitmap_prog = make_bitmap_fragment_program(ctx, sampler);
+
+ stfp->bitmap_program = (struct st_fragment_program *)
+ _mesa_combine_programs(ctx,
+ &bitmap_prog->Base.Base, &stfp->Base.Base);
+ stfp->bitmap_program->bitmap_sampler = sampler;
#if 0
{
- struct gl_program *p = &stfp->Base.Base;
+ struct gl_program *p = &stfp->bitmap_program->Base.Base;
printf("Combined bitmap program:\n");
_mesa_print_program(p);
printf("InputsRead: 0x%x\n", p->InputsRead);
@@ -196,11 +207,7 @@ combined_bitmap_fragment_program(GLcontext *ctx)
#endif
/* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp, NULL);
-
- /* save new program, update serial numbers */
- st->bitmap.user_prog_sn = st->fp->serialNo;
- st->bitmap.combined_prog = stfp;
+ st_translate_fragment_program(st, stfp->bitmap_program, NULL);
}
/* Ideally we'd have updated the pipe constants during the normal
@@ -208,7 +215,7 @@ combined_bitmap_fragment_program(GLcontext *ctx)
*/
st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
- return stfp;
+ return stfp->bitmap_program;
}
@@ -451,10 +458,25 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* vertex shader state: position + texcoord pass-through */
cso_set_vertex_shader_handle(cso, st->bitmap.vs);
- /* sampler / texture state */
- cso_single_sampler(cso, 0, &st->bitmap.sampler);
- cso_single_sampler_done(cso);
- pipe->set_sampler_textures(pipe, 1, &pt);
+ /* user samplers, plus our bitmap sampler */
+ {
+ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+ uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_samplers);
+ uint i;
+ for (i = 0; i < st->state.num_samplers; i++) {
+ samplers[i] = &st->state.samplers[i];
+ }
+ samplers[stfp->bitmap_sampler] = &st->bitmap.sampler;
+ cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers); }
+
+ /* user textures, plus the bitmap texture */
+ {
+ struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures);
+ memcpy(textures, st->state.sampler_texture, sizeof(textures));
+ textures[stfp->bitmap_sampler] = pt;
+ cso_set_sampler_textures(cso, num, textures);
+ }
/* viewport state: viewport matching window dims */
{
@@ -771,6 +793,7 @@ st_destroy_bitmap(struct st_context *st)
{
struct pipe_context *pipe = st->pipe;
+#if 0
if (st->bitmap.combined_prog) {
st_delete_program(st->ctx, &st->bitmap.combined_prog->Base.Base);
}
@@ -778,7 +801,7 @@ st_destroy_bitmap(struct st_context *st)
if (st->bitmap.program) {
st_delete_program(st->ctx, &st->bitmap.program->Base.Base);
}
-
+#endif
if (st->bitmap.vs) {
pipe->delete_vs_state(pipe, st->bitmap.vs);
st->bitmap.vs = NULL;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 003ec0d2b79..67f8b1f8ebb 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -159,6 +159,10 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
stfp->state.tokens = NULL;
}
+ if (stfp->bitmap_program) {
+ st_delete_program(ctx, &stfp->bitmap_program->Base.Base);
+ }
+
st_free_translated_vertex_programs(st, stfp->vertex_programs);
}
break;
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index ae1ba41d4fb..2851770d4ca 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -144,9 +144,6 @@ struct st_context
/** for glBitmap */
struct {
- struct st_fragment_program *program; /**< bitmap tex/kil program */
- GLuint user_prog_sn; /**< user fragment program serial no. */
- struct st_fragment_program *combined_prog;
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
struct pipe_shader_state vert_shader;
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index e58b8a18515..1a2062131d0 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -69,6 +69,10 @@ struct st_fragment_program
* outputs match this fragment program's inputs.
*/
struct translated_vertex_program *vertex_programs;
+
+ /** Program prefixed with glBitmap prologue */
+ struct st_fragment_program *bitmap_program;
+ uint bitmap_sampler;
};