diff options
author | Brian Paul <[email protected]> | 2008-04-22 18:38:37 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-04-22 18:43:05 -0600 |
commit | 33f3938d2d6340b31d758c96bd35f858c6c8267d (patch) | |
tree | ee9211f0d5733d33134936092b304ed86db758ea | |
parent | 1977fbff6010af0a5bd0bba7c0367b7713185a92 (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.c | 85 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_program.c | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.h | 4 |
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; }; |