Bunch of little fixes:
Fix mem leaks in _mesa_TexEnvProgramCacheDestroy(). Check if ctx->Driver.BindProgram is non-null before calling. s/unsigned/GLuint/ Use MAX_INSTRUCTIONS instead of magic 100, check program length after it's made. Use _mesa_init_instruction() instead of _mesa_memset().
This commit is contained in:
@@ -33,32 +33,33 @@
|
|||||||
#include "shader/program.h"
|
#include "shader/program.h"
|
||||||
#include "shader/program_instruction.h"
|
#include "shader/program_instruction.h"
|
||||||
|
|
||||||
|
#define MAX_INSTRUCTIONS 100
|
||||||
|
|
||||||
#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
|
#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
|
||||||
|
|
||||||
struct mode_opt {
|
struct mode_opt {
|
||||||
unsigned Source:4;
|
GLuint Source:4;
|
||||||
unsigned Operand:3;
|
GLuint Operand:3;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct state_key {
|
struct state_key {
|
||||||
GLuint enabled_units;
|
GLbitfield enabled_units;
|
||||||
unsigned separate_specular:1;
|
GLuint separate_specular:1;
|
||||||
unsigned fog_enabled:1;
|
GLuint fog_enabled:1;
|
||||||
unsigned fog_mode:2;
|
GLuint fog_mode:2;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned enabled:1;
|
GLuint enabled:1;
|
||||||
unsigned source_index:3;
|
GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */
|
||||||
unsigned ScaleShiftRGB:2;
|
GLuint ScaleShiftRGB:2;
|
||||||
unsigned ScaleShiftA:2;
|
GLuint ScaleShiftA:2;
|
||||||
|
|
||||||
unsigned NumArgsRGB:2;
|
GLuint NumArgsRGB:2;
|
||||||
unsigned ModeRGB:4;
|
GLuint ModeRGB:4;
|
||||||
struct mode_opt OptRGB[3];
|
struct mode_opt OptRGB[3];
|
||||||
|
|
||||||
unsigned NumArgsA:2;
|
GLuint NumArgsA:2;
|
||||||
unsigned ModeA:4;
|
GLuint ModeA:4;
|
||||||
struct mode_opt OptA[3];
|
struct mode_opt OptA[3];
|
||||||
} unit[8];
|
} unit[8];
|
||||||
};
|
};
|
||||||
@@ -281,8 +282,6 @@ struct texenv_fragment_program {
|
|||||||
GLuint temp_in_use; /* Tracks temporary regs which are in
|
GLuint temp_in_use; /* Tracks temporary regs which are in
|
||||||
* use.
|
* use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
GLboolean error;
|
GLboolean error;
|
||||||
|
|
||||||
struct ureg src_texture[MAX_TEXTURE_UNITS];
|
struct ureg src_texture[MAX_TEXTURE_UNITS];
|
||||||
@@ -468,7 +467,7 @@ static void emit_dst( struct prog_dst_register *dst,
|
|||||||
|
|
||||||
static struct prog_instruction *
|
static struct prog_instruction *
|
||||||
emit_op(struct texenv_fragment_program *p,
|
emit_op(struct texenv_fragment_program *p,
|
||||||
GLuint op,
|
enum prog_opcode op,
|
||||||
struct ureg dest,
|
struct ureg dest,
|
||||||
GLuint mask,
|
GLuint mask,
|
||||||
GLuint saturate,
|
GLuint saturate,
|
||||||
@@ -479,7 +478,7 @@ emit_op(struct texenv_fragment_program *p,
|
|||||||
GLuint nr = p->program->Base.NumInstructions++;
|
GLuint nr = p->program->Base.NumInstructions++;
|
||||||
struct prog_instruction *inst = &p->program->Base.Instructions[nr];
|
struct prog_instruction *inst = &p->program->Base.Instructions[nr];
|
||||||
|
|
||||||
_mesa_memset(inst, 0, sizeof(*inst));
|
_mesa_init_instruction(inst);
|
||||||
inst->Opcode = op;
|
inst->Opcode = op;
|
||||||
|
|
||||||
emit_arg( &inst->SrcReg[0], src0 );
|
emit_arg( &inst->SrcReg[0], src0 );
|
||||||
@@ -500,7 +499,7 @@ emit_op(struct texenv_fragment_program *p,
|
|||||||
|
|
||||||
|
|
||||||
static struct ureg emit_arith( struct texenv_fragment_program *p,
|
static struct ureg emit_arith( struct texenv_fragment_program *p,
|
||||||
GLuint op,
|
enum prog_opcode op,
|
||||||
struct ureg dest,
|
struct ureg dest,
|
||||||
GLuint mask,
|
GLuint mask,
|
||||||
GLuint saturate,
|
GLuint saturate,
|
||||||
@@ -529,7 +528,7 @@ static struct ureg emit_arith( struct texenv_fragment_program *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct ureg emit_texld( struct texenv_fragment_program *p,
|
static struct ureg emit_texld( struct texenv_fragment_program *p,
|
||||||
GLuint op,
|
enum prog_opcode op,
|
||||||
struct ureg dest,
|
struct ureg dest,
|
||||||
GLuint destmask,
|
GLuint destmask,
|
||||||
GLuint tex_unit,
|
GLuint tex_unit,
|
||||||
@@ -586,8 +585,6 @@ static struct ureg register_const4f( struct texenv_fragment_program *p,
|
|||||||
#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
|
#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct ureg get_one( struct texenv_fragment_program *p )
|
static struct ureg get_one( struct texenv_fragment_program *p )
|
||||||
{
|
{
|
||||||
if (is_undef(p->one))
|
if (is_undef(p->one))
|
||||||
@@ -611,8 +608,6 @@ static struct ureg get_zero( struct texenv_fragment_program *p )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void program_error( struct texenv_fragment_program *p, const char *msg )
|
static void program_error( struct texenv_fragment_program *p, const char *msg )
|
||||||
{
|
{
|
||||||
_mesa_problem(NULL, msg);
|
_mesa_problem(NULL, msg);
|
||||||
@@ -985,7 +980,8 @@ static void create_new_program(struct state_key *key, GLcontext *ctx,
|
|||||||
p.state = key;
|
p.state = key;
|
||||||
p.program = program;
|
p.program = program;
|
||||||
|
|
||||||
p.program->Base.Instructions = MALLOC(sizeof(struct prog_instruction) * 100);
|
p.program->Base.Instructions =
|
||||||
|
_mesa_malloc(sizeof(struct prog_instruction) * MAX_INSTRUCTIONS);
|
||||||
p.program->Base.NumInstructions = 0;
|
p.program->Base.NumInstructions = 0;
|
||||||
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
|
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
|
||||||
p.program->NumTexIndirections = 1; /* correct? */
|
p.program->NumTexIndirections = 1; /* correct? */
|
||||||
@@ -1066,6 +1062,7 @@ static void create_new_program(struct state_key *key, GLcontext *ctx,
|
|||||||
if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
|
if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
|
||||||
program_error(&p, "Exceeded max ALU instructions");
|
program_error(&p, "Exceeded max ALU instructions");
|
||||||
|
|
||||||
|
ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
|
||||||
|
|
||||||
/* Notify driver the fragment program has (actually) changed.
|
/* Notify driver the fragment program has (actually) changed.
|
||||||
*/
|
*/
|
||||||
@@ -1078,11 +1075,10 @@ static void create_new_program(struct state_key *key, GLcontext *ctx,
|
|||||||
_mesa_print_program(&p.program->Base);
|
_mesa_print_program(&p.program->Base);
|
||||||
_mesa_printf("\n");
|
_mesa_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *search_cache( struct texenvprog_cache *cache,
|
static void *search_cache( struct texenvprog_cache *cache,
|
||||||
GLuint hash,
|
GLuint hash,
|
||||||
const void *key,
|
const void *key,
|
||||||
@@ -1149,7 +1145,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
|
|
||||||
cache_item(&ctx->Texture.env_fp_cache, hash, key, ctx->_TexEnvProgram);
|
cache_item(&ctx->Texture.env_fp_cache, hash, key, ctx->_TexEnvProgram);
|
||||||
} else {
|
} else {
|
||||||
FREE(key);
|
_mesa_free(key);
|
||||||
if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
|
if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1160,9 +1156,10 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
/* Tell the driver about the change. Could define a new target for
|
/* Tell the driver about the change. Could define a new target for
|
||||||
* this?
|
* this?
|
||||||
*/
|
*/
|
||||||
if (ctx->FragmentProgram._Current != prev)
|
if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
|
||||||
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, (struct program *)
|
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
|
||||||
ctx->FragmentProgram._Current);
|
(struct program *) ctx->FragmentProgram._Current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
|
void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
|
||||||
@@ -1171,9 +1168,8 @@ void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
|
|||||||
|
|
||||||
for (a = ctx->Texture.env_fp_cache; a; a = tmp) {
|
for (a = ctx->Texture.env_fp_cache; a; a = tmp) {
|
||||||
tmp = a->next;
|
tmp = a->next;
|
||||||
FREE(a->key);
|
_mesa_free(a->key);
|
||||||
FREE(a->data);
|
ctx->Driver.DeleteProgram(ctx, (struct program *) a->data);
|
||||||
FREE(a);
|
_mesa_free(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user