gallium: glBitmap code now separe from glDraw/CopyPixels code

Also, glBitmap now re-uses the vertex buffer to avoid frequent allocations/
deallocations.  And, use u_simple_shaders utility code.
This commit is contained in:
Brian
2008-03-20 14:50:17 -06:00
parent 3ece9ace54
commit f6cd3778c5
5 changed files with 16 additions and 294 deletions

View File

@@ -172,6 +172,7 @@ STATETRACKER_SOURCES = \
state_tracker/st_atom_texture.c \ state_tracker/st_atom_texture.c \
state_tracker/st_atom_viewport.c \ state_tracker/st_atom_viewport.c \
state_tracker/st_cb_accum.c \ state_tracker/st_cb_accum.c \
state_tracker/st_cb_bitmap.c \
state_tracker/st_cb_blit.c \ state_tracker/st_cb_blit.c \
state_tracker/st_cb_bufferobjects.c \ state_tracker/st_cb_bufferobjects.c \
state_tracker/st_cb_clear.c \ state_tracker/st_cb_clear.c \

View File

@@ -56,6 +56,7 @@
#include "pipe/p_inlines.h" #include "pipe/p_inlines.h"
#include "pipe/p_winsys.h" #include "pipe/p_winsys.h"
#include "util/p_tile.h" #include "util/p_tile.h"
#include "util/u_draw_quad.h"
#include "shader/prog_instruction.h" #include "shader/prog_instruction.h"
#include "cso_cache/cso_context.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 * 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 * Create a simple vertex shader that just passes through the
* vertex position and texcoord (and optionally, color). * 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) st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
{ {
/* only make programs once and re-use */ /* 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_rasterizer(cso);
cso_save_viewport(cso); cso_save_viewport(cso);
/* setup state: just scissor */ /* rasterizer state: just scissor */
{ {
struct pipe_rasterizer_state setup; struct pipe_rasterizer_state rasterizer;
memset(&setup, 0, sizeof(setup)); memset(&rasterizer, 0, sizeof(rasterizer));
if (ctx->Scissor.Enabled) 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 */ /* 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 static void
copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLsizei width, GLsizei height, GLsizei width, GLsizei height,
@@ -1337,5 +1057,4 @@ void st_init_drawpixels_functions(struct dd_function_table *functions)
{ {
functions->DrawPixels = st_DrawPixels; functions->DrawPixels = st_DrawPixels;
functions->CopyPixels = st_CopyPixels; functions->CopyPixels = st_CopyPixels;
functions->Bitmap = st_Bitmap;
} }

View File

@@ -30,10 +30,6 @@
#define ST_CB_DRAWPIXELS_H #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); extern void st_init_drawpixels_functions(struct dd_function_table *functions);

View File

@@ -35,8 +35,9 @@
#include "st_public.h" #include "st_public.h"
#include "st_context.h" #include "st_context.h"
#include "st_cb_accum.h" #include "st_cb_accum.h"
#include "st_cb_bufferobjects.h" #include "st_cb_bitmap.h"
#include "st_cb_blit.h" #include "st_cb_blit.h"
#include "st_cb_bufferobjects.h"
#include "st_cb_clear.h" #include "st_cb_clear.h"
#include "st_cb_drawpixels.h" #include "st_cb_drawpixels.h"
#include "st_cb_fbo.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_atoms( st );
st_destroy_draw( st ); st_destroy_draw( st );
st_destroy_generate_mipmap(st); st_destroy_generate_mipmap(st);
st_destroy_bitmap(st);
st_destroy_blit(st); st_destroy_blit(st);
st_destroy_clear(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); _mesa_init_glsl_driver_functions(functions);
st_init_accum_functions(functions); st_init_accum_functions(functions);
st_init_bufferobject_functions(functions); st_init_bitmap_functions(functions);
st_init_blit_functions(functions); st_init_blit_functions(functions);
st_init_bufferobject_functions(functions);
st_init_clear_functions(functions); st_init_clear_functions(functions);
st_init_drawpixels_functions(functions); st_init_drawpixels_functions(functions);
st_init_fbo_functions(functions); st_init_fbo_functions(functions);

View File

@@ -147,6 +147,9 @@ struct st_context
struct st_fragment_program *program; /**< bitmap tex/kil program */ struct st_fragment_program *program; /**< bitmap tex/kil program */
GLuint user_prog_sn; /**< user fragment program serial no. */ GLuint user_prog_sn; /**< user fragment program serial no. */
struct st_fragment_program *combined_prog; struct st_fragment_program *combined_prog;
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
struct pipe_buffer *vbuf;
} bitmap; } bitmap;
/** for glClear */ /** for glClear */