st/mesa: fix the glBitmap cache wrt FS, scissor, and clamp color changes

We need to track those states in the cache and flush the cache
if the next glBitmap call uses different states.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19859>
This commit is contained in:
Marek Olšák 2022-11-18 10:20:17 -05:00 committed by Marge Bot
parent 525c70c61a
commit 33ca53ac79
4 changed files with 35 additions and 18 deletions

View file

@ -868,8 +868,6 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
GLbitfield newEnabled =
state * ((1 << ctx->Const.MaxViewports) - 1);
if (newEnabled != ctx->Scissor.EnableFlags) {
st_flush_bitmap_cache(st_context(ctx));
FLUSH_VERTICES(ctx, 0,
GL_SCISSOR_BIT | GL_ENABLE_BIT);
ctx->NewDriverState |= ST_NEW_SCISSOR | ST_NEW_RASTERIZER;
@ -1404,8 +1402,6 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap,
return;
}
if (((ctx->Scissor.EnableFlags >> index) & 1) != state) {
st_flush_bitmap_cache(st_context(ctx));
FLUSH_VERTICES(ctx, 0,
GL_SCISSOR_BIT | GL_ENABLE_BIT);
ctx->NewDriverState |= ST_NEW_SCISSOR | ST_NEW_RASTERIZER;

View file

@ -51,9 +51,6 @@ set_scissor_no_notify(struct gl_context *ctx, unsigned idx,
height == ctx->Scissor.ScissorArray[idx].Height)
return;
if (ctx->Scissor.EnableFlags)
st_flush_bitmap_cache(st_context(ctx));
FLUSH_VERTICES(ctx, 0, GL_SCISSOR_BIT);
ctx->NewDriverState |= ST_NEW_SCISSOR;

View file

@ -170,7 +170,8 @@ st_make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
static void
setup_render_state(struct gl_context *ctx,
struct pipe_sampler_view *sv,
const GLfloat *color)
const GLfloat *color, struct gl_program *fp,
bool scissor_enabled, bool clamp_frag_color)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@ -182,10 +183,10 @@ setup_render_state(struct gl_context *ctx,
key.st = st->has_shareable_shaders ? NULL : st;
key.bitmap = GL_TRUE;
key.clamp_color = st->clamp_frag_color_in_shader &&
ctx->Color._ClampFragmentColor;
clamp_frag_color;
key.lower_alpha_func = COMPARE_FUNC_ALWAYS;
fpv = st_get_fp_variant(st, st->fp, &key);
fpv = st_get_fp_variant(st, fp, &key);
/* As an optimization, Mesa's fragment programs will sometimes get the
* primary color from a statevar/constant rather than a varying variable.
@ -198,7 +199,7 @@ setup_render_state(struct gl_context *ctx,
GLfloat colorSave[4];
COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
st_upload_constants(st, st->fp, MESA_SHADER_FRAGMENT);
st_upload_constants(st, fp, MESA_SHADER_FRAGMENT);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
}
@ -211,7 +212,7 @@ setup_render_state(struct gl_context *ctx,
/* rasterizer state: just scissor */
st->bitmap.rasterizer.scissor = ctx->Scissor.EnableFlags & 1;
st->bitmap.rasterizer.scissor = scissor_enabled;
cso_set_rasterizer(cso, &st->bitmap.rasterizer);
/* fragment shader state: TEX lookup program */
@ -243,8 +244,7 @@ setup_render_state(struct gl_context *ctx,
{
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
unsigned num_views =
st_get_sampler_views(st, PIPE_SHADER_FRAGMENT,
ctx->FragmentProgram._Current, sampler_views);
st_get_sampler_views(st, PIPE_SHADER_FRAGMENT, fp, sampler_views);
num_views = MAX2(fpv->bitmap_sampler + 1, num_views);
sampler_views[fpv->bitmap_sampler] = sv;
@ -294,7 +294,9 @@ restore_render_state(struct gl_context *ctx)
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 gl_program *fp, bool scissor_enabled,
bool clamp_frag_color)
{
struct st_context *st = st_context(ctx);
const float fb_width = (float) st->state.fb_width;
@ -327,7 +329,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
tBot = (float) height;
}
setup_render_state(ctx, sv, color);
setup_render_state(ctx, sv, color, fp, scissor_enabled, clamp_frag_color);
/* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
z = z * 2.0f - 1.0f;
@ -357,6 +359,8 @@ reset_cache(struct st_context *st)
cache->ymin = 1000000;
cache->ymax = -1000000;
_mesa_reference_program(st->ctx, &cache->fp, NULL);
assert(!cache->texture);
/* allocate a new texture */
@ -453,7 +457,10 @@ st_flush_bitmap_cache(struct st_context *st)
cache->zpos,
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
sv,
cache->color);
cache->color,
cache->fp,
cache->scissor_enabled,
cache->clamp_frag_color);
}
/* release/free the texture */
@ -483,12 +490,18 @@ accum_bitmap(struct gl_context *ctx,
height > BITMAP_CACHE_HEIGHT)
return GL_FALSE; /* too big to cache */
bool scissor_enabled = ctx->Scissor.EnableFlags & 0x1;
bool clamp_frag_color = ctx->Color._ClampFragmentColor;
if (!cache->empty) {
px = x - cache->xpos; /* pos in buffer */
py = y - cache->ypos;
if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
!TEST_EQ_4V(ctx->Current.RasterColor, cache->color) ||
ctx->FragmentProgram._Current != cache->fp ||
scissor_enabled != cache->scissor_enabled ||
clamp_frag_color != cache->clamp_frag_color ||
((fabsf(z - cache->zpos) > Z_EPSILON))) {
/* This bitmap would extend beyond cache bounds, or the bitmap
* color is changing
@ -507,6 +520,9 @@ accum_bitmap(struct gl_context *ctx,
cache->zpos = z;
cache->empty = GL_FALSE;
COPY_4FV(cache->color, ctx->Current.RasterColor);
_mesa_reference_program(ctx, &cache->fp, ctx->FragmentProgram._Current);
cache->scissor_enabled = scissor_enabled;
cache->clamp_frag_color = clamp_frag_color;
}
assert(px != -999);
@ -645,7 +661,10 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
if (view) {
draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
width, height, view, ctx->Current.RasterColor);
width, height, view, ctx->Current.RasterColor,
ctx->FragmentProgram._Current,
ctx->Scissor.EnableFlags & 0x1,
ctx->Color._ClampFragmentColor);
}
}
@ -660,4 +679,5 @@ st_destroy_bitmap(struct st_context *st)
pipe_texture_unmap(pipe, cache->trans);
}
pipe_resource_reference(&st->bitmap.cache.texture, NULL);
_mesa_reference_program(st->ctx, &st->bitmap.cache.fp, NULL);
}

View file

@ -62,6 +62,10 @@ struct st_bitmap_cache
/** Bounds of region used in window coords */
GLint xmin, ymin, xmax, ymax;
/** GL states */
struct gl_program *fp;
bool scissor_enabled;
bool clamp_frag_color;
GLfloat color[4];
/** Bitmap's Z position */