diff options
author | Brian <brian.paul@tungstengraphics.com> | 2007-10-30 17:46:40 -0600 |
---|---|---|
committer | Brian <brian.paul@tungstengraphics.com> | 2007-10-30 17:46:40 -0600 |
commit | 2dfe0c4a24feef8b7ffc5951d9d1867661493bf2 (patch) | |
tree | 34eb17f04b87e4fae30254d8a2b9ab93569235c5 /src/mesa/state_tracker | |
parent | d6a739f6b0658414a81715bf690159f7cfdb4961 (diff) |
combine shaders for glCopyPixels
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 143 |
1 files changed, 64 insertions, 79 deletions
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c74c8fa641..1864d65ee8 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -64,26 +64,23 @@ * If bitmapMode, use KIL instruction to kill the "0-pixels". */ static struct st_fragment_program * -make_fragment_shader(struct st_context *st, GLboolean bitmapMode) +make_bitmap_fragment_shader(struct st_context *st) { /* only make programs once and re-use */ - static struct st_fragment_program *progs[2] = { NULL, NULL }; + static struct st_fragment_program *prog = NULL; GLcontext *ctx = st->ctx; struct st_fragment_program *stfp; struct gl_program *p; GLuint ic = 0; - if (progs[bitmapMode]) - return progs[bitmapMode]; + if (prog) + return prog; p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!p) return NULL; - if (bitmapMode) - p->NumInstructions = 6; - else - p->NumInstructions = 2; + p->NumInstructions = 6; p->Instructions = _mesa_alloc_instructions(p->NumInstructions); if (!p->Instructions) { @@ -91,96 +88,81 @@ make_fragment_shader(struct st_context *st, GLboolean bitmapMode) return NULL; } _mesa_init_instructions(p->Instructions, p->NumInstructions); - if (bitmapMode) { - /* - * 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; - 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].TexSrcTarget = TEXTURE_2D_INDEX; - ic++; - /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */ - p->Instructions[ic].Opcode = OPCODE_SWZ; - p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; - p->Instructions[ic].DstReg.Index = 0; - p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X; - p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[0].Index = 0; - p->Instructions[ic].SrcReg[0].Swizzle - = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE ); - ic++; + /* + * 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; + 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].TexSrcTarget = TEXTURE_2D_INDEX; + ic++; - /* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */ - p->Instructions[ic].Opcode = OPCODE_SUB; - p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; - p->Instructions[ic].DstReg.Index = 0; - p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[0].Index = 0; - p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW; - p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[1].Index = 0; - p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */ - ic++; + /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */ + p->Instructions[ic].Opcode = OPCODE_SWZ; + p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; + p->Instructions[ic].DstReg.Index = 0; + p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X; + p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + p->Instructions[ic].SrcReg[0].Index = 0; + p->Instructions[ic].SrcReg[0].Swizzle + = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE ); + ic++; - /* KIL if tmp0 < 0 */ - p->Instructions[ic].Opcode = OPCODE_KIL; - p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[0].Index = 0; - ic++; + /* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */ + p->Instructions[ic].Opcode = OPCODE_SUB; + p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; + p->Instructions[ic].DstReg.Index = 0; + p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + p->Instructions[ic].SrcReg[0].Index = 0; + p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW; + p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY; + p->Instructions[ic].SrcReg[1].Index = 0; + p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */ + ic++; + + /* KIL if tmp0 < 0 */ + p->Instructions[ic].Opcode = OPCODE_KIL; + p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + 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++; - /* 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++; - } - else { - /* DrawPixels mode */ - /* TEX result.color, 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_COLR; - 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].TexSrcTarget = TEXTURE_2D_INDEX; - ic++; - } /* END; */ p->Instructions[ic++].Opcode = OPCODE_END; assert(ic == p->NumInstructions); - p->InputsRead = FRAG_BIT_TEX0; + p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0; p->OutputsWritten = (1 << FRAG_RESULT_COLR); - if (bitmapMode) { - p->InputsRead |= FRAG_BIT_COL0; - } stfp = (struct st_fragment_program *) p; st_translate_fragment_program(st, stfp, NULL, stfp->tokens, ST_MAX_SHADER_TOKENS); - progs[bitmapMode] = stfp; + prog = stfp; return stfp; } static struct st_fragment_program * -make_drawpix_fragment_shader(struct st_context *st) +make_drawpix_fragment_shader(GLcontext *ctx) { - GLcontext *ctx = st->ctx; + struct st_context *st = ctx->st; struct st_fragment_program *stfp; if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn @@ -963,7 +945,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->st); + stfp = make_drawpix_fragment_shader(ctx); stvp = make_vertex_shader(ctx->st, GL_FALSE); color = NULL; } @@ -1146,7 +1128,7 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct pipe_mipmap_tree *mt; /* create the fragment program */ - stfp = make_fragment_shader(ctx->st, GL_TRUE); + stfp = make_bitmap_fragment_shader(ctx->st); /* and vertex program */ stvp = make_vertex_shader(ctx->st, GL_TRUE); @@ -1252,6 +1234,9 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLfloat *color; uint format; + /* make sure rendering has completed */ + pipe->flush(pipe, 0x0); + st_validate_state(st); if (type == GL_STENCIL) { @@ -1263,7 +1248,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (type == GL_COLOR) { rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); color = NULL; - stfp = make_fragment_shader(ctx->st, GL_FALSE); + stfp = make_drawpix_fragment_shader(ctx); stvp = make_vertex_shader(ctx->st, GL_FALSE); } else { |