From 563584a4ee853c45b7a4b60c68ac8dea4d92942d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 18 Oct 2007 13:27:10 -0600 Subject: [PATCH] checkpoint: code refactoring for glCopyPixels --- src/mesa/state_tracker/st_cb_drawpixels.c | 173 +++++++++++++++------- 1 file changed, 123 insertions(+), 50 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 03fc1340e7b..858ce176fe0 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -55,15 +55,21 @@ /** * 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". */ static struct st_fragment_program * make_fragment_shader(struct st_context *st, GLboolean bitmapMode) { + /* only make programs once and re-use */ + static struct st_fragment_program *progs[2] = { NULL, NULL }; GLcontext *ctx = st->ctx; struct st_fragment_program *stfp; struct gl_program *p; GLuint ic = 0; + if (progs[bitmapMode]) + return progs[bitmapMode]; + p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!p) return NULL; @@ -159,6 +165,8 @@ make_fragment_shader(struct st_context *st, GLboolean bitmapMode) st_translate_fragment_program(st, stfp, NULL, stfp->tokens, ST_MAX_SHADER_TOKENS); + progs[bitmapMode] = stfp; + return stfp; } @@ -166,15 +174,20 @@ make_fragment_shader(struct st_context *st, GLboolean bitmapMode) /** * Create fragment shader that does a TEX() instruction to get a Z * value, then writes to FRAG_RESULT_DEPR. + * Pass fragment color through as-is. */ static struct st_fragment_program * make_fragment_shader_z(struct st_context *st) { GLcontext *ctx = st->ctx; - struct st_fragment_program *stfp; + /* only make programs once and re-use */ + static struct st_fragment_program *stfp = NULL; struct gl_program *p; GLuint ic = 0; + if (stfp) + return stfp; + p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); if (!p) return NULL; @@ -226,16 +239,21 @@ make_fragment_shader_z(struct st_context *st) /** * Create a simple vertex shader that just passes through the - * vertex position and texcoord (and color). + * vertex position and texcoord (and optionally, color). */ static struct st_vertex_program * make_vertex_shader(struct st_context *st, GLboolean passColor) { + /* only make programs once and re-use */ + static struct st_vertex_program *progs[2] = { NULL, NULL }; GLcontext *ctx = st->ctx; struct st_vertex_program *stvp; struct gl_program *p; GLuint ic = 0; + if (progs[passColor]) + return progs[passColor]; + p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); if (!p) return NULL; @@ -292,6 +310,8 @@ make_vertex_shader(struct st_context *st, GLboolean passColor) st_translate_vertex_program(st, stvp, NULL, stvp->tokens, ST_MAX_SHADER_TOKENS); + progs[passColor] = stvp; + return stvp; } @@ -311,8 +331,51 @@ _mesa_base_format(GLenum format) +static struct pipe_mipmap_tree * +alloc_mipmap_tree(struct st_context *st, + GLsizei width, GLsizei height, uint pipeFormat) +{ + const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE; + struct pipe_mipmap_tree *mt; + GLuint cpp; + + mt = CALLOC_STRUCT(pipe_mipmap_tree); + if (!mt) + return NULL; + + cpp = st_sizeof_format(pipeFormat); + + /* allocate texture region/storage */ + mt->region = st->pipe->region_alloc(st->pipe, cpp, width, height, flags); + + mt->target = PIPE_TEXTURE_2D; + mt->internal_format = GL_RGBA; + mt->format = pipeFormat; + mt->first_level = 0; + mt->last_level = 0; + mt->width0 = width; + mt->height0 = height; + mt->depth0 = 1; + mt->cpp = cpp; + mt->compressed = 0; + mt->pitch = mt->region->pitch; + mt->depth_pitch = 0; + mt->total_height = height; + mt->level[0].level_offset = 0; + mt->level[0].width = width; + mt->level[0].height = height; + mt->level[0].depth = 1; + mt->level[0].nr_images = 1; + mt->level[0].image_offset = NULL; + mt->refcount = 1; + + return mt; +} + + /** - * Make mipmap tree containing the glDrawPixels image. + * Make mipmap tree containing an image for glDrawPixels image. + * If 'pixels' is NULL, leave the texture image data undefined. */ static struct pipe_mipmap_tree * make_mipmap_tree(struct st_context *st, @@ -322,7 +385,6 @@ make_mipmap_tree(struct st_context *st, { struct pipe_context *pipe = st->pipe; const struct gl_texture_format *mformat; - const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE; struct pipe_mipmap_tree *mt; GLuint pipeFormat, cpp; GLenum baseFormat; @@ -336,7 +398,7 @@ make_mipmap_tree(struct st_context *st, assert(pipeFormat); cpp = st_sizeof_format(pipeFormat); - mt = CALLOC_STRUCT(pipe_mipmap_tree); + mt = alloc_mipmap_tree(st, width, height, pipeFormat); if (!mt) return NULL; @@ -346,15 +408,12 @@ make_mipmap_tree(struct st_context *st, */ printf("st_DrawPixels (sourcing from PBO not implemented yet)\n"); } - else { + + { static const GLuint dstImageOffsets = 0; GLboolean success; + GLuint pitch = mt->region->pitch; GLubyte *dest; - GLuint pitch; - - /* allocate texture region/storage */ - mt->region = st->pipe->region_alloc(st->pipe, cpp, width, height, flags); - pitch = mt->region->pitch; /* map texture region */ dest = pipe->region_map(pipe, mt->region); @@ -377,10 +436,10 @@ make_mipmap_tree(struct st_context *st, /* unmap */ pipe->region_unmap(pipe, mt->region); - assert(success); } +#if 0 mt->target = PIPE_TEXTURE_2D; mt->internal_format = GL_RGBA; mt->format = pipeFormat; @@ -401,7 +460,7 @@ make_mipmap_tree(struct st_context *st, mt->level[0].nr_images = 1; mt->level[0].image_offset = NULL; mt->refcount = 1; - +#endif return mt; } @@ -804,10 +863,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { - static struct st_fragment_program *stfp_c = NULL; /* color */ - static struct st_fragment_program *stfp_z = NULL; /* z */ - static struct st_vertex_program *stvp_t = NULL; /* just emit texcoord */ - static struct st_vertex_program *stvp_c = NULL; /* emit color too */ struct st_fragment_program *stfp; struct st_vertex_program *stvp; struct st_context *st = ctx->st; @@ -820,28 +875,12 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, return; } - /* create the fragment programs if needed */ - if (!stfp_c) { - stfp_c = make_fragment_shader(ctx->st, GL_FALSE); - } - if (!stfp_z) { - stfp_z = make_fragment_shader_z(ctx->st); - } - - /* and vertex programs */ - if (!stvp_t) { - stvp_t = make_vertex_shader(ctx->st, GL_FALSE); - } - if (!stvp_c) { - stvp_c = make_vertex_shader(ctx->st, GL_TRUE); - } - st_validate_state(st); if (format == GL_DEPTH_COMPONENT) { ps = st->state.framebuffer.zbuf; - stfp = stfp_z; - stvp = stvp_c; + stfp = make_fragment_shader_z(ctx->st); + stvp = make_vertex_shader(ctx->st, GL_TRUE); color = ctx->Current.RasterColor; } else if (format == GL_STENCIL_INDEX) { @@ -851,8 +890,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } else { ps = st->state.framebuffer.cbufs[0]; - stfp = stfp_c; - stvp = stvp_t; + stfp = make_fragment_shader(ctx->st, GL_FALSE); + stvp = make_vertex_shader(ctx->st, GL_FALSE); color = NULL; } @@ -1032,19 +1071,16 @@ static void st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { - static struct st_vertex_program *stvp = NULL; - static struct st_fragment_program *stfp = NULL; + struct st_vertex_program *stvp; + struct st_fragment_program *stfp; struct st_context *st = ctx->st; struct pipe_mipmap_tree *mt; - /* create the fragment program if needed */ - if (!stfp) { - stfp = make_fragment_shader(ctx->st, GL_TRUE); - } + /* create the fragment program */ + stfp = make_fragment_shader(ctx->st, GL_TRUE); + /* and vertex program */ - if (!stvp) { - stvp = make_vertex_shader(ctx->st, GL_TRUE); - } + stvp = make_vertex_shader(ctx->st, GL_TRUE); st_validate_state(st); @@ -1138,22 +1174,59 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint dstx, GLint dsty, GLenum type) { struct st_context *st = ctx->st; + struct pipe_context *pipe = st->pipe; + struct st_renderbuffer *rbRead; + struct st_vertex_program *stvp; + struct st_fragment_program *stfp; + struct pipe_surface *psRead; + struct pipe_mipmap_tree *mt; + GLfloat *color; + uint format; st_validate_state(st); if (type == GL_STENCIL) { + /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); return; } - /* allocate a texture of size width x height */ + if (type == GL_COLOR) { + rbRead = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + color = NULL; + stfp = make_fragment_shader(ctx->st, GL_FALSE); + stvp = make_vertex_shader(ctx->st, GL_FALSE); + } + else { + rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); + color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; + stfp = make_fragment_shader_z(ctx->st); + stvp = make_vertex_shader(ctx->st, GL_TRUE); + } + + psRead = rbRead->surface; + format = psRead->format; - /* blit/copy framebuffer region into texture */ + mt = alloc_mipmap_tree(ctx->st, width, height, format); + if (!mt) + return; - /* draw textured quad */ + /* copy source framebuffer region into mipmap/texture */ + pipe->region_copy(pipe, + mt->region, /* dest */ + 0, /* dest_offset */ + 0, 0, /* destx/y */ + psRead->region, + 0, /* src_offset */ + srcx, srcy, width, height); - fprintf(stderr, "st_CopyPixels not implemented yet\n"); + /* draw textured quad */ + draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, + mt, stvp, stfp, color); + + free_mipmap_tree(st->pipe, mt); } -- 2.30.2