mesa: create glBitmap textures while creating display lists
This makes glCallList just a textured draw, which is blazingly fast. Reviewed-by: Brian Paul <brianp@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17780>
This commit is contained in:
@@ -52,8 +52,10 @@
|
|||||||
#include "util/u_memory.h"
|
#include "util/u_memory.h"
|
||||||
#include "api_exec_decl.h"
|
#include "api_exec_decl.h"
|
||||||
|
|
||||||
|
#include "state_tracker/st_context.h"
|
||||||
#include "state_tracker/st_cb_texture.h"
|
#include "state_tracker/st_cb_texture.h"
|
||||||
#include "state_tracker/st_cb_bitmap.h"
|
#include "state_tracker/st_cb_bitmap.h"
|
||||||
|
#include "state_tracker/st_sampler_view.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_mesa_glthread_should_execute_list(struct gl_context *ctx,
|
_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:
|
case OPCODE_DRAW_PIXELS:
|
||||||
free(get_pointer(&n[5]));
|
free(get_pointer(&n[5]));
|
||||||
break;
|
break;
|
||||||
case OPCODE_BITMAP:
|
case OPCODE_BITMAP: {
|
||||||
free(get_pointer(&n[7]));
|
struct pipe_resource *tex = get_pointer(&n[7]);
|
||||||
|
pipe_resource_reference(&tex, NULL);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case OPCODE_POLYGON_STIPPLE:
|
case OPCODE_POLYGON_STIPPLE:
|
||||||
free(get_pointer(&n[1]));
|
free(get_pointer(&n[1]));
|
||||||
break;
|
break;
|
||||||
@@ -1336,21 +1340,32 @@ save_Bitmap(GLsizei width, GLsizei height,
|
|||||||
GET_CURRENT_CONTEXT(ctx);
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
Node *n;
|
Node *n;
|
||||||
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
|
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
|
||||||
n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS);
|
struct pipe_resource *tex =
|
||||||
if (n) {
|
st_make_bitmap_texture(ctx, width, height, &ctx->Unpack, pixels);
|
||||||
n[1].i = (GLint) width;
|
|
||||||
n[2].i = (GLint) height;
|
if (!tex) {
|
||||||
n[3].f = xorig;
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glNewList -> glBitmap");
|
||||||
n[4].f = yorig;
|
return;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS);
|
||||||
|
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) {
|
if (ctx->ExecuteFlag) {
|
||||||
CALL_Bitmap(ctx->Exec, (width, height,
|
ASSERT_OUTSIDE_BEGIN_END(ctx);
|
||||||
xorig, yorig, xmove, ymove, pixels));
|
_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));
|
CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui));
|
||||||
break;
|
break;
|
||||||
case OPCODE_BITMAP:
|
case OPCODE_BITMAP:
|
||||||
{
|
if (_mesa_inside_begin_end(ctx)) {
|
||||||
const struct gl_pixelstore_attrib save = ctx->Unpack;
|
_mesa_error(ctx, GL_INVALID_OPERATION,
|
||||||
ctx->Unpack = ctx->DefaultPacking;
|
"glCallList -> glBitmap inside Begin/End");
|
||||||
CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i,
|
} else {
|
||||||
n[3].f, n[4].f, n[5].f, n[6].f,
|
_mesa_bitmap(ctx, n[1].i, n[2].i, n[3].f, n[4].f, n[5].f,
|
||||||
get_pointer(&n[7])));
|
n[6].f, NULL, get_pointer(&n[7]));
|
||||||
ctx->Unpack = save; /* restore */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPCODE_BLEND_COLOR:
|
case OPCODE_BLEND_COLOR:
|
||||||
|
@@ -101,6 +101,11 @@ _mesa_draw_gallium_multimode_fallback(struct gl_context *ctx,
|
|||||||
const unsigned char *mode,
|
const unsigned char *mode,
|
||||||
unsigned num_draws);
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -316,13 +316,11 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLAPIENTRY
|
void
|
||||||
_mesa_Bitmap( GLsizei width, GLsizei height,
|
_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height,
|
||||||
GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
|
GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
|
||||||
const GLubyte *bitmap )
|
const GLubyte *bitmap, struct pipe_resource *tex)
|
||||||
{
|
{
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
|
|
||||||
FLUSH_VERTICES(ctx, 0, 0);
|
FLUSH_VERTICES(ctx, 0, 0);
|
||||||
|
|
||||||
if (width < 0 || height < 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 x = util_ifloor(ctx->Current.RasterPos[0] + epsilon - xorig);
|
||||||
GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig);
|
GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig);
|
||||||
|
|
||||||
if (ctx->Unpack.BufferObj) {
|
if (!tex && ctx->Unpack.BufferObj) {
|
||||||
/* unpack from PBO */
|
/* unpack from PBO */
|
||||||
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height,
|
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height,
|
||||||
1, GL_COLOR_INDEX, GL_BITMAP,
|
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) {
|
else if (ctx->RenderMode == GL_FEEDBACK) {
|
||||||
@@ -396,3 +394,13 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
|
|||||||
_mesa_flush(ctx);
|
_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);
|
||||||
|
}
|
||||||
|
@@ -88,6 +88,8 @@ static GLboolean UseBitmapCache = GL_TRUE;
|
|||||||
/** Epsilon for Z comparisons */
|
/** Epsilon for Z comparisons */
|
||||||
#define Z_EPSILON 1e-06
|
#define Z_EPSILON 1e-06
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_bitmap_state(struct st_context *st);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy user-provide bitmap bits into texture buffer, expanding
|
* 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.
|
* Create a texture which represents a bitmap image.
|
||||||
*/
|
*/
|
||||||
static struct pipe_resource *
|
struct pipe_resource *
|
||||||
make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
|
st_make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
|
||||||
const struct gl_pixelstore_attrib *unpack,
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
const GLubyte *bitmap)
|
const GLubyte *bitmap)
|
||||||
{
|
{
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
struct pipe_context *pipe = st->pipe;
|
struct pipe_context *pipe = st->pipe;
|
||||||
@@ -125,6 +127,9 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
|
|||||||
ubyte *dest;
|
ubyte *dest;
|
||||||
struct pipe_resource *pt;
|
struct pipe_resource *pt;
|
||||||
|
|
||||||
|
if (!st->bitmap.tex_format)
|
||||||
|
init_bitmap_state(st);
|
||||||
|
|
||||||
/* PBO source... */
|
/* PBO source... */
|
||||||
bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
|
bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
|
||||||
if (!bitmap) {
|
if (!bitmap) {
|
||||||
@@ -283,12 +288,13 @@ restore_render_state(struct gl_context *ctx)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a glBitmap by drawing a textured quad
|
* Render a glBitmap by drawing a textured quad
|
||||||
|
*
|
||||||
|
* take_ownership means the callee will be resposible for unreferencing sv.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
|
||||||
GLsizei width, GLsizei height,
|
GLsizei width, GLsizei height,
|
||||||
struct pipe_sampler_view *sv,
|
struct pipe_sampler_view *sv, const GLfloat *color)
|
||||||
const GLfloat *color)
|
|
||||||
{
|
{
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
const float fb_width = (float) st->state.fb_width;
|
const float fb_width = (float) st->state.fb_width;
|
||||||
@@ -589,15 +595,17 @@ init_bitmap_state(struct st_context *st)
|
|||||||
void
|
void
|
||||||
st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
|
st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
|
||||||
GLsizei width, GLsizei height,
|
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 st_context *st = st_context(ctx);
|
||||||
struct pipe_resource *pt;
|
|
||||||
|
|
||||||
assert(width > 0);
|
assert(width > 0);
|
||||||
assert(height > 0);
|
assert(height > 0);
|
||||||
|
|
||||||
st_invalidate_readpix_cache(st);
|
st_invalidate_readpix_cache(st);
|
||||||
|
if (tex)
|
||||||
|
st_flush_bitmap_cache(st);
|
||||||
|
|
||||||
if (!st->bitmap.tex_format) {
|
if (!st->bitmap.tex_format) {
|
||||||
init_bitmap_state(st);
|
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);
|
st_validate_state(st, ST_PIPELINE_META);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap))
|
struct pipe_sampler_view *view = NULL;
|
||||||
return;
|
|
||||||
|
|
||||||
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
|
if (!tex) {
|
||||||
if (pt) {
|
if (UseBitmapCache && accum_bitmap(ctx, x, y, width, height, unpack, bitmap))
|
||||||
struct pipe_sampler_view *sv =
|
return;
|
||||||
st_create_texture_sampler_view(st->pipe, pt);
|
|
||||||
|
struct pipe_resource *pt =
|
||||||
|
st_make_bitmap_texture(ctx, width, height, unpack, bitmap);
|
||||||
|
if (!pt)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
|
assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
|
||||||
|
|
||||||
if (sv) {
|
view = st_create_texture_sampler_view(st->pipe, pt);
|
||||||
draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
|
/* unreference the texture because it's referenced by sv */
|
||||||
width, height, sv, ctx->Current.RasterColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release/free the texture */
|
|
||||||
pipe_resource_reference(&pt, NULL);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,8 +45,14 @@ st_destroy_bitmap(struct st_context *st);
|
|||||||
extern void
|
extern void
|
||||||
st_flush_bitmap_cache(struct st_context *st);
|
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,
|
void st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
|
||||||
GLsizei width, GLsizei height,
|
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 */
|
#endif /* ST_CB_BITMAP_H */
|
||||||
|
Reference in New Issue
Block a user