Implement shader concatenation for glBitmap.

This commit is contained in:
Brian 2007-10-30 18:38:32 -06:00
parent fb9cf48259
commit 520c71161a
2 changed files with 82 additions and 40 deletions

View file

@ -59,28 +59,22 @@
/**
* Create a simple fragment shader that does a TEX() instruction to get
* the fragment color.
* If bitmapMode, use KIL instruction to kill the "0-pixels".
* Make fragment program for glBitmap:
* Sample the texture and kill the fragment if the bit is 0.
* This program will be combined with the user's fragment program.
*/
static struct st_fragment_program *
make_bitmap_fragment_shader(struct st_context *st)
make_bitmap_fragment_program(GLcontext *ctx)
{
/* only make programs once and re-use */
static struct st_fragment_program *prog = NULL;
GLcontext *ctx = st->ctx;
struct st_fragment_program *stfp;
struct gl_program *p;
GLuint ic = 0;
if (prog)
return prog;
p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
if (!p)
return NULL;
p->NumInstructions = 6;
p->NumInstructions = 5;
p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
if (!p->Instructions) {
@ -89,11 +83,6 @@ make_bitmap_fragment_shader(struct st_context *st)
}
_mesa_init_instructions(p->Instructions, p->NumInstructions);
/*
* XXX, we need to compose this fragment shader with the current
* user-provided fragment shader so the fragment program is applied
* to the fragments which aren't culled.
*/
/* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
p->Instructions[ic].Opcode = OPCODE_TEX;
p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
@ -133,34 +122,84 @@ make_bitmap_fragment_shader(struct st_context *st)
p->Instructions[ic].SrcReg[0].Index = 0;
ic++;
/* MOV result.color, fragment.color */
p->Instructions[ic].Opcode = OPCODE_MOV;
p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLR;
p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_COL0;
ic++;
/* END; */
p->Instructions[ic++].Opcode = OPCODE_END;
assert(ic == p->NumInstructions);
p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0;
p->OutputsWritten = (1 << FRAG_RESULT_COLR);
p->InputsRead = FRAG_BIT_TEX0;
p->OutputsWritten = 0x0;
stfp = (struct st_fragment_program *) p;
st_translate_fragment_program(st, stfp, NULL,
st_translate_fragment_program(ctx->st, stfp, NULL,
stfp->tokens, ST_MAX_SHADER_TOKENS);
prog = stfp;
return stfp;
}
/**
* Combine basic bitmap fragment program with the user-defined program.
*/
static struct st_fragment_program *
make_drawpix_fragment_shader(GLcontext *ctx)
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);
}
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.
*/
stfp = (struct st_fragment_program *)
_mesa_combine_programs(ctx,
&st->bitmap.program->Base.Base,
&st->fp->Base.Base);
#if 0
{
struct gl_program *p = &stfp->Base.Base;
printf("Combined bitmap program:\n");
_mesa_print_program(p);
printf("InputsRead: 0x%x\n", p->InputsRead);
printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
_mesa_print_parameter_list(p->Parameters);
}
#endif
/* translate to TGSI tokens */
st_translate_fragment_program(st, stfp, NULL,
stfp->tokens, ST_MAX_SHADER_TOKENS);
/* save new program, update serial numbers */
st->bitmap.user_prog_sn = st->fp->serialNo;
st->bitmap.combined_prog = stfp;
}
/* Ideally we'd have updated the pipe constants during the normal
* st/atom mechanism. But we can't since this is specific to glBitmap.
*/
st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
return stfp;
}
/**
* Make fragment shader for glDraw/CopyPixels. This shader is made
* by combining the pixel transfer shader with the user-defined shader.
*/
static struct st_fragment_program *
combined_drawpix_fragment_program(GLcontext *ctx)
{
struct st_context *st = ctx->st;
struct st_fragment_program *stfp;
@ -168,13 +207,13 @@ make_drawpix_fragment_shader(GLcontext *ctx)
if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
&& st->fp->serialNo == st->pixel_xfer.user_prog_sn) {
/* the pixel tranfer program has not changed and the user-defined
* shader has not changed, so re-use the combined program.
* program has not changed, so re-use the combined program.
*/
stfp = st->pixel_xfer.combined_prog;
}
else {
/* Concatenate the pixel transfer program with the current user-
* defined shader.
* defined program.
*/
stfp = (struct st_fragment_program *)
_mesa_combine_programs(ctx,
@ -241,7 +280,7 @@ make_fragment_shader_z(struct st_context *st)
}
_mesa_init_instructions(p->Instructions, p->NumInstructions);
/* TEX result.color, fragment.texcoord[0], texture[0], 2D; */
/* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */
p->Instructions[ic].Opcode = OPCODE_TEX;
p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPR;
@ -945,7 +984,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
else {
ps = st->state.framebuffer.cbufs[0];
stfp = make_drawpix_fragment_shader(ctx);
stfp = combined_drawpix_fragment_program(ctx);
stvp = make_vertex_shader(ctx->st, GL_FALSE);
color = NULL;
}
@ -1122,16 +1161,13 @@ static void
st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
{
struct st_vertex_program *stvp;
struct st_fragment_program *stfp;
struct st_vertex_program *stvp;
struct st_context *st = ctx->st;
struct pipe_mipmap_tree *mt;
/* create the fragment program */
stfp = make_bitmap_fragment_shader(ctx->st);
/* and vertex program */
stvp = make_vertex_shader(ctx->st, GL_TRUE);
stfp = combined_bitmap_fragment_program(ctx);
st_validate_state(st);
@ -1248,7 +1284,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
if (type == GL_COLOR) {
rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
color = NULL;
stfp = make_drawpix_fragment_shader(ctx);
stfp = combined_drawpix_fragment_program(ctx);
stvp = make_vertex_shader(ctx->st, GL_FALSE);
}
else {

View file

@ -142,6 +142,12 @@ struct st_context
GLuint combined_prog_sn;
} pixel_xfer;
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;
} bitmap;
/**
* Buffer object which stores the ctx->Current.Attrib[] values.
* Used for vertex array drawing when we we need an attribute for