mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
Use program serial numbers to avoid re-generating fragment programs for glDrawPixels.
This commit is contained in:
parent
ee70c02b62
commit
d6a739f6b0
5 changed files with 58 additions and 28 deletions
|
|
@ -42,6 +42,7 @@
|
|||
#include "shader/prog_print.h"
|
||||
|
||||
#include "st_context.h"
|
||||
#include "st_program.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -79,8 +80,6 @@ is_identity(const GLfloat m[16])
|
|||
static void
|
||||
make_state_key(GLcontext *ctx, struct state_key *key)
|
||||
{
|
||||
/*GLuint i, j;*/
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 ||
|
||||
|
|
@ -189,6 +188,8 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key)
|
|||
inst[ic].SrcReg[0].Index = FRAG_RESULT_COLR;
|
||||
ic++;
|
||||
|
||||
/* XXX reimplement in terms of MUL/MAD (see t_vp_build.c) */
|
||||
|
||||
/* DP4 result.color.x, tmp0, matrow0; */
|
||||
_mesa_init_instructions(inst + ic, 1);
|
||||
inst[ic].Opcode = OPCODE_DP4;
|
||||
|
|
@ -268,6 +269,9 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key)
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Update st->pixel_xfer.program in response to new pixel-transfer state.
|
||||
*/
|
||||
static void
|
||||
update_pixel_transfer(struct st_context *st)
|
||||
{
|
||||
|
|
@ -277,14 +281,14 @@ update_pixel_transfer(struct st_context *st)
|
|||
make_state_key(st->ctx, &key);
|
||||
|
||||
fp = (struct gl_fragment_program *)
|
||||
_mesa_search_program_cache(st->pixel_transfer_cache, &key, sizeof(key));
|
||||
_mesa_search_program_cache(st->pixel_xfer.cache, &key, sizeof(key));
|
||||
if (!fp) {
|
||||
fp = get_pixel_transfer_program(st->ctx, &key);
|
||||
_mesa_program_cache_insert(st->ctx, st->pixel_transfer_cache,
|
||||
_mesa_program_cache_insert(st->ctx, st->pixel_xfer.cache,
|
||||
&key, sizeof(key), &fp->Base);
|
||||
}
|
||||
|
||||
st->pixel_transfer_program = fp;
|
||||
st->pixel_xfer.program = (struct st_fragment_program *) fp;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -182,30 +182,48 @@ make_drawpix_fragment_shader(struct st_context *st)
|
|||
{
|
||||
GLcontext *ctx = st->ctx;
|
||||
struct st_fragment_program *stfp;
|
||||
struct gl_program *p;
|
||||
|
||||
/*
|
||||
* XXX Use st_program's serial numbers to determine when the
|
||||
* user-provided program and pixel-transfer program to avoid
|
||||
* needless combining/translation here.
|
||||
*/
|
||||
if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
|
||||
&& st->fp->serialNo == st->pixel_xfer.user_prog_sn) {
|
||||
/* the pixel tranfer program has not changed and the user-defined
|
||||
* shader has not changed, so re-use the combined program.
|
||||
*/
|
||||
stfp = st->pixel_xfer.combined_prog;
|
||||
}
|
||||
else {
|
||||
/* Concatenate the pixel transfer program with the current user-
|
||||
* defined shader.
|
||||
*/
|
||||
stfp = (struct st_fragment_program *)
|
||||
_mesa_combine_programs(ctx,
|
||||
&st->pixel_xfer.program->Base.Base,
|
||||
&st->fp->Base.Base);
|
||||
|
||||
p = _mesa_combine_programs(ctx,
|
||||
&st->pixel_transfer_program->Base,
|
||||
&ctx->FragmentProgram._Current->Base);
|
||||
#if 0
|
||||
_mesa_print_program(p);
|
||||
printf("InputsRead: 0x%x\n", p->InputsRead);
|
||||
printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
|
||||
_mesa_print_parameter_list(p->Parameters);
|
||||
{
|
||||
struct gl_program *p = &stfp->Base.Base;
|
||||
_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
|
||||
|
||||
stfp = (struct st_fragment_program *) p;
|
||||
st_translate_fragment_program(st, stfp, NULL,
|
||||
stfp->tokens, ST_MAX_SHADER_TOKENS);
|
||||
/* translate to TGSI tokens */
|
||||
st_translate_fragment_program(st, stfp, NULL,
|
||||
stfp->tokens, ST_MAX_SHADER_TOKENS);
|
||||
|
||||
/* save new program, update serial numbers */
|
||||
st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
|
||||
st->pixel_xfer.user_prog_sn = st->fp->serialNo;
|
||||
st->pixel_xfer.combined_prog_sn = stfp->serialNo;
|
||||
st->pixel_xfer.combined_prog = stfp;
|
||||
}
|
||||
|
||||
st_upload_constants( st, p->Parameters, PIPE_SHADER_FRAGMENT );
|
||||
/* Ideally we'd have updated the pipe constants during the normal
|
||||
* st/atom mechanism. But we can't since this is specific to glDrawPixels.
|
||||
*/
|
||||
st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
|
||||
|
||||
return stfp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#include "st_atom_shader.h"
|
||||
|
||||
|
||||
static GLuint SerialNo = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Called via ctx->Driver.BindProgram() to bind an ARB vertex or
|
||||
|
|
@ -91,7 +93,7 @@ static struct gl_program *st_new_program( GLcontext *ctx,
|
|||
case GL_VERTEX_PROGRAM_ARB: {
|
||||
struct st_vertex_program *prog = CALLOC_STRUCT(st_vertex_program);
|
||||
|
||||
prog->serialNo = 1;
|
||||
prog->serialNo = SerialNo++;
|
||||
|
||||
return _mesa_init_vertex_program( ctx,
|
||||
&prog->Base,
|
||||
|
|
@ -103,7 +105,7 @@ static struct gl_program *st_new_program( GLcontext *ctx,
|
|||
case GL_FRAGMENT_PROGRAM_NV: {
|
||||
struct st_fragment_program *prog = CALLOC_STRUCT(st_fragment_program);
|
||||
|
||||
prog->serialNo = 1;
|
||||
prog->serialNo = SerialNo++;
|
||||
|
||||
return _mesa_init_fragment_program( ctx,
|
||||
&prog->Base,
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ struct st_context *st_create_context( GLcontext *ctx,
|
|||
|
||||
st->haveFramebufferRegions = GL_TRUE;
|
||||
|
||||
st->pixel_transfer_cache = _mesa_new_program_cache();
|
||||
st->pixel_xfer.cache = _mesa_new_program_cache();
|
||||
|
||||
#if 0
|
||||
st_init_cb_clear( st );
|
||||
|
|
@ -126,7 +126,7 @@ void st_destroy_context( struct st_context *st )
|
|||
#endif
|
||||
cso_cache_delete( st->cache );
|
||||
|
||||
_mesa_delete_program_cache(st->ctx, st->pixel_transfer_cache);
|
||||
_mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
|
||||
|
||||
st->pipe->destroy( st->pipe );
|
||||
FREE( st );
|
||||
|
|
|
|||
|
|
@ -133,8 +133,14 @@ struct st_context
|
|||
struct st_vertex_program *vp; /**< Currently bound vertex program */
|
||||
struct st_fragment_program *fp; /**< Currently bound fragment program */
|
||||
|
||||
struct gl_fragment_program *pixel_transfer_program;
|
||||
struct gl_program_cache *pixel_transfer_cache;
|
||||
struct {
|
||||
struct gl_program_cache *cache;
|
||||
struct st_fragment_program *program; /**< cur pixel transfer prog */
|
||||
GLuint xfer_prog_sn; /**< pixel xfer program serial no. */
|
||||
GLuint user_prog_sn; /**< user fragment program serial no. */
|
||||
struct st_fragment_program *combined_prog;
|
||||
GLuint combined_prog_sn;
|
||||
} pixel_xfer;
|
||||
|
||||
/**
|
||||
* Buffer object which stores the ctx->Current.Attrib[] values.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue