Add a facility to route all rasterization through a fragment program
which is automatically generated to match the current texture environment state. Introduces a new value ctx->FragmentProgram._Active which is true when either _Enabled is true or there is such a fragment program ready to run. To test out on a driver running the software rasterizer, set MESA_TEX_PROG=t in the environment. It goes without saying that performance is lower for the software rasterizer in this mode.
This commit is contained in:
@@ -1602,6 +1602,9 @@ _mesa_initialize_context( GLcontext *ctx,
|
|||||||
ctx->TnlModule.SwapCount = 0;
|
ctx->TnlModule.SwapCount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
|
||||||
|
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1829,7 +1829,9 @@ struct gl_fragment_program_state
|
|||||||
{
|
{
|
||||||
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
|
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
|
||||||
GLboolean _Enabled; /* Really enabled? */
|
GLboolean _Enabled; /* 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 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 */
|
||||||
|
|
||||||
@@ -2652,6 +2654,9 @@ struct __GLcontextRec
|
|||||||
struct fragment_program _TexEnvProgram; /**< Texture state as fragment program */
|
struct fragment_program _TexEnvProgram; /**< Texture state as fragment program */
|
||||||
struct vertex_program _TnlProgram; /**< Fixed func TNL state as vertex program */
|
struct vertex_program _TnlProgram; /**< Fixed func TNL state as vertex program */
|
||||||
|
|
||||||
|
GLboolean _MaintainTexEnvProgram;
|
||||||
|
GLboolean _MaintainTnlProgram;
|
||||||
|
|
||||||
struct gl_occlusion_state Occlusion; /**< GL_ARB_occlusion_query */
|
struct gl_occlusion_state Occlusion; /**< GL_ARB_occlusion_query */
|
||||||
|
|
||||||
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
|
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
|
||||||
|
@@ -933,6 +933,14 @@ update_program(GLcontext *ctx)
|
|||||||
&& ctx->FragmentProgram.Current->Instructions;
|
&& ctx->FragmentProgram.Current->Instructions;
|
||||||
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
|
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
|
||||||
&& ctx->ATIFragmentShader.Current->Instructions;
|
&& ctx->ATIFragmentShader.Current->Instructions;
|
||||||
|
|
||||||
|
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
|
||||||
|
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
|
||||||
|
|
||||||
|
if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
|
||||||
|
ctx->FragmentProgram._Current = &ctx->_TexEnvProgram;
|
||||||
|
ctx->FragmentProgram._Active = GL_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -984,6 +992,11 @@ _mesa_update_state( GLcontext *ctx )
|
|||||||
if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
|
if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
|
||||||
update_arrays( ctx );
|
update_arrays( ctx );
|
||||||
|
|
||||||
|
if (ctx->_MaintainTexEnvProgram) {
|
||||||
|
if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR))
|
||||||
|
_mesa_UpdateTexEnvProgram(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/* ctx->_NeedEyeCoords is now up to date.
|
/* ctx->_NeedEyeCoords is now up to date.
|
||||||
*
|
*
|
||||||
* If the truth value of this variable has changed, update for the
|
* If the truth value of this variable has changed, update for the
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
#include "shader/arbfragparse.h"
|
#include "shader/arbfragparse.h"
|
||||||
|
|
||||||
|
|
||||||
#define DISASSEM 1
|
#define DISASSEM 0
|
||||||
|
|
||||||
/* Use uregs to represent registers internally, translate to Mesa's
|
/* Use uregs to represent registers internally, translate to Mesa's
|
||||||
* expected formats on emit.
|
* expected formats on emit.
|
||||||
@@ -76,30 +76,17 @@ const static struct ureg undef = {
|
|||||||
#define Z 2
|
#define Z 2
|
||||||
#define W 3
|
#define W 3
|
||||||
|
|
||||||
#define MAX_CONSTANT 32
|
|
||||||
|
|
||||||
/* State used to build the fragment program:
|
/* State used to build the fragment program:
|
||||||
*/
|
*/
|
||||||
struct texenv_fragment_program {
|
struct texenv_fragment_program {
|
||||||
struct fragment_program *prog;
|
struct fragment_program *program;
|
||||||
GLcontext *ctx;
|
GLcontext *ctx;
|
||||||
|
|
||||||
GLfloat constant[MAX_CONSTANT][4];
|
|
||||||
GLuint constant_flags[MAX_CONSTANT];
|
|
||||||
GLuint nr_constants;
|
|
||||||
|
|
||||||
GLuint temp_flag; /* Tracks temporary regs which are in
|
GLuint temp_flag; /* Tracks temporary regs which are in
|
||||||
* use.
|
* use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
struct {
|
|
||||||
GLuint reg; /* Hardware constant idx */
|
|
||||||
const GLfloat *values; /* Pointer to tracked values */
|
|
||||||
} param[MAX_CONSTANT];
|
|
||||||
GLuint nr_params;
|
|
||||||
|
|
||||||
|
|
||||||
GLboolean error;
|
GLboolean error;
|
||||||
|
|
||||||
struct ureg src_texture; /* Reg containing sampled texture color,
|
struct ureg src_texture; /* Reg containing sampled texture color,
|
||||||
@@ -167,22 +154,40 @@ static void release_temps( struct texenv_fragment_program *p )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct ureg emit_decl( struct texenv_fragment_program *p,
|
static struct ureg register_param6( struct texenv_fragment_program *p,
|
||||||
GLuint type, GLuint nr )
|
GLint s0,
|
||||||
|
GLint s1,
|
||||||
|
GLint s2,
|
||||||
|
GLint s3,
|
||||||
|
GLint s4,
|
||||||
|
GLint s5)
|
||||||
{
|
{
|
||||||
struct ureg reg = make_ureg(type, nr);
|
GLint tokens[6];
|
||||||
|
GLuint idx;
|
||||||
if (type == PROGRAM_INPUT) {
|
tokens[0] = s0;
|
||||||
p->prog->InputsRead |= 1<<nr;
|
tokens[1] = s1;
|
||||||
}
|
tokens[2] = s2;
|
||||||
else {
|
tokens[3] = s3;
|
||||||
/* Other ???
|
tokens[4] = s4;
|
||||||
*/
|
tokens[5] = s5;
|
||||||
|
idx = _mesa_add_state_reference( p->program->Parameters, tokens );
|
||||||
|
return make_ureg(PROGRAM_STATE_VAR, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reg;
|
|
||||||
|
#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
|
||||||
|
#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
|
||||||
|
#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
|
||||||
|
#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
|
||||||
|
|
||||||
|
|
||||||
|
static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
|
||||||
|
{
|
||||||
|
p->program->InputsRead |= (1<<input);
|
||||||
|
return make_ureg(PROGRAM_INPUT, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void emit_arg( struct fp_src_register *reg,
|
static void emit_arg( struct fp_src_register *reg,
|
||||||
struct ureg ureg )
|
struct ureg ureg )
|
||||||
{
|
{
|
||||||
@@ -214,15 +219,15 @@ emit_op(struct texenv_fragment_program *p,
|
|||||||
struct ureg src1,
|
struct ureg src1,
|
||||||
struct ureg src2 )
|
struct ureg src2 )
|
||||||
{
|
{
|
||||||
GLuint nr = p->prog->Base.NumInstructions++;
|
GLuint nr = p->program->Base.NumInstructions++;
|
||||||
struct fp_instruction *inst = &p->prog->Instructions[nr];
|
struct fp_instruction *inst = &p->program->Instructions[nr];
|
||||||
|
|
||||||
memset(inst, 0, sizeof(*inst));
|
memset(inst, 0, sizeof(*inst));
|
||||||
inst->Opcode = op;
|
inst->Opcode = op;
|
||||||
|
|
||||||
if (!is_undef(src0)) emit_arg( &inst->SrcReg[0], src0 );
|
emit_arg( &inst->SrcReg[0], src0 );
|
||||||
if (!is_undef(src1)) emit_arg( &inst->SrcReg[1], src1 );
|
emit_arg( &inst->SrcReg[1], src1 );
|
||||||
if (!is_undef(src2)) emit_arg( &inst->SrcReg[2], src2 );
|
emit_arg( &inst->SrcReg[2], src2 );
|
||||||
|
|
||||||
inst->Saturate = saturate;
|
inst->Saturate = saturate;
|
||||||
|
|
||||||
@@ -243,7 +248,7 @@ static struct ureg emit_arith( struct texenv_fragment_program *p,
|
|||||||
{
|
{
|
||||||
emit_op(p, op, dest, mask, saturate, src0, src1, src2);
|
emit_op(p, op, dest, mask, saturate, src0, src1, src2);
|
||||||
|
|
||||||
p->prog->NumAluInstructions++;
|
p->program->NumAluInstructions++;
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,100 +270,40 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
|
|||||||
inst->TexSrcIdx = tex_idx;
|
inst->TexSrcIdx = tex_idx;
|
||||||
inst->TexSrcUnit = tex_unit;
|
inst->TexSrcUnit = tex_unit;
|
||||||
|
|
||||||
p->prog->NumTexInstructions++;
|
p->program->NumTexInstructions++;
|
||||||
|
|
||||||
if (coord.file != PROGRAM_INPUT &&
|
if (coord.file != PROGRAM_INPUT &&
|
||||||
(coord.idx < VERT_ATTRIB_TEX0 ||
|
(coord.idx < FRAG_ATTRIB_TEX0 ||
|
||||||
coord.idx > VERT_ATTRIB_TEX7)) {
|
coord.idx > FRAG_ATTRIB_TEX7)) {
|
||||||
p->prog->NumTexIndirections++;
|
p->program->NumTexIndirections++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct ureg emit_const1f( struct texenv_fragment_program *p, GLfloat c0 )
|
static struct ureg register_const4f( struct texenv_fragment_program *p,
|
||||||
|
GLfloat s0,
|
||||||
|
GLfloat s1,
|
||||||
|
GLfloat s2,
|
||||||
|
GLfloat s3)
|
||||||
{
|
{
|
||||||
GLint reg, idx;
|
GLfloat values[4];
|
||||||
|
GLuint idx;
|
||||||
for (reg = 0; reg < MAX_CONSTANT; reg++) {
|
values[0] = s0;
|
||||||
for (idx = 0; idx < 4; idx++) {
|
values[1] = s1;
|
||||||
if (!(p->constant_flags[reg] & (1<<idx)) ||
|
values[2] = s2;
|
||||||
p->constant[reg][idx] == c0) {
|
values[3] = s3;
|
||||||
p->constant[reg][idx] = c0;
|
idx = _mesa_add_unnamed_constant( p->program->Parameters, values );
|
||||||
p->constant_flags[reg] |= 1<<idx;
|
return make_ureg(PROGRAM_STATE_VAR, idx);
|
||||||
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
|
|
||||||
return swizzle1(make_ureg(PROGRAM_LOCAL_PARAM, reg),idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
|
#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1)
|
||||||
p->error = 1;
|
#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1)
|
||||||
return undef;
|
#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
|
||||||
}
|
|
||||||
|
|
||||||
static struct ureg emit_const2f( struct texenv_fragment_program *p,
|
|
||||||
GLfloat c0, GLfloat c1 )
|
|
||||||
{
|
|
||||||
GLint reg, idx;
|
|
||||||
|
|
||||||
for (reg = 0; reg < MAX_CONSTANT; reg++) {
|
|
||||||
if (p->constant_flags[reg] == 0xf)
|
|
||||||
continue;
|
|
||||||
for (idx = 0; idx < 3; idx++) {
|
|
||||||
if (!(p->constant_flags[reg] & (3<<idx))) {
|
|
||||||
p->constant[reg][idx] = c0;
|
|
||||||
p->constant[reg][idx+1] = c1;
|
|
||||||
p->constant_flags[reg] |= 3<<idx;
|
|
||||||
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
|
|
||||||
return swizzle(make_ureg(PROGRAM_LOCAL_PARAM, reg),idx,idx+1,idx,idx+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
|
|
||||||
p->error = 1;
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct ureg emit_const4f( struct texenv_fragment_program *p,
|
|
||||||
GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3 )
|
|
||||||
{
|
|
||||||
GLint reg;
|
|
||||||
|
|
||||||
for (reg = 0; reg < MAX_CONSTANT; reg++) {
|
|
||||||
if (p->constant_flags[reg] == 0xf &&
|
|
||||||
p->constant[reg][0] == c0 &&
|
|
||||||
p->constant[reg][1] == c1 &&
|
|
||||||
p->constant[reg][2] == c2 &&
|
|
||||||
p->constant[reg][3] == c3) {
|
|
||||||
return make_ureg(PROGRAM_LOCAL_PARAM, reg);
|
|
||||||
}
|
|
||||||
else if (p->constant_flags[reg] == 0) {
|
|
||||||
p->constant[reg][0] = c0;
|
|
||||||
p->constant[reg][1] = c1;
|
|
||||||
p->constant[reg][2] = c2;
|
|
||||||
p->constant[reg][3] = c3;
|
|
||||||
p->constant_flags[reg] = 0xf;
|
|
||||||
if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
|
|
||||||
return make_ureg(PROGRAM_LOCAL_PARAM, reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
|
|
||||||
p->error = 1;
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct ureg emit_const4fv( struct texenv_fragment_program *p, const GLfloat *c )
|
|
||||||
{
|
|
||||||
return emit_const4f( p, c[0], c[1], c[2], c[3] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -393,9 +338,7 @@ static struct ureg get_source( struct texenv_fragment_program *p,
|
|||||||
if (is_undef(p->src_texture)) {
|
if (is_undef(p->src_texture)) {
|
||||||
|
|
||||||
GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
|
GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
|
||||||
struct ureg texcoord = emit_decl(p,
|
struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
|
||||||
PROGRAM_INPUT,
|
|
||||||
VERT_ATTRIB_TEX0+unit);
|
|
||||||
struct ureg tmp = get_temp( p );
|
struct ureg tmp = get_temp( p );
|
||||||
|
|
||||||
/* TODO: Use D0_MASK_XY where possible.
|
/* TODO: Use D0_MASK_XY where possible.
|
||||||
@@ -420,14 +363,15 @@ static struct ureg get_source( struct texenv_fragment_program *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case GL_CONSTANT:
|
case GL_CONSTANT:
|
||||||
return emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
|
return register_param2(p, STATE_TEXENV_COLOR, unit);
|
||||||
case GL_PRIMARY_COLOR:
|
case GL_PRIMARY_COLOR:
|
||||||
return emit_decl(p, PROGRAM_INPUT, VERT_ATTRIB_COLOR0);
|
return register_input(p, FRAG_ATTRIB_COL0);
|
||||||
case GL_PREVIOUS:
|
case GL_PREVIOUS:
|
||||||
default:
|
default:
|
||||||
return emit_decl(p,
|
if (is_undef(p->src_previous))
|
||||||
p->src_previous.file,
|
return register_input(p, FRAG_ATTRIB_COL0);
|
||||||
p->src_previous.idx);
|
else
|
||||||
|
return p->src_previous;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +392,7 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
|
|||||||
* Emit tmp = 1.0 - arg.xyzw
|
* Emit tmp = 1.0 - arg.xyzw
|
||||||
*/
|
*/
|
||||||
arg = get_temp( p );
|
arg = get_temp( p );
|
||||||
one = emit_const1f(p, 1);
|
one = register_const1f(p, 1.0);
|
||||||
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0, one, src, undef);
|
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0, one, src, undef);
|
||||||
|
|
||||||
case GL_SRC_ALPHA:
|
case GL_SRC_ALPHA:
|
||||||
@@ -461,7 +405,7 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
|
|||||||
* Emit tmp = 1.0 - arg.wwww
|
* Emit tmp = 1.0 - arg.wwww
|
||||||
*/
|
*/
|
||||||
arg = get_temp( p );
|
arg = get_temp( p );
|
||||||
one = emit_const1f(p, 1);
|
one = register_const1f(p, 1.0);
|
||||||
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0,
|
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0,
|
||||||
one, swizzle1(src, W), undef);
|
one, swizzle1(src, W), undef);
|
||||||
case GL_SRC_COLOR:
|
case GL_SRC_COLOR:
|
||||||
@@ -559,7 +503,7 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
|
|||||||
/* tmp = arg0 + arg1
|
/* tmp = arg0 + arg1
|
||||||
* result = tmp + -.5
|
* result = tmp + -.5
|
||||||
*/
|
*/
|
||||||
tmp = emit_const1f(p, .5);
|
tmp = register_const1f(p, .5);
|
||||||
tmp = swizzle1(tmp,X);
|
tmp = swizzle1(tmp,X);
|
||||||
emit_arith( p, FP_OPCODE_ADD, dest, mask, 0, src[0], src[1], undef );
|
emit_arith( p, FP_OPCODE_ADD, dest, mask, 0, src[0], src[1], undef );
|
||||||
emit_arith( p, FP_OPCODE_SUB, dest, mask, saturate, dest, tmp, undef );
|
emit_arith( p, FP_OPCODE_SUB, dest, mask, saturate, dest, tmp, undef );
|
||||||
@@ -578,8 +522,8 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
|
|||||||
case GL_DOT3_RGB: {
|
case GL_DOT3_RGB: {
|
||||||
struct ureg tmp0 = get_temp( p );
|
struct ureg tmp0 = get_temp( p );
|
||||||
struct ureg tmp1 = get_temp( p );
|
struct ureg tmp1 = get_temp( p );
|
||||||
struct ureg neg1 = emit_const1f(p, -1);
|
struct ureg neg1 = register_const1f(p, -1);
|
||||||
struct ureg two = emit_const1f(p, 2);
|
struct ureg two = register_const1f(p, 2);
|
||||||
|
|
||||||
/* tmp0 = 2*src0 - 1
|
/* tmp0 = 2*src0 - 1
|
||||||
* tmp1 = 2*src1 - 1
|
* tmp1 = 2*src1 - 1
|
||||||
@@ -610,7 +554,7 @@ static struct ureg get_dest( struct texenv_fragment_program *p, int unit )
|
|||||||
else if (unit != p->last_tex_stage)
|
else if (unit != p->last_tex_stage)
|
||||||
return get_temp( p );
|
return get_temp( p );
|
||||||
else
|
else
|
||||||
return make_ureg(PROGRAM_OUTPUT, VERT_ATTRIB_COLOR0);
|
return make_ureg(PROGRAM_OUTPUT, FRAG_OUTPUT_COLR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -684,11 +628,11 @@ static struct ureg emit_texenv( struct texenv_fragment_program *p, int unit )
|
|||||||
*/
|
*/
|
||||||
if (alpha_shift || rgb_shift) {
|
if (alpha_shift || rgb_shift) {
|
||||||
if (rgb_shift == alpha_shift) {
|
if (rgb_shift == alpha_shift) {
|
||||||
shift = emit_const1f(p, 1<<rgb_shift);
|
shift = register_const1f(p, 1<<rgb_shift);
|
||||||
shift = swizzle1(shift,X);
|
shift = swizzle1(shift,X);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shift = emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
|
shift = register_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
|
||||||
shift = swizzle(shift,X,X,X,Y);
|
shift = swizzle(shift,X,X,X,Y);
|
||||||
}
|
}
|
||||||
return emit_arith( p, FP_OPCODE_MUL, dest, WRITEMASK_XYZW,
|
return emit_arith( p, FP_OPCODE_MUL, dest, WRITEMASK_XYZW,
|
||||||
@@ -704,22 +648,23 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
GLuint unit;
|
GLuint unit;
|
||||||
struct ureg cf, out;
|
struct ureg cf, out;
|
||||||
|
|
||||||
p.ctx = ctx;
|
if (ctx->FragmentProgram._Enabled)
|
||||||
p.prog = &ctx->_TexEnvProgram;
|
return;
|
||||||
|
|
||||||
if (p.prog->Instructions == NULL) {
|
p.ctx = ctx;
|
||||||
p.prog->Instructions = MALLOC(sizeof(struct fp_instruction) * 100);
|
p.program = &ctx->_TexEnvProgram;
|
||||||
|
|
||||||
|
if (p.program->Instructions == NULL) {
|
||||||
|
p.program->Instructions = MALLOC(sizeof(struct fp_instruction) * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.prog->Base.NumInstructions = 0;
|
p.program->Base.NumInstructions = 0;
|
||||||
p.prog->NumTexIndirections = 1; /* correct? */
|
p.program->NumTexIndirections = 1; /* correct? */
|
||||||
p.prog->NumTexInstructions = 0;
|
p.program->NumTexInstructions = 0;
|
||||||
p.prog->NumAluInstructions = 0;
|
p.program->NumAluInstructions = 0;
|
||||||
|
|
||||||
memset( p.constant_flags, 0, sizeof(p.constant_flags) );
|
|
||||||
|
|
||||||
p.src_texture = undef;
|
p.src_texture = undef;
|
||||||
p.src_previous = make_ureg(PROGRAM_INPUT, VERT_ATTRIB_COLOR0);
|
p.src_previous = undef;
|
||||||
p.last_tex_stage = 0;
|
p.last_tex_stage = 0;
|
||||||
|
|
||||||
if (ctx->Texture._EnabledUnits) {
|
if (ctx->Texture._EnabledUnits) {
|
||||||
@@ -738,12 +683,12 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
}
|
}
|
||||||
|
|
||||||
cf = get_source( &p, GL_PREVIOUS, 0 );
|
cf = get_source( &p, GL_PREVIOUS, 0 );
|
||||||
out = make_ureg( PROGRAM_OUTPUT, VERT_ATTRIB_COLOR0 );
|
out = make_ureg( PROGRAM_OUTPUT, FRAG_OUTPUT_COLR );
|
||||||
|
|
||||||
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
|
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
|
||||||
/* Emit specular add.
|
/* Emit specular add.
|
||||||
*/
|
*/
|
||||||
struct ureg s = emit_decl(&p, PROGRAM_INPUT, VERT_ATTRIB_COLOR1);
|
struct ureg s = register_input(&p, FRAG_ATTRIB_COL1);
|
||||||
emit_arith( &p, FP_OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef );
|
emit_arith( &p, FP_OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef );
|
||||||
}
|
}
|
||||||
else if (memcmp(&cf, &out, sizeof(cf)) != 0) {
|
else if (memcmp(&cf, &out, sizeof(cf)) != 0) {
|
||||||
@@ -753,18 +698,23 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
|
|||||||
emit_arith( &p, FP_OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef );
|
emit_arith( &p, FP_OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.prog->NumTexIndirections > ctx->Const.MaxFragmentProgramTexIndirections)
|
/* Finish up:
|
||||||
|
*/
|
||||||
|
emit_arith( &p, FP_OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef);
|
||||||
|
|
||||||
|
|
||||||
|
if (p.program->NumTexIndirections > ctx->Const.MaxFragmentProgramTexIndirections)
|
||||||
program_error(&p, "Exceeded max nr indirect texture lookups");
|
program_error(&p, "Exceeded max nr indirect texture lookups");
|
||||||
|
|
||||||
if (p.prog->NumTexInstructions > ctx->Const.MaxFragmentProgramTexInstructions)
|
if (p.program->NumTexInstructions > ctx->Const.MaxFragmentProgramTexInstructions)
|
||||||
program_error(&p, "Exceeded max TEX instructions");
|
program_error(&p, "Exceeded max TEX instructions");
|
||||||
|
|
||||||
if (p.prog->NumAluInstructions > ctx->Const.MaxFragmentProgramAluInstructions)
|
if (p.program->NumAluInstructions > ctx->Const.MaxFragmentProgramAluInstructions)
|
||||||
program_error(&p, "Exceeded max ALU instructions");
|
program_error(&p, "Exceeded max ALU instructions");
|
||||||
|
|
||||||
#if DISASSEM
|
#if DISASSEM
|
||||||
_mesa_debug_fp_inst(p.prog->NumTexInstructions + p.prog->NumAluInstructions,
|
_mesa_debug_fp_inst(p.program->NumTexInstructions + p.program->NumAluInstructions,
|
||||||
p.prog->Instructions);
|
p.program->Instructions);
|
||||||
_mesa_printf("\n");
|
_mesa_printf("\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
39
src/mesa/main/texenvprogram.h
Normal file
39
src/mesa/main/texenvprogram.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* \file texenvprogram.h
|
||||||
|
* Texture state management.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mesa 3-D graphics library
|
||||||
|
* Version: 5.1
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TEXENVPROGRAM_H
|
||||||
|
#define TEXENVPROGRAM_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
|
||||||
|
extern void _mesa_UpdateTexEnvProgram( GLcontext *ctx );
|
||||||
|
|
||||||
|
#endif
|
@@ -46,6 +46,7 @@ MAIN_SOURCES = \
|
|||||||
main/texcompress.c \
|
main/texcompress.c \
|
||||||
main/texcompress_s3tc.c \
|
main/texcompress_s3tc.c \
|
||||||
main/texcompress_fxt1.c \
|
main/texcompress_fxt1.c \
|
||||||
|
main/texenvprogram.c \
|
||||||
main/texformat.c \
|
main/texformat.c \
|
||||||
main/teximage.c \
|
main/teximage.c \
|
||||||
main/texobj.c \
|
main/texobj.c \
|
||||||
|
@@ -80,7 +80,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
|
|||||||
#ifdef DO_TEX
|
#ifdef DO_TEX
|
||||||
{
|
{
|
||||||
GLfloat invQ;
|
GLfloat invQ;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
invQ = 1.0F;
|
invQ = 1.0F;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -100,7 +100,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
|
|||||||
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
|
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
|
||||||
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
|
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
|
||||||
GLfloat invQ;
|
GLfloat invQ;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
invQ = 1.0F;
|
invQ = 1.0F;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -104,7 +104,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
|
|||||||
rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
|
rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
rasterMask |= FRAGPROG_BIT;
|
rasterMask |= FRAGPROG_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ _swrast_update_fog_hint( GLcontext *ctx )
|
|||||||
{
|
{
|
||||||
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||||
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
|
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
|
||||||
ctx->FragmentProgram._Enabled ||
|
ctx->FragmentProgram._Active ||
|
||||||
(ctx->Hint.Fog == GL_NICEST &&
|
(ctx->Hint.Fog == GL_NICEST &&
|
||||||
swrast->AllowPixelFog));
|
swrast->AllowPixelFog));
|
||||||
}
|
}
|
||||||
@@ -202,10 +202,10 @@ _swrast_update_fog_state( GLcontext *ctx )
|
|||||||
|
|
||||||
/* determine if fog is needed, and if so, which fog mode */
|
/* determine if fog is needed, and if so, which fog mode */
|
||||||
swrast->_FogEnabled = GL_FALSE;
|
swrast->_FogEnabled = GL_FALSE;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
if (ctx->FragmentProgram.Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) {
|
if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) {
|
||||||
const struct fragment_program *p
|
const struct fragment_program *p
|
||||||
= (struct fragment_program *) ctx->FragmentProgram.Current;
|
= (struct fragment_program *) ctx->FragmentProgram._Current;
|
||||||
if (p->FogOption != GL_NONE) {
|
if (p->FogOption != GL_NONE) {
|
||||||
swrast->_FogEnabled = GL_TRUE;
|
swrast->_FogEnabled = GL_TRUE;
|
||||||
swrast->_FogMode = p->FogOption;
|
swrast->_FogMode = p->FogOption;
|
||||||
@@ -226,8 +226,8 @@ _swrast_update_fog_state( GLcontext *ctx )
|
|||||||
static void
|
static void
|
||||||
_swrast_update_fragment_program( GLcontext *ctx )
|
_swrast_update_fragment_program( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
struct fragment_program *program = ctx->FragmentProgram.Current;
|
struct fragment_program *program = ctx->FragmentProgram._Current;
|
||||||
_mesa_load_state_parameters(ctx, program->Parameters);
|
_mesa_load_state_parameters(ctx, program->Parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ _swrast_validate_triangle( GLcontext *ctx,
|
|||||||
|
|
||||||
if (ctx->Texture._EnabledUnits == 0
|
if (ctx->Texture._EnabledUnits == 0
|
||||||
&& NEED_SECONDARY_COLOR(ctx)
|
&& NEED_SECONDARY_COLOR(ctx)
|
||||||
&& !ctx->FragmentProgram._Enabled) {
|
&& !ctx->FragmentProgram._Active) {
|
||||||
/* separate specular color, but no texture */
|
/* separate specular color, but no texture */
|
||||||
swrast->SpecTriangle = swrast->Triangle;
|
swrast->SpecTriangle = swrast->Triangle;
|
||||||
swrast->Triangle = _swrast_add_spec_terms_triangle;
|
swrast->Triangle = _swrast_add_spec_terms_triangle;
|
||||||
@@ -318,7 +318,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
|
|||||||
|
|
||||||
if (ctx->Texture._EnabledUnits == 0
|
if (ctx->Texture._EnabledUnits == 0
|
||||||
&& NEED_SECONDARY_COLOR(ctx)
|
&& NEED_SECONDARY_COLOR(ctx)
|
||||||
&& !ctx->FragmentProgram._Enabled) {
|
&& !ctx->FragmentProgram._Active) {
|
||||||
swrast->SpecLine = swrast->Line;
|
swrast->SpecLine = swrast->Line;
|
||||||
swrast->Line = _swrast_add_spec_terms_line;
|
swrast->Line = _swrast_add_spec_terms_line;
|
||||||
}
|
}
|
||||||
@@ -341,7 +341,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
|
|||||||
|
|
||||||
if (ctx->Texture._EnabledUnits == 0
|
if (ctx->Texture._EnabledUnits == 0
|
||||||
&& NEED_SECONDARY_COLOR(ctx)
|
&& NEED_SECONDARY_COLOR(ctx)
|
||||||
&& !ctx->FragmentProgram._Enabled) {
|
&& !ctx->FragmentProgram._Active) {
|
||||||
swrast->SpecPoint = swrast->Point;
|
swrast->SpecPoint = swrast->Point;
|
||||||
swrast->Point = _swrast_add_spec_terms_point;
|
swrast->Point = _swrast_add_spec_terms_point;
|
||||||
}
|
}
|
||||||
|
@@ -808,7 +808,7 @@ static void translate_program( struct fragment_program *p )
|
|||||||
|
|
||||||
void _swrast_translate_program( GLcontext *ctx )
|
void _swrast_translate_program( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
struct fragment_program *p = ctx->FragmentProgram.Current;
|
struct fragment_program *p = ctx->FragmentProgram._Current;
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
p->c_strlen = 0;
|
p->c_strlen = 0;
|
||||||
|
@@ -1410,7 +1410,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
|
|||||||
void
|
void
|
||||||
_swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
|
_swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
|
||||||
{
|
{
|
||||||
const struct fragment_program *program = ctx->FragmentProgram.Current;
|
const struct fragment_program *program = ctx->FragmentProgram._Current;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
|
ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
|
||||||
@@ -1418,7 +1418,7 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
|
|||||||
for (i = 0; i < span->end; i++) {
|
for (i = 0; i < span->end; i++) {
|
||||||
if (span->array->mask[i]) {
|
if (span->array->mask[i]) {
|
||||||
init_machine(ctx, &ctx->FragmentProgram.Machine,
|
init_machine(ctx, &ctx->FragmentProgram.Machine,
|
||||||
ctx->FragmentProgram.Current, span, i);
|
ctx->FragmentProgram._Current, span, i);
|
||||||
|
|
||||||
#ifdef USE_TCC
|
#ifdef USE_TCC
|
||||||
if (!_swrast_execute_codegen_program(ctx, program, ~0,
|
if (!_swrast_execute_codegen_program(ctx, program, ~0,
|
||||||
|
@@ -120,7 +120,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
|
|||||||
#endif
|
#endif
|
||||||
#if FLAGS & TEXTURE
|
#if FLAGS & TEXTURE
|
||||||
span->arrayMask |= SPAN_TEXTURE;
|
span->arrayMask |= SPAN_TEXTURE;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
/* Don't divide texture s,t,r by q (use TXP to do that) */
|
/* Don't divide texture s,t,r by q (use TXP to do that) */
|
||||||
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
|
||||||
if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
|
if (ctx->Texture._EnabledCoordUnits & (1 << u)) {
|
||||||
|
@@ -128,7 +128,7 @@ _swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span )
|
|||||||
GLuint i;
|
GLuint i;
|
||||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
|
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
|
||||||
const GLfloat *tc = ctx->Current.RasterTexCoords[i];
|
const GLfloat *tc = ctx->Current.RasterTexCoords[i];
|
||||||
if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) {
|
if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled) {
|
||||||
COPY_4V(span->tex[i], tc);
|
COPY_4V(span->tex[i], tc);
|
||||||
}
|
}
|
||||||
else if (tc[3] > 0.0F) {
|
else if (tc[3] > 0.0F) {
|
||||||
@@ -406,7 +406,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
if (obj) {
|
if (obj) {
|
||||||
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
|
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
|
||||||
needLambda = (obj->MinFilter != obj->MagFilter)
|
needLambda = (obj->MinFilter != obj->MagFilter)
|
||||||
|| ctx->FragmentProgram._Enabled;
|
|| ctx->FragmentProgram._Active;
|
||||||
texW = img->WidthScale;
|
texW = img->WidthScale;
|
||||||
texH = img->HeightScale;
|
texH = img->HeightScale;
|
||||||
}
|
}
|
||||||
@@ -431,7 +431,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
GLfloat r = span->tex[u][2];
|
GLfloat r = span->tex[u][2];
|
||||||
GLfloat q = span->tex[u][3];
|
GLfloat q = span->tex[u][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
/* do perspective correction but don't divide s, t, r by q */
|
/* do perspective correction but don't divide s, t, r by q */
|
||||||
const GLfloat dwdx = span->dwdx;
|
const GLfloat dwdx = span->dwdx;
|
||||||
GLfloat w = span->w;
|
GLfloat w = span->w;
|
||||||
@@ -482,7 +482,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
GLfloat r = span->tex[u][2];
|
GLfloat r = span->tex[u][2];
|
||||||
GLfloat q = span->tex[u][3];
|
GLfloat q = span->tex[u][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
/* do perspective correction but don't divide s, t, r by q */
|
/* do perspective correction but don't divide s, t, r by q */
|
||||||
const GLfloat dwdx = span->dwdx;
|
const GLfloat dwdx = span->dwdx;
|
||||||
GLfloat w = span->w;
|
GLfloat w = span->w;
|
||||||
@@ -540,7 +540,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
if (obj) {
|
if (obj) {
|
||||||
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
|
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
|
||||||
needLambda = (obj->MinFilter != obj->MagFilter)
|
needLambda = (obj->MinFilter != obj->MagFilter)
|
||||||
|| ctx->FragmentProgram._Enabled;
|
|| ctx->FragmentProgram._Active;
|
||||||
texW = (GLfloat) img->WidthScale;
|
texW = (GLfloat) img->WidthScale;
|
||||||
texH = (GLfloat) img->HeightScale;
|
texH = (GLfloat) img->HeightScale;
|
||||||
}
|
}
|
||||||
@@ -565,7 +565,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
GLfloat r = span->tex[0][2];
|
GLfloat r = span->tex[0][2];
|
||||||
GLfloat q = span->tex[0][3];
|
GLfloat q = span->tex[0][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
/* do perspective correction but don't divide s, t, r by q */
|
/* do perspective correction but don't divide s, t, r by q */
|
||||||
const GLfloat dwdx = span->dwdx;
|
const GLfloat dwdx = span->dwdx;
|
||||||
GLfloat w = span->w;
|
GLfloat w = span->w;
|
||||||
@@ -616,7 +616,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
|
|||||||
GLfloat r = span->tex[0][2];
|
GLfloat r = span->tex[0][2];
|
||||||
GLfloat q = span->tex[0][3];
|
GLfloat q = span->tex[0][3];
|
||||||
GLuint i;
|
GLuint i;
|
||||||
if (ctx->FragmentProgram._Enabled) {
|
if (ctx->FragmentProgram._Active) {
|
||||||
/* do perspective correction but don't divide s, t, r by q */
|
/* do perspective correction but don't divide s, t, r by q */
|
||||||
const GLfloat dwdx = span->dwdx;
|
const GLfloat dwdx = span->dwdx;
|
||||||
GLfloat w = span->w;
|
GLfloat w = span->w;
|
||||||
@@ -1174,7 +1174,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
|
|||||||
interpolate_fog(ctx, span);
|
interpolate_fog(ctx, span);
|
||||||
|
|
||||||
/* Compute fragment colors with fragment program or texture lookups */
|
/* Compute fragment colors with fragment program or texture lookups */
|
||||||
if (ctx->FragmentProgram._Enabled)
|
if (ctx->FragmentProgram._Active)
|
||||||
/* XXX interpolate depth values here??? */
|
/* XXX interpolate depth values here??? */
|
||||||
_swrast_exec_fragment_program( ctx, span );
|
_swrast_exec_fragment_program( ctx, span );
|
||||||
else if (ctx->ATIFragmentShader._Enabled)
|
else if (ctx->ATIFragmentShader._Enabled)
|
||||||
@@ -1252,7 +1252,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
|
|||||||
if (span->interpMask & SPAN_FOG)
|
if (span->interpMask & SPAN_FOG)
|
||||||
interpolate_fog(ctx, span);
|
interpolate_fog(ctx, span);
|
||||||
|
|
||||||
if (ctx->FragmentProgram._Enabled)
|
if (ctx->FragmentProgram._Active)
|
||||||
_swrast_exec_fragment_program( ctx, span );
|
_swrast_exec_fragment_program( ctx, span );
|
||||||
else if (ctx->ATIFragmentShader._Enabled)
|
else if (ctx->ATIFragmentShader._Enabled)
|
||||||
_swrast_exec_fragment_shader( ctx, span );
|
_swrast_exec_fragment_shader( ctx, span );
|
||||||
@@ -1262,7 +1262,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
|
|||||||
|
|
||||||
ASSERT(span->arrayMask & SPAN_RGBA);
|
ASSERT(span->arrayMask & SPAN_RGBA);
|
||||||
|
|
||||||
if (!ctx->FragmentProgram._Enabled) {
|
if (!ctx->FragmentProgram._Active) {
|
||||||
/* Add base and specular colors */
|
/* Add base and specular colors */
|
||||||
if (ctx->Fog.ColorSumEnabled ||
|
if (ctx->Fog.ColorSumEnabled ||
|
||||||
(ctx->Light.Enabled &&
|
(ctx->Light.Enabled &&
|
||||||
|
@@ -1075,7 +1075,7 @@ _swrast_choose_triangle( GLcontext *ctx )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled) {
|
if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Active) {
|
||||||
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
|
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
|
||||||
const struct gl_texture_object *texObj2D;
|
const struct gl_texture_object *texObj2D;
|
||||||
const struct gl_texture_image *texImg;
|
const struct gl_texture_image *texImg;
|
||||||
@@ -1090,7 +1090,7 @@ _swrast_choose_triangle( GLcontext *ctx )
|
|||||||
|
|
||||||
/* First see if we can use an optimized 2-D texture function */
|
/* First see if we can use an optimized 2-D texture function */
|
||||||
if (ctx->Texture._EnabledCoordUnits == 0x1
|
if (ctx->Texture._EnabledCoordUnits == 0x1
|
||||||
&& !ctx->FragmentProgram._Enabled
|
&& !ctx->FragmentProgram._Active
|
||||||
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
|
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
|
||||||
&& texObj2D->WrapS == GL_REPEAT
|
&& texObj2D->WrapS == GL_REPEAT
|
||||||
&& texObj2D->WrapT == GL_REPEAT
|
&& texObj2D->WrapT == GL_REPEAT
|
||||||
|
@@ -367,6 +367,10 @@ static void emit_matrix_transform_vec4( struct tnl_program *p,
|
|||||||
emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);
|
emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This version is much easier to implement if writemasks are not
|
||||||
|
* supported natively on the target or (like SSE), the target doesn't
|
||||||
|
* have a clean/obvious dotproduct implementation.
|
||||||
|
*/
|
||||||
static void emit_transpose_matrix_transform_vec4( struct tnl_program *p,
|
static void emit_transpose_matrix_transform_vec4( struct tnl_program *p,
|
||||||
struct ureg dest,
|
struct ureg dest,
|
||||||
const struct ureg *mat,
|
const struct ureg *mat,
|
||||||
@@ -692,14 +696,12 @@ static void build_lighting( struct tnl_program *p )
|
|||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (light->EyePosition[3] == 0) {
|
if (light->EyePosition[3] == 0) {
|
||||||
/* Can used precomputed constants in this case:
|
/* Can used precomputed constants in this case.
|
||||||
|
* Attenuation never applies to infinite lights.
|
||||||
*/
|
*/
|
||||||
VPpli = register_param3(p, STATE_LIGHT, i,
|
VPpli = register_param3(p, STATE_LIGHT, i,
|
||||||
STATE_POSITION_NORMALIZED);
|
STATE_POSITION_NORMALIZED);
|
||||||
half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
|
half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
|
||||||
|
|
||||||
/* Spot attenuation maybe applies to this case? Could
|
|
||||||
* precompute if so? */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct ureg Ppli = register_param3(p, STATE_LIGHT, i,
|
struct ureg Ppli = register_param3(p, STATE_LIGHT, i,
|
||||||
@@ -1082,9 +1084,15 @@ static void build_pointsize( struct tnl_program *p )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void build_passthrough( struct tnl_program *p, GLuint inputs )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
|
void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct tnl_program p;
|
struct tnl_program p;
|
||||||
|
|
||||||
if (ctx->VertexProgram._Enabled)
|
if (ctx->VertexProgram._Enabled)
|
||||||
@@ -1136,6 +1144,15 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
|
|||||||
if (ctx->Point._Attenuated)
|
if (ctx->Point._Attenuated)
|
||||||
build_pointsize(&p);
|
build_pointsize(&p);
|
||||||
|
|
||||||
|
/* Is there a need to copy inputs to outputs? The software
|
||||||
|
* implementation might do this more efficiently by just assigning
|
||||||
|
* the missing results to point at input arrays.
|
||||||
|
*/
|
||||||
|
if (/* tnl->vp_copy_inputs && */
|
||||||
|
(tnl->render_inputs & ~p.program->OutputsWritten)) {
|
||||||
|
build_passthrough(&p, tnl->render_inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finish up:
|
/* Finish up:
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user