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:
@@ -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 \
|
||||||
|
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user