fragment.position support
World position is calculated in the vertex shader and passed to the fragment shader via an unused texcoord.
This commit is contained in:
parent
0f614df797
commit
6c9cc81601
|
@ -549,6 +549,7 @@ struct r300_stencilbuffer_state {
|
|||
/* Can be tested with colormat currently. */
|
||||
#define VSF_MAX_FRAGMENT_TEMPS (14)
|
||||
|
||||
#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
|
||||
|
||||
struct r300_vertex_shader_fragment {
|
||||
int length;
|
||||
|
@ -623,6 +624,7 @@ struct r300_vertex_program {
|
|||
|
||||
int pos_end;
|
||||
int num_temporaries; /* Number of temp vars used by program */
|
||||
int wpos_idx;
|
||||
int inputs[VERT_ATTRIB_MAX];
|
||||
int outputs[VERT_RESULT_MAX];
|
||||
int native;
|
||||
|
|
|
@ -1555,6 +1555,13 @@ static void init_program(struct r300_fragment_program *rp)
|
|||
}
|
||||
InputsRead &= ~FRAG_BITS_TEX_ANY;
|
||||
|
||||
/* fragment position treated as a texcoord */
|
||||
if (InputsRead & FRAG_BIT_WPOS) {
|
||||
cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0;
|
||||
cs->inputs[FRAG_ATTRIB_WPOS].reg = get_hw_temp(rp);
|
||||
}
|
||||
InputsRead &= ~FRAG_BIT_WPOS;
|
||||
|
||||
/* Then primary colour */
|
||||
if (InputsRead & FRAG_BIT_COL0) {
|
||||
cs->inputs[FRAG_ATTRIB_COL0].refcount = 0;
|
||||
|
|
|
@ -1044,6 +1044,59 @@ r300UpdateDrawBuffer(GLcontext *ctx)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[],
|
||||
GLfloat *value)
|
||||
{
|
||||
r300ContextPtr r300 = R300_CONTEXT(ctx);
|
||||
|
||||
switch(state[0])
|
||||
{
|
||||
case STATE_INTERNAL:
|
||||
switch(state[1])
|
||||
{
|
||||
case STATE_R300_WINDOW_DIMENSION:
|
||||
value[0] = r300->radeon.dri.drawable->w; /* width */
|
||||
value[1] = r300->radeon.dri.drawable->h; /* height */
|
||||
value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
|
||||
value[3] = 1.0F; /* not used */
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update R300's own internal state parameters.
|
||||
* For now just STATE_R300_WINDOW_DIMENSION
|
||||
*/
|
||||
static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
|
||||
{
|
||||
struct r300_vertex_program_cont *vpc;
|
||||
struct gl_program_parameter_list *paramList;
|
||||
GLuint i;
|
||||
|
||||
if(!(new_state & (_NEW_BUFFERS|_NEW_PROGRAM)))
|
||||
return;
|
||||
|
||||
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
|
||||
if (!vpc)
|
||||
return;
|
||||
|
||||
paramList = vpc->mesa_program.Base.Parameters;
|
||||
|
||||
if (!paramList)
|
||||
return;
|
||||
|
||||
for (i = 0; i < paramList->NumParameters; i++) {
|
||||
if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR){
|
||||
r300FetchStateParameter(ctx,
|
||||
paramList->Parameters[i].StateIndexes,
|
||||
paramList->ParameterValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
* Polygon state
|
||||
*/
|
||||
|
@ -1304,6 +1357,20 @@ void r300_setup_rs_unit(GLcontext *ctx)
|
|||
|
||||
r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
|
||||
|
||||
if (InputsRead & FRAG_BIT_WPOS){
|
||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
|
||||
if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
|
||||
break;
|
||||
|
||||
if(i == ctx->Const.MaxTextureUnits){
|
||||
fprintf(stderr, "\tno free texcoord found...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
InputsRead |= (FRAG_BIT_TEX0 << i);
|
||||
InputsRead &= ~FRAG_BIT_WPOS;
|
||||
}
|
||||
|
||||
for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
|
||||
r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
|
||||
| R300_RS_INTERP_USED
|
||||
|
@ -1680,6 +1747,7 @@ void r300UpdateShaders(r300ContextPtr rmesa)
|
|||
|
||||
return ;
|
||||
}
|
||||
r300UpdateStateParameters(ctx, _NEW_PROGRAM);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1813,6 +1881,9 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
|
|||
if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
|
||||
r300UpdateDrawBuffer(ctx);
|
||||
}
|
||||
|
||||
r300UpdateStateParameters(ctx, new_state);
|
||||
|
||||
#ifndef CB_DPATH
|
||||
/* Go inefficiency! */
|
||||
r300ResetHwState(r300);
|
||||
|
|
|
@ -958,17 +958,155 @@ static void position_invariant(struct gl_program *prog)
|
|||
assert(vpi->Opcode == OPCODE_END);
|
||||
}
|
||||
|
||||
static void insert_wpos(struct r300_vertex_program *vp,
|
||||
struct gl_program *prog,
|
||||
GLint pos)
|
||||
{
|
||||
|
||||
GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 };
|
||||
struct prog_instruction *vpi;
|
||||
struct prog_instruction *vpi_insert;
|
||||
GLuint temp_index;
|
||||
GLuint window_index;
|
||||
int i = 0;
|
||||
|
||||
vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction));
|
||||
memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction));
|
||||
|
||||
vpi_insert = &vpi[pos];
|
||||
|
||||
/* make a copy before outputting VERT_RESULT_HPOS */
|
||||
vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
|
||||
vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
|
||||
|
||||
vpi_insert++;
|
||||
memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
|
||||
|
||||
vpi_insert[i].Opcode = OPCODE_MOV;
|
||||
|
||||
vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
|
||||
vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
|
||||
vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
vpi_insert[i].DstReg.CondMask = COND_TR;
|
||||
|
||||
vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[0].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
|
||||
i++;
|
||||
|
||||
/* perspective divide */
|
||||
vpi_insert[i].Opcode = OPCODE_RCP;
|
||||
|
||||
vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].DstReg.Index = temp_index;
|
||||
vpi_insert[i].DstReg.WriteMask = WRITEMASK_W;
|
||||
vpi_insert[i].DstReg.CondMask = COND_TR;
|
||||
|
||||
vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[0].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
|
||||
i++;
|
||||
|
||||
vpi_insert[i].Opcode = OPCODE_MUL;
|
||||
|
||||
vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].DstReg.Index = temp_index;
|
||||
vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
|
||||
vpi_insert[i].DstReg.CondMask = COND_TR;
|
||||
|
||||
vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[0].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
|
||||
vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[1].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_ZERO);
|
||||
i++;
|
||||
|
||||
/* viewport transformation */
|
||||
window_index = _mesa_add_state_reference(prog->Parameters, tokens);
|
||||
|
||||
vpi_insert[i].Opcode = OPCODE_MAD;
|
||||
|
||||
vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].DstReg.Index = temp_index;
|
||||
vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
|
||||
vpi_insert[i].DstReg.CondMask = COND_TR;
|
||||
|
||||
vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[0].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
|
||||
vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
|
||||
vpi_insert[i].SrcReg[1].Index = window_index;
|
||||
vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
|
||||
vpi_insert[i].SrcReg[2].File = PROGRAM_STATE_VAR;
|
||||
vpi_insert[i].SrcReg[2].Index = window_index;
|
||||
vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO);
|
||||
i++;
|
||||
|
||||
vpi_insert[i].Opcode = OPCODE_MUL;
|
||||
|
||||
vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
|
||||
vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0+vp->wpos_idx;
|
||||
vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
|
||||
vpi_insert[i].DstReg.CondMask = COND_TR;
|
||||
|
||||
vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
|
||||
vpi_insert[i].SrcReg[0].Index = temp_index;
|
||||
vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
|
||||
|
||||
vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR;
|
||||
vpi_insert[i].SrcReg[1].Index = window_index;
|
||||
vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE);
|
||||
i++;
|
||||
|
||||
memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
|
||||
|
||||
free(prog->Instructions);
|
||||
|
||||
prog->Instructions = vpi;
|
||||
|
||||
prog->NumInstructions += i;
|
||||
vpi = &prog->Instructions[prog->NumInstructions-1];
|
||||
|
||||
assert(vpi->Opcode == OPCODE_END);
|
||||
}
|
||||
|
||||
static void pos_as_texcoord(struct r300_vertex_program *vp,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
struct prog_instruction *vpi;
|
||||
int pos = 0;
|
||||
|
||||
for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){
|
||||
if( vpi->DstReg.File == PROGRAM_OUTPUT &&
|
||||
vpi->DstReg.Index == VERT_RESULT_HPOS ){
|
||||
insert_wpos(vp, prog, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key,
|
||||
struct gl_vertex_program *mesa_vp)
|
||||
struct gl_vertex_program *mesa_vp,
|
||||
GLint wpos_idx)
|
||||
{
|
||||
struct r300_vertex_program *vp;
|
||||
|
||||
vp = _mesa_calloc(sizeof(*vp));
|
||||
_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
|
||||
|
||||
vp->wpos_idx = wpos_idx;
|
||||
|
||||
if(mesa_vp->IsPositionInvariant)
|
||||
position_invariant(&mesa_vp->Base);
|
||||
|
||||
if(wpos_idx > -1)
|
||||
pos_as_texcoord(vp, &mesa_vp->Base);
|
||||
|
||||
assert(mesa_vp->Base.NumInstructions);
|
||||
|
||||
vp->num_temporaries=mesa_vp->Base.NumTemporaries;
|
||||
|
@ -986,12 +1124,28 @@ void r300_select_vertex_shader(r300ContextPtr r300)
|
|||
GLint i;
|
||||
struct r300_vertex_program_cont *vpc;
|
||||
struct r300_vertex_program *vp;
|
||||
GLint wpos_idx;
|
||||
|
||||
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
|
||||
InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
|
||||
|
||||
wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
|
||||
|
||||
wpos_idx = -1;
|
||||
if (InputsRead & FRAG_BIT_WPOS){
|
||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
|
||||
if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
|
||||
break;
|
||||
|
||||
if(i == ctx->Const.MaxTextureUnits){
|
||||
fprintf(stderr, "\tno free texcoord found\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
InputsRead |= (FRAG_BIT_TEX0 << i);
|
||||
wpos_idx = i;
|
||||
}
|
||||
|
||||
if (InputsRead & FRAG_BIT_COL0)
|
||||
wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
|
||||
|
||||
|
@ -1013,7 +1167,7 @@ void r300_select_vertex_shader(r300ContextPtr r300)
|
|||
|
||||
//_mesa_print_program(&vpc->mesa_program.Base);
|
||||
|
||||
vp = build_program(&wanted_key, &vpc->mesa_program);
|
||||
vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
|
||||
vp->next = vpc->progs;
|
||||
vpc->progs = vp;
|
||||
|
||||
|
|
Loading…
Reference in New Issue