From: Marek Olšák Date: Mon, 25 Jul 2022 00:47:26 +0000 (-0400) Subject: mesa: create glBitmap textures while creating display lists X-Git-Tag: upstream/22.3.5~4305 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb860f63f6df60a00c5a97df4cb98a2e0850d3aa;p=platform%2Fupstream%2Fmesa.git mesa: create glBitmap textures while creating display lists This makes glCallList just a textured draw, which is blazingly fast. Reviewed-by: Brian Paul Part-of: --- diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index c4cddad..594e9c5 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -52,8 +52,10 @@ #include "util/u_memory.h" #include "api_exec_decl.h" +#include "state_tracker/st_context.h" #include "state_tracker/st_cb_texture.h" #include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_sampler_view.h" static bool _mesa_glthread_should_execute_list(struct gl_context *ctx, @@ -860,9 +862,11 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) case OPCODE_DRAW_PIXELS: free(get_pointer(&n[5])); break; - case OPCODE_BITMAP: - free(get_pointer(&n[7])); + case OPCODE_BITMAP: { + struct pipe_resource *tex = get_pointer(&n[7]); + pipe_resource_reference(&tex, NULL); break; + } case OPCODE_POLYGON_STIPPLE: free(get_pointer(&n[1])); break; @@ -1336,21 +1340,32 @@ save_Bitmap(GLsizei width, GLsizei height, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + struct pipe_resource *tex = + st_make_bitmap_texture(ctx, width, height, &ctx->Unpack, pixels); + + if (!tex) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glNewList -> glBitmap"); + return; + } + n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS); - if (n) { - n[1].i = (GLint) width; - n[2].i = (GLint) height; - n[3].f = xorig; - n[4].f = yorig; - n[5].f = xmove; - n[6].f = ymove; - save_pointer(&n[7], - unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX, - GL_BITMAP, pixels, &ctx->Unpack)); + if (!n) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glNewList -> glBitmap (3)"); + pipe_resource_reference(&tex, NULL); + return; } + + n[1].i = (GLint) width; + n[2].i = (GLint) height; + n[3].f = xorig; + n[4].f = yorig; + n[5].f = xmove; + n[6].f = ymove; + save_pointer(&n[7], tex); + if (ctx->ExecuteFlag) { - CALL_Bitmap(ctx->Exec, (width, height, - xorig, yorig, xmove, ymove, pixels)); + ASSERT_OUTSIDE_BEGIN_END(ctx); + _mesa_bitmap(ctx, width, height, xorig, yorig, xmove, ymove, NULL, tex); } } @@ -10853,13 +10868,12 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui)); break; case OPCODE_BITMAP: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i, - n[3].f, n[4].f, n[5].f, n[6].f, - get_pointer(&n[7]))); - ctx->Unpack = save; /* restore */ + if (_mesa_inside_begin_end(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCallList -> glBitmap inside Begin/End"); + } else { + _mesa_bitmap(ctx, n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, + n[6].f, NULL, get_pointer(&n[7])); } break; case OPCODE_BLEND_COLOR: diff --git a/src/mesa/main/draw.h b/src/mesa/main/draw.h index 7a59964..aa65745 100644 --- a/src/mesa/main/draw.h +++ b/src/mesa/main/draw.h @@ -101,6 +101,11 @@ _mesa_draw_gallium_multimode_fallback(struct gl_context *ctx, const unsigned char *mode, unsigned num_draws); +void +_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap, struct pipe_resource *tex); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 15c60f2..627330d 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -316,13 +316,11 @@ end: } -void GLAPIENTRY -_mesa_Bitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ) +void +_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap, struct pipe_resource *tex) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0, 0); if (width < 0 || height < 0) { @@ -354,7 +352,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, GLint x = util_ifloor(ctx->Current.RasterPos[0] + epsilon - xorig); GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig); - if (ctx->Unpack.BufferObj) { + if (!tex && ctx->Unpack.BufferObj) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, GL_COLOR_INDEX, GL_BITMAP, @@ -371,7 +369,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, } } - st_Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); + st_Bitmap(ctx, x, y, width, height, &ctx->Unpack, bitmap, tex); } } else if (ctx->RenderMode == GL_FEEDBACK) { @@ -396,3 +394,13 @@ _mesa_Bitmap( GLsizei width, GLsizei height, _mesa_flush(ctx); } } + +void GLAPIENTRY +_mesa_Bitmap(GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap) +{ + GET_CURRENT_CONTEXT(ctx); + + _mesa_bitmap(ctx, width, height, xorig, yorig, xmove, ymove, bitmap, NULL); +} diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 48c28ea..8cc8b8f 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -88,6 +88,8 @@ static GLboolean UseBitmapCache = GL_TRUE; /** Epsilon for Z comparisons */ #define Z_EPSILON 1e-06 +static void +init_bitmap_state(struct st_context *st); /** * Copy user-provide bitmap bits into texture buffer, expanding @@ -114,10 +116,10 @@ unpack_bitmap(struct st_context *st, /** * Create a texture which represents a bitmap image. */ -static struct pipe_resource * -make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap) +struct pipe_resource * +st_make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; @@ -125,6 +127,9 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, ubyte *dest; struct pipe_resource *pt; + if (!st->bitmap.tex_format) + init_bitmap_state(st); + /* PBO source... */ bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap); if (!bitmap) { @@ -283,12 +288,13 @@ restore_render_state(struct gl_context *ctx) /** * Render a glBitmap by drawing a textured quad + * + * take_ownership means the callee will be resposible for unreferencing sv. */ static void draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, - struct pipe_sampler_view *sv, - const GLfloat *color) + struct pipe_sampler_view *sv, const GLfloat *color) { struct st_context *st = st_context(ctx); const float fb_width = (float) st->state.fb_width; @@ -589,15 +595,17 @@ init_bitmap_state(struct st_context *st) void st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap) + const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap, + struct pipe_resource *tex) { struct st_context *st = st_context(ctx); - struct pipe_resource *pt; assert(width > 0); assert(height > 0); st_invalidate_readpix_cache(st); + if (tex) + st_flush_bitmap_cache(st); if (!st->bitmap.tex_format) { init_bitmap_state(st); @@ -613,23 +621,30 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y, st_validate_state(st, ST_PIPELINE_META); } - if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap)) - return; + struct pipe_sampler_view *view = NULL; - pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); - if (pt) { - struct pipe_sampler_view *sv = - st_create_texture_sampler_view(st->pipe, pt); + if (!tex) { + if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap)) + return; - assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT); + struct pipe_resource *pt = + st_make_bitmap_texture(ctx, width, height, unpack, bitmap); + if (!pt) + return; - if (sv) { - draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], - width, height, sv, ctx->Current.RasterColor); - } + assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT); - /* release/free the texture */ + view = st_create_texture_sampler_view(st->pipe, pt); + /* unreference the texture because it's referenced by sv */ pipe_resource_reference(&pt, NULL); + } else { + /* tex comes from a display list. */ + view = st_create_texture_sampler_view(st->pipe, tex); + } + + if (view) { + draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2], + width, height, view, ctx->Current.RasterColor); } } diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h index 8a75886..936d49d 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.h +++ b/src/mesa/state_tracker/st_cb_bitmap.h @@ -45,8 +45,14 @@ st_destroy_bitmap(struct st_context *st); extern void st_flush_bitmap_cache(struct st_context *st); +struct pipe_resource * +st_make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap); + void st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap); + const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap, + struct pipe_resource *tex); #endif /* ST_CB_BITMAP_H */