Several fp and vp tweaks:
- Renumber VERT_RESULT_* values so that they match the numbers of the corresponding FRAG_ATTRIB_ values. - Add ctx->VertexProgram._Current and FragmentProgram._Current values which point to either the current client-supplied program if enabled, or otherwise to the current mesa-internal program. Thus this program is always the correct one for the current state, providing that the mesa flags to turn on automatic generation are enabled. - Add callbacks to ctx->Driver.BindProgram() in texenvprogram.c and t_vp_build.c so that the driver knows when the generated program changes. This is cleaner than trying to code all the possible _NEW_* flags into the driver, and more precise as well. - Add a UsesKill flag to identify fragment programs with that instruction, as these can require special treatment. - Move the FRAG_OUTPUT values to mtypes.h, near to similar defn's.
This commit is contained in:
@@ -195,18 +195,18 @@ enum
|
|||||||
#define VERT_RESULT_HPOS 0
|
#define VERT_RESULT_HPOS 0
|
||||||
#define VERT_RESULT_COL0 1
|
#define VERT_RESULT_COL0 1
|
||||||
#define VERT_RESULT_COL1 2
|
#define VERT_RESULT_COL1 2
|
||||||
#define VERT_RESULT_BFC0 3
|
#define VERT_RESULT_FOGC 3
|
||||||
#define VERT_RESULT_BFC1 4
|
#define VERT_RESULT_TEX0 4
|
||||||
#define VERT_RESULT_FOGC 5
|
#define VERT_RESULT_TEX1 5
|
||||||
#define VERT_RESULT_PSIZ 6
|
#define VERT_RESULT_TEX2 6
|
||||||
#define VERT_RESULT_TEX0 7
|
#define VERT_RESULT_TEX3 7
|
||||||
#define VERT_RESULT_TEX1 8
|
#define VERT_RESULT_TEX4 8
|
||||||
#define VERT_RESULT_TEX2 9
|
#define VERT_RESULT_TEX5 9
|
||||||
#define VERT_RESULT_TEX3 10
|
#define VERT_RESULT_TEX6 10
|
||||||
#define VERT_RESULT_TEX4 11
|
#define VERT_RESULT_TEX7 11
|
||||||
#define VERT_RESULT_TEX5 12
|
#define VERT_RESULT_PSIZ 12
|
||||||
#define VERT_RESULT_TEX6 13
|
#define VERT_RESULT_BFC0 13
|
||||||
#define VERT_RESULT_TEX7 14
|
#define VERT_RESULT_BFC1 14
|
||||||
#define VERT_RESULT_MAX 15
|
#define VERT_RESULT_MAX 15
|
||||||
|
|
||||||
|
|
||||||
@@ -226,7 +226,9 @@ enum
|
|||||||
FRAG_ATTRIB_TEX4 = 8,
|
FRAG_ATTRIB_TEX4 = 8,
|
||||||
FRAG_ATTRIB_TEX5 = 9,
|
FRAG_ATTRIB_TEX5 = 9,
|
||||||
FRAG_ATTRIB_TEX6 = 10,
|
FRAG_ATTRIB_TEX6 = 10,
|
||||||
FRAG_ATTRIB_TEX7 = 11
|
FRAG_ATTRIB_TEX7 = 11,
|
||||||
|
|
||||||
|
FRAG_ATTRIB_MAX = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -257,6 +259,14 @@ enum
|
|||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Fragment program results
|
||||||
|
*/
|
||||||
|
#define FRAG_OUTPUT_COLR 0
|
||||||
|
#define FRAG_OUTPUT_COLH 1
|
||||||
|
#define FRAG_OUTPUT_DEPR 2
|
||||||
|
#define FRAG_OUTPUT_MAX 3
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indexes for all renderbuffers
|
* Indexes for all renderbuffers
|
||||||
*/
|
*/
|
||||||
@@ -1791,6 +1801,7 @@ struct fragment_program
|
|||||||
GLuint NumNativeTexIndirections;
|
GLuint NumNativeTexIndirections;
|
||||||
GLenum FogOption;
|
GLenum FogOption;
|
||||||
struct program_parameter_list *Parameters; /**< array [NumParameters] */
|
struct program_parameter_list *Parameters; /**< array [NumParameters] */
|
||||||
|
GLboolean UsesKill;
|
||||||
|
|
||||||
#ifdef USE_TCC
|
#ifdef USE_TCC
|
||||||
char c_str[4096]; /* experimental... */
|
char c_str[4096]; /* experimental... */
|
||||||
@@ -1835,6 +1846,9 @@ struct gl_vertex_program_state
|
|||||||
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */
|
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */
|
||||||
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */
|
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */
|
||||||
struct vertex_program *Current; /**< ptr to currently bound program */
|
struct vertex_program *Current; /**< ptr to currently bound program */
|
||||||
|
struct vertex_program *_Current; /**< ptr to currently bound
|
||||||
|
program, including internal
|
||||||
|
(t_vp_build.c) programs */
|
||||||
|
|
||||||
GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
||||||
GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
|
||||||
@@ -1865,7 +1879,8 @@ struct gl_fragment_program_state
|
|||||||
GLboolean _Enabled; /* Really enabled? */
|
GLboolean _Enabled; /* Really enabled? */
|
||||||
GLboolean _Active; /* Really really enabled? */
|
GLboolean _Active; /* Really really enabled? */
|
||||||
struct fragment_program *Current; /* ptr to currently bound program */
|
struct fragment_program *Current; /* ptr to currently bound program */
|
||||||
struct fragment_program *_Current; /* ptr to currently active program */
|
struct fragment_program *_Current; /* ptr to currently active program
|
||||||
|
(including internal programs) */
|
||||||
struct fp_machine Machine; /* machine state */
|
struct fp_machine Machine; /* machine state */
|
||||||
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */
|
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */
|
||||||
|
|
||||||
|
@@ -1130,32 +1130,41 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
{
|
{
|
||||||
struct state_key *key;
|
struct state_key *key;
|
||||||
GLuint hash;
|
GLuint hash;
|
||||||
|
struct fragment_program *prev = ctx->FragmentProgram._Current;
|
||||||
|
|
||||||
if (ctx->FragmentProgram._Enabled)
|
if (!ctx->FragmentProgram._Enabled) {
|
||||||
return;
|
key = make_state_key(ctx);
|
||||||
|
hash = hash_key(key);
|
||||||
|
|
||||||
|
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
|
||||||
|
(struct fragment_program *)
|
||||||
|
search_cache(ctx->Texture.env_fp_cache, hash, key, sizeof(*key));
|
||||||
|
|
||||||
key = make_state_key(ctx);
|
if (!ctx->_TexEnvProgram) {
|
||||||
hash = hash_key(key);
|
if (1) _mesa_printf("Building new texenv proggy for key %x\n", hash);
|
||||||
|
|
||||||
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
|
|
||||||
(struct fragment_program *)
|
|
||||||
search_cache(ctx->Texture.env_fp_cache, hash, key, sizeof(*key));
|
|
||||||
|
|
||||||
if (!ctx->_TexEnvProgram) {
|
|
||||||
if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
|
|
||||||
|
|
||||||
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
|
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
|
||||||
(struct fragment_program *)
|
(struct fragment_program *)
|
||||||
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||||
|
|
||||||
create_new_program(key, ctx, ctx->_TexEnvProgram);
|
create_new_program(key, ctx, ctx->_TexEnvProgram);
|
||||||
|
|
||||||
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);
|
FREE(key);
|
||||||
if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
|
if (1) _mesa_printf("Found existing texenv program for key %x\n", hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tell the driver about the change. Could define a new target for
|
||||||
|
* this?
|
||||||
|
*/
|
||||||
|
if (ctx->FragmentProgram._Current != prev)
|
||||||
|
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, (struct program *)
|
||||||
|
ctx->FragmentProgram._Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
|
void _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx )
|
||||||
|
@@ -3013,6 +3013,7 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_TEX_KIL:
|
case OP_TEX_KIL:
|
||||||
|
Program->UsesKill = 1;
|
||||||
if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
|
if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
|
||||||
return 1;
|
return 1;
|
||||||
fp->Opcode = FP_OPCODE_KIL;
|
fp->Opcode = FP_OPCODE_KIL;
|
||||||
@@ -4014,6 +4015,8 @@ _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
|
|||||||
program->NumTexInstructions =
|
program->NumTexInstructions =
|
||||||
program->NumTexIndirections = 0;
|
program->NumTexIndirections = 0;
|
||||||
|
|
||||||
|
program->UsesKill = 0;
|
||||||
|
|
||||||
program->FPInstructions = NULL;
|
program->FPInstructions = NULL;
|
||||||
program->VPInstructions = NULL;
|
program->VPInstructions = NULL;
|
||||||
|
|
||||||
|
@@ -65,6 +65,8 @@ struct arb_program
|
|||||||
GLuint NumAluInstructions;
|
GLuint NumAluInstructions;
|
||||||
GLuint NumTexInstructions;
|
GLuint NumTexInstructions;
|
||||||
GLuint NumTexIndirections;
|
GLuint NumTexIndirections;
|
||||||
|
|
||||||
|
GLboolean UsesKill;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -37,15 +37,6 @@
|
|||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fragment program output registers.
|
|
||||||
* Note: when we fully suppport GL_ARB_draw_buffers we'll have more than
|
|
||||||
* one output color.
|
|
||||||
*/
|
|
||||||
#define FRAG_OUTPUT_COLR 0 /* fragment color */
|
|
||||||
#define FRAG_OUTPUT_COLH 1 /* fragment color, half precision (NV) */
|
|
||||||
#define FRAG_OUTPUT_DEPR 2 /* depth/Z */
|
|
||||||
|
|
||||||
|
|
||||||
/* condition codes */
|
/* condition codes */
|
||||||
#define COND_GT 1 /* greater than zero */
|
#define COND_GT 1 /* greater than zero */
|
||||||
|
@@ -288,8 +288,9 @@ static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
|
static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
|
||||||
"HPOS", "COL0", "COL1", "BFC0", "BFC1", "FOGC", "PSIZ",
|
"HPOS", "COL0", "COL1", "FOGC",
|
||||||
"TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
|
"TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",
|
||||||
|
"PSIZ", "BFC0", "BFC1", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NOTE: the order here must match opcodes in nvvertprog.h */
|
/* NOTE: the order here must match opcodes in nvvertprog.h */
|
||||||
|
@@ -53,10 +53,10 @@ struct state_key {
|
|||||||
unsigned fog_source_is_depth:1;
|
unsigned fog_source_is_depth:1;
|
||||||
unsigned tnl_do_vertex_fog:1;
|
unsigned tnl_do_vertex_fog:1;
|
||||||
unsigned separate_specular:1;
|
unsigned separate_specular:1;
|
||||||
unsigned fog_enabled:1;
|
|
||||||
unsigned fog_mode:2;
|
unsigned fog_mode:2;
|
||||||
unsigned point_attenuated:1;
|
unsigned point_attenuated:1;
|
||||||
unsigned texture_enabled_global:1;
|
unsigned texture_enabled_global:1;
|
||||||
|
unsigned fragprog_inputs_read:12;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned light_enabled:1;
|
unsigned light_enabled:1;
|
||||||
@@ -75,10 +75,10 @@ struct state_key {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define FOG_LINEAR 0
|
#define FOG_NONE 0
|
||||||
#define FOG_EXP 1
|
#define FOG_LINEAR 1
|
||||||
#define FOG_EXP2 2
|
#define FOG_EXP 2
|
||||||
#define FOG_UNKNOWN 3
|
#define FOG_EXP2 3
|
||||||
|
|
||||||
static GLuint translate_fog_mode( GLenum mode )
|
static GLuint translate_fog_mode( GLenum mode )
|
||||||
{
|
{
|
||||||
@@ -86,7 +86,7 @@ static GLuint translate_fog_mode( GLenum mode )
|
|||||||
case GL_LINEAR: return FOG_LINEAR;
|
case GL_LINEAR: return FOG_LINEAR;
|
||||||
case GL_EXP: return FOG_EXP;
|
case GL_EXP: return FOG_EXP;
|
||||||
case GL_EXP2: return FOG_EXP2;
|
case GL_EXP2: return FOG_EXP2;
|
||||||
default: return FOG_UNKNOWN;
|
default: return FOG_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,9 +116,16 @@ static struct state_key *make_state_key( GLcontext *ctx )
|
|||||||
{
|
{
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct vertex_buffer *VB = &tnl->vb;
|
struct vertex_buffer *VB = &tnl->vb;
|
||||||
|
struct fragment_program *fp = ctx->FragmentProgram._Current;
|
||||||
struct state_key *key = CALLOC_STRUCT(state_key);
|
struct state_key *key = CALLOC_STRUCT(state_key);
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
|
/* This now relies on texenvprogram.c being active:
|
||||||
|
*/
|
||||||
|
assert(fp);
|
||||||
|
|
||||||
|
key->fragprog_inputs_read = fp->InputsRead;
|
||||||
|
|
||||||
key->separate_specular = (ctx->Light.Model.ColorControl ==
|
key->separate_specular = (ctx->Light.Model.ColorControl ==
|
||||||
GL_SEPARATE_SPECULAR_COLOR);
|
GL_SEPARATE_SPECULAR_COLOR);
|
||||||
|
|
||||||
@@ -166,18 +173,13 @@ static struct state_key *make_state_key( GLcontext *ctx )
|
|||||||
if (ctx->Transform.RescaleNormals)
|
if (ctx->Transform.RescaleNormals)
|
||||||
key->rescale_normals = 1;
|
key->rescale_normals = 1;
|
||||||
|
|
||||||
if (ctx->Fog.Enabled)
|
key->fog_mode = translate_fog_mode(fp->FogOption);
|
||||||
key->fog_enabled = 1;
|
|
||||||
|
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)
|
||||||
if (key->fog_enabled) {
|
key->fog_source_is_depth = 1;
|
||||||
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)
|
|
||||||
key->fog_source_is_depth = 1;
|
if (tnl->_DoVertexFog)
|
||||||
|
key->tnl_do_vertex_fog = 1;
|
||||||
if (tnl->_DoVertexFog)
|
|
||||||
key->tnl_do_vertex_fog = 1;
|
|
||||||
|
|
||||||
key->fog_mode = translate_fog_mode(ctx->Fog.Mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->Point._Attenuated)
|
if (ctx->Point._Attenuated)
|
||||||
key->point_attenuated = 1;
|
key->point_attenuated = 1;
|
||||||
@@ -332,6 +334,9 @@ static struct ureg get_temp( struct tnl_program *p )
|
|||||||
_mesa_exit(1);
|
_mesa_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bit > p->program->Base.NumTemporaries)
|
||||||
|
p->program->Base.NumTemporaries = bit;
|
||||||
|
|
||||||
p->temp_in_use |= 1<<(bit-1);
|
p->temp_in_use |= 1<<(bit-1);
|
||||||
return make_ureg(PROGRAM_TEMPORARY, bit-1);
|
return make_ureg(PROGRAM_TEMPORARY, bit-1);
|
||||||
}
|
}
|
||||||
@@ -710,6 +715,8 @@ static GLuint material_attrib( GLuint side, GLuint property )
|
|||||||
side);
|
side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get a bitmask of which material values vary on a per-vertex basis.
|
||||||
|
*/
|
||||||
static void set_material_flags( struct tnl_program *p )
|
static void set_material_flags( struct tnl_program *p )
|
||||||
{
|
{
|
||||||
p->color_materials = 0;
|
p->color_materials = 0;
|
||||||
@@ -1194,9 +1201,14 @@ static void build_texture_transform( struct tnl_program *p )
|
|||||||
GLuint i, j;
|
GLuint i, j;
|
||||||
|
|
||||||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
|
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
|
||||||
GLuint texmat_enabled = p->state->unit[i].texmat_enabled;
|
|
||||||
|
|
||||||
if (p->state->unit[i].texgen_enabled || texmat_enabled) {
|
if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (p->state->unit[i].texgen_enabled ||
|
||||||
|
p->state->unit[i].texmat_enabled) {
|
||||||
|
|
||||||
|
GLuint texmat_enabled = p->state->unit[i].texmat_enabled;
|
||||||
struct ureg out = register_output(p, VERT_RESULT_TEX0 + i);
|
struct ureg out = register_output(p, VERT_RESULT_TEX0 + i);
|
||||||
struct ureg out_texgen = undef;
|
struct ureg out_texgen = undef;
|
||||||
|
|
||||||
@@ -1293,10 +1305,7 @@ static void build_texture_transform( struct tnl_program *p )
|
|||||||
|
|
||||||
release_temps(p);
|
release_temps(p);
|
||||||
}
|
}
|
||||||
else if (p->state->unit[i].texunit_really_enabled) {
|
else {
|
||||||
/* KW: _ReallyEnabled isn't sufficient? Need to know whether
|
|
||||||
* this texture unit is referenced by the fragment shader.
|
|
||||||
*/
|
|
||||||
emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i);
|
emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1338,15 +1347,23 @@ static void build_tnl_program( struct tnl_program *p )
|
|||||||
|
|
||||||
/* Lighting calculations:
|
/* Lighting calculations:
|
||||||
*/
|
*/
|
||||||
if (p->state->light_global_enabled)
|
if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) {
|
||||||
build_lighting(p);
|
if (p->state->light_global_enabled)
|
||||||
else
|
build_lighting(p);
|
||||||
emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0);
|
else {
|
||||||
|
if (p->state->fragprog_inputs_read & FRAG_BIT_COL0)
|
||||||
|
emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0);
|
||||||
|
|
||||||
if (p->state->fog_enabled)
|
if (p->state->fragprog_inputs_read & FRAG_BIT_COL1)
|
||||||
|
emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((p->state->fragprog_inputs_read & FRAG_BIT_FOGC) ||
|
||||||
|
p->state->fog_mode != FOG_NONE)
|
||||||
build_fog(p);
|
build_fog(p);
|
||||||
|
|
||||||
if (p->state->texture_enabled_global)
|
if (p->state->fragprog_inputs_read & FRAG_BITS_TEX_ANY)
|
||||||
build_texture_transform(p);
|
build_texture_transform(p);
|
||||||
|
|
||||||
if (p->state->point_attenuated)
|
if (p->state->point_attenuated)
|
||||||
@@ -1470,42 +1487,60 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
|
|||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct state_key *key;
|
struct state_key *key;
|
||||||
GLuint hash;
|
GLuint hash;
|
||||||
|
struct vertex_program *prev = ctx->VertexProgram._Current;
|
||||||
|
|
||||||
if (ctx->VertexProgram._Enabled)
|
if (ctx->VertexProgram._Enabled) {
|
||||||
return;
|
/* Grab all the relevent state and put it in a single structure:
|
||||||
|
*/
|
||||||
|
key = make_state_key(ctx);
|
||||||
|
hash = hash_key(key);
|
||||||
|
|
||||||
/* Grab all the relevent state and put it in a single structure:
|
if (tnl->vp_cache == NULL) {
|
||||||
*/
|
tnl->vp_cache = MALLOC(sizeof(*tnl->vp_cache));
|
||||||
key = make_state_key(ctx);
|
tnl->vp_cache->size = 5;
|
||||||
hash = hash_key(key);
|
tnl->vp_cache->n_items = 0;
|
||||||
|
tnl->vp_cache->items = MALLOC(tnl->vp_cache->size *
|
||||||
/* Look for an already-prepared program for this state:
|
sizeof(*tnl->vp_cache->items));
|
||||||
*/
|
_mesa_memset(tnl->vp_cache->items, 0, tnl->vp_cache->size *
|
||||||
ctx->_TnlProgram = (struct vertex_program *)
|
sizeof(*tnl->vp_cache->items));
|
||||||
search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
|
}
|
||||||
|
|
||||||
/* OK, we'll have to build a new one:
|
|
||||||
*/
|
|
||||||
if (!ctx->_TnlProgram) {
|
|
||||||
if (0)
|
|
||||||
_mesa_printf("Build new TNL program\n");
|
|
||||||
|
|
||||||
|
/* Look for an already-prepared program for this state:
|
||||||
|
*/
|
||||||
ctx->_TnlProgram = (struct vertex_program *)
|
ctx->_TnlProgram = (struct vertex_program *)
|
||||||
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
|
search_cache( tnl->vp_cache, hash, key, sizeof(*key) );
|
||||||
|
|
||||||
|
/* OK, we'll have to build a new one:
|
||||||
|
*/
|
||||||
|
if (!ctx->_TnlProgram) {
|
||||||
|
if (0)
|
||||||
|
_mesa_printf("Build new TNL program\n");
|
||||||
|
|
||||||
|
ctx->_TnlProgram = (struct vertex_program *)
|
||||||
|
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
|
||||||
|
|
||||||
create_new_program( key, ctx->_TnlProgram,
|
create_new_program( key, ctx->_TnlProgram,
|
||||||
ctx->Const.VertexProgram.MaxTemps );
|
ctx->Const.VertexProgram.MaxTemps );
|
||||||
|
|
||||||
cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram );
|
|
||||||
|
cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FREE(key);
|
||||||
|
if (0)
|
||||||
|
_mesa_printf("Found existing TNL program for key %x\n", hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FREE(key);
|
ctx->VertexProgram._Current = ctx->VertexProgram.Current;
|
||||||
if (0)
|
|
||||||
_mesa_printf("Found existing TNL program for key %x\n", hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need a BindProgram callback for the driver?
|
/* Tell the driver about the change. Could define a new target for
|
||||||
|
* this?
|
||||||
*/
|
*/
|
||||||
|
if (ctx->VertexProgram._Current != prev)
|
||||||
|
ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, (struct program *)
|
||||||
|
ctx->VertexProgram._Current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user