gallium: glBitmap code now separe from glDraw/CopyPixels code
authorBrian <brian.paul@tungstengraphics.com>
Thu, 20 Mar 2008 20:50:17 +0000 (14:50 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 20 Mar 2008 21:04:08 +0000 (15:04 -0600)
Also, glBitmap now re-uses the vertex buffer to avoid frequent allocations/
deallocations.  And, use u_simple_shaders utility code.

src/mesa/sources
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_drawpixels.h
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h

index 287af7121aac22a754faa36bb1d4c78af87c695b..d109dce5bcc4b3da449020039c7366d188574ef3 100644 (file)
@@ -172,6 +172,7 @@ STATETRACKER_SOURCES = \
        state_tracker/st_atom_texture.c \
        state_tracker/st_atom_viewport.c \
        state_tracker/st_cb_accum.c \
+       state_tracker/st_cb_bitmap.c \
        state_tracker/st_cb_blit.c \
        state_tracker/st_cb_bufferobjects.c \
        state_tracker/st_cb_clear.c \
index 99d5e3e848f918a32164885b90c67695a577ff68..b4cd93cd548e31b52db0c054d61a27f152ca2e91 100644 (file)
@@ -56,6 +56,7 @@
 #include "pipe/p_inlines.h"
 #include "pipe/p_winsys.h"
 #include "util/p_tile.h"
+#include "util/u_draw_quad.h"
 #include "shader/prog_instruction.h"
 #include "cso_cache/cso_context.h"
 
@@ -85,140 +86,6 @@ is_passthrough_program(const struct gl_fragment_program *prog)
 }
 
 
-/**
- * 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_program(GLcontext *ctx)
-{
-   struct st_fragment_program *stfp;
-   struct gl_program *p;
-   GLuint ic = 0;
-
-   p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-   if (!p)
-      return NULL;
-
-   p->NumInstructions = 5;
-
-   p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
-   if (!p->Instructions) {
-      ctx->Driver.DeleteProgram(ctx, p);
-      return NULL;
-   }
-   _mesa_init_instructions(p->Instructions, p->NumInstructions);
-
-   /* 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++;
-
-   /* 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++;
-
-   /* END; */
-   p->Instructions[ic++].Opcode = OPCODE_END;
-
-   assert(ic == p->NumInstructions);
-
-   p->InputsRead = FRAG_BIT_TEX0;
-   p->OutputsWritten = 0x0;
-
-   stfp = (struct st_fragment_program *) p;
-   stfp->Base.UsesKill = GL_TRUE;
-   st_translate_fragment_program(ctx->st, stfp, NULL);
-
-   return stfp;
-}
-
-
-/**
- * Combine basic bitmap fragment program with the user-defined program.
- */
-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);
-   }
-
-   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);
-
-      /* 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
@@ -351,7 +218,7 @@ make_fragment_shader_z(struct st_context *st)
  * Create a simple vertex shader that just passes through the
  * vertex position and texcoord (and optionally, color).
  */
-struct st_vertex_program *
+static struct st_vertex_program *
 st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
 {
    /* only make programs once and re-use */
@@ -655,14 +522,14 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    cso_save_rasterizer(cso);
    cso_save_viewport(cso);
 
-   /* setup state: just scissor */
+   /* rasterizer state: just scissor */
    {
-      struct pipe_rasterizer_state  setup;
-      memset(&setup, 0, sizeof(setup));
+      struct pipe_rasterizer_state rasterizer;
+      memset(&rasterizer, 0, sizeof(rasterizer));
       if (ctx->Scissor.Enabled)
-         setup.scissor = 1;
+         rasterizer.scissor = 1;
 
-      cso_set_rasterizer(cso, &setup);
+      cso_set_rasterizer(cso, &rasterizer);
    }
 
    /* fragment shader state: TEX lookup program */
@@ -990,153 +857,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
 
 
 
-/**
- * Create a texture which represents a bitmap image.
- */
-static struct pipe_texture *
-make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
-                    const struct gl_pixelstore_attrib *unpack,
-                    const GLubyte *bitmap)
-{
-   struct pipe_context *pipe = ctx->st->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *surface;
-   uint format = 0, cpp, comp;
-   ubyte *dest;
-   struct pipe_texture *pt;
-   int row, col;
-
-   /* find a texture format we know */
-   if (screen->is_format_supported( screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE )) {
-      format = PIPE_FORMAT_U_I8;
-      cpp = 1;
-      comp = 0;
-   }
-   else if (screen->is_format_supported( screen, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE )) {
-      format = PIPE_FORMAT_A8R8G8B8_UNORM;
-      cpp = 4;
-      comp = 3; /* alpha channel */ /*XXX little-endian dependency */
-   }
-   else {
-      /* XXX support more formats */
-      assert( 0 );
-   }
-
-   /**
-    * Create a texture.
-    */
-   pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height,
-                         1, 0);
-   if (!pt)
-      return NULL;
-
-   if (unpack->BufferObj && unpack->BufferObj->Name) {
-      /*
-      pt->region = buffer_object_region(unpack->BufferObj);
-      */
-      printf("st_Bitmap (sourcing from PBO not implemented yet)\n");
-   }
-
-   surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
-   /* map texture surface */
-   dest = pipe_surface_map(surface);
-
-   /* Put image into texture surface.
-    * Note that the image is actually going to be upside down in
-    * the texture.  We deal with that with texcoords.
-    */
-
-   for (row = 0; row < height; row++) {
-      const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
-                 bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
-      ubyte *destRow = dest + row * surface->pitch * cpp;
-
-      if (unpack->LsbFirst) {
-         /* Lsb first */
-         GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
-         for (col = 0; col < width; col++) {
-
-            /* set texel to 255 if bit is set */
-            destRow[comp] = (*src & mask) ? 255 : 0;
-            destRow += cpp;
-
-            if (mask == 128U) {
-               src++;
-               mask = 1U;
-            }
-            else {
-               mask = mask << 1;
-            }
-         }
-
-         /* get ready for next row */
-         if (mask != 1)
-            src++;
-      }
-      else {
-         /* Msb first */
-         GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
-         for (col = 0; col < width; col++) {
-
-            /* set texel to 255 if bit is set */
-            destRow[comp] =(*src & mask) ? 255 : 0;
-            destRow += cpp;
-
-            if (mask == 1U) {
-               src++;
-               mask = 128U;
-            }
-            else {
-               mask = mask >> 1;
-            }
-         }
-
-         /* get ready for next row */
-         if (mask != 128)
-            src++;
-      }
-
-   } /* row */
-
-   /* Release surface */
-   pipe_surface_unmap(surface);
-   pipe_surface_reference(&surface, NULL);
-   pipe->texture_update(pipe, pt, 0, 0x1);
-
-   pt->format = format;
-
-   return pt;
-}
-
-
-
-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_fragment_program *stfp;
-   struct st_vertex_program *stvp;
-   struct st_context *st = ctx->st;
-   struct pipe_texture *pt;
-
-   stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
-   stfp = combined_bitmap_fragment_program(ctx);
-
-   st_validate_state(st);
-
-   pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
-   if (pt) {
-      draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
-                         width, height, 1.0, 1.0,
-                         pt, stvp, stfp,
-                         ctx->Current.RasterColor, GL_FALSE);
-
-      pipe_texture_reference(&pt, NULL);
-   }
-}
-
-
 static void
 copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                     GLsizei width, GLsizei height,
@@ -1337,5 +1057,4 @@ void st_init_drawpixels_functions(struct dd_function_table *functions)
 {
    functions->DrawPixels = st_DrawPixels;
    functions->CopyPixels = st_CopyPixels;
-   functions->Bitmap = st_Bitmap;
 }
index b8b906f06bce14e9127ad6c5b956627536153803..71ba487020090f08e8e9c28678c915a05733cf9e 100644 (file)
 #define ST_CB_DRAWPIXELS_H
 
 
-extern struct st_vertex_program *
-st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor);
-
-
 extern void st_init_drawpixels_functions(struct dd_function_table *functions);
 
 
index b1681be2eb5fa7ce16286118575d518bc98e03b1..d9e8722976444e028f727366c90ce9c3c074f48d 100644 (file)
@@ -35,8 +35,9 @@
 #include "st_public.h"
 #include "st_context.h"
 #include "st_cb_accum.h"
-#include "st_cb_bufferobjects.h"
+#include "st_cb_bitmap.h"
 #include "st_cb_blit.h"
+#include "st_cb_bufferobjects.h"
 #include "st_cb_clear.h"
 #include "st_cb_drawpixels.h"
 #include "st_cb_fbo.h"
@@ -154,6 +155,7 @@ static void st_destroy_context_priv( struct st_context *st )
    st_destroy_atoms( st );
    st_destroy_draw( st );
    st_destroy_generate_mipmap(st);
+   st_destroy_bitmap(st);
    st_destroy_blit(st);
    st_destroy_clear(st);
 
@@ -221,8 +223,9 @@ void st_init_driver_functions(struct dd_function_table *functions)
    _mesa_init_glsl_driver_functions(functions);
 
    st_init_accum_functions(functions);
-   st_init_bufferobject_functions(functions);
+   st_init_bitmap_functions(functions);
    st_init_blit_functions(functions);
+   st_init_bufferobject_functions(functions);
    st_init_clear_functions(functions);
    st_init_drawpixels_functions(functions);
    st_init_fbo_functions(functions);
index 2563c7fed01c8eb9e8f67bbd11e68287f0505e90..2d37086799d8d2f3f4e0987602eda98c77d3e709 100644 (file)
@@ -147,6 +147,9 @@ struct st_context
       struct st_fragment_program *program;  /**< bitmap tex/kil program */
       GLuint user_prog_sn;  /**< user fragment program serial no. */
       struct st_fragment_program *combined_prog;
+      void *vs;
+      float vertices[4][3][4];  /**< vertex pos + color + texcoord */
+      struct pipe_buffer *vbuf;
    } bitmap;
 
    /** for glClear */