nouveau: NV40 glClipPlane support.

This commit is contained in:
Ben Skeggs 2007-01-30 16:00:20 +11:00
parent ede8017d2c
commit d2c4d9ff9b
5 changed files with 101 additions and 13 deletions

View File

@ -32,6 +32,7 @@ typedef union {
struct { struct {
uint32_t vp_in_reg; uint32_t vp_in_reg;
uint32_t vp_out_reg; uint32_t vp_out_reg;
uint32_t clip_enables;
} NV30VP; } NV30VP;
} nvsCardPriv; } nvsCardPriv;

View File

@ -811,12 +811,65 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp)
} }
static void static void
pass0_prealloc_mesa_consts(nouveauShader *nvs) pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs)
{
struct gl_program *prog = &nvs->mesa.vp.Base;
nvsFragmentHeader *parent = nvs->program_tree;
nvsInstruction *nvsinst;
GLuint fpos = 0;
nvsRegister opos, epos, eqn, mv[4];
GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 };
GLint id;
int i;
/* modelview transform */
pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION);
pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1);
for (i=0; i<4; i++) {
tokens[3] = tokens[4] = i;
id = _mesa_add_state_reference(prog->Parameters, tokens);
pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id);
}
ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused);
ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused);
ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused);
ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused);
/* Emit code to emulate fixed-function glClipPlane */
for (i=0; i<6; i++) {
GLuint clipmask = SMASK_X;
nvsRegister clip;
if (!(ctx->Transform.ClipPlanesEnabled & (1<<i)))
continue;
/* Point a const at a user clipping plane */
tokens[0] = STATE_CLIPPLANE;
tokens[1] = i;
id = _mesa_add_state_reference(prog->Parameters, tokens);
pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id);
pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i);
/*XXX: something else needs to take care of modifying the
* instructions to write to the correct hw clip register.
*/
switch (i) {
case 0: case 3: clipmask = SMASK_Y; break;
case 1: case 4: clipmask = SMASK_Z; break;
case 2: case 5: clipmask = SMASK_W; break;
}
/* Emit transform */
ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused);
}
}
static void
pass0_rebase_mesa_consts(nouveauShader *nvs)
{ {
struct pass0_rec *rec = nvs->pass_rec; struct pass0_rec *rec = nvs->pass_rec;
struct gl_program *prog = &nvs->mesa.vp.Base; struct gl_program *prog = &nvs->mesa.vp.Base;
struct prog_instruction *inst = prog->Instructions; struct prog_instruction *inst = prog->Instructions;
struct gl_program_parameter_list *plist = prog->Parameters;
int i; int i;
/*XXX: not a good idea, params->hw_index is malloc'd */ /*XXX: not a good idea, params->hw_index is malloc'd */
@ -848,10 +901,23 @@ pass0_prealloc_mesa_consts(nouveauShader *nvs)
inst++; inst++;
} }
}
static void
pass0_resolve_mesa_consts(nouveauShader *nvs)
{
struct pass0_rec *rec = nvs->pass_rec;
struct gl_program *prog = &nvs->mesa.vp.Base;
struct gl_program_parameter_list *plist = prog->Parameters;
int i;
/* Init all const tracking/alloc info from the parameter list, rather /* Init all const tracking/alloc info from the parameter list, rather
* than doing it as we translate the program. Otherwise we can't get * than doing it as we translate the program. Otherwise:
* at the correct constant info when relative addressing is being used. * 1) we can't get at the correct constant info when relative
* addressing is being used due to src->Index not pointing
* at the exact const;
* 2) as we add extra consts to the program, mesa will call realloc()
* and we get invalid pointers to the const data.
*/ */
rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base;
nvs->param_high = rec->mesa_const_last; nvs->param_high = rec->mesa_const_last;
@ -907,12 +973,10 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
if (vp->IsPositionInvariant) if (vp->IsPositionInvariant)
_mesa_insert_mvp_code(ctx, vp); _mesa_insert_mvp_code(ctx, vp);
pass0_prealloc_mesa_consts(nvs); pass0_rebase_mesa_consts(nvs);
#if 0 if (!prog->String && ctx->Transform.ClipPlanesEnabled)
if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) pass0_vp_insert_ff_clip_planes(ctx, nvs);
pass0_insert_ff_clip_planes();
#endif
pass0_build_attrib_map(nvs, vp); pass0_build_attrib_map(nvs, vp);
break; break;
@ -921,7 +985,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
if (fp->FogOption != GL_NONE) if (fp->FogOption != GL_NONE)
_mesa_append_fog_code(ctx, fp); _mesa_append_fog_code(ctx, fp);
pass0_prealloc_mesa_consts(nvs); pass0_rebase_mesa_consts(nvs);
break; break;
default: default:
fprintf(stderr, "Unknown program type %d", prog->Target); fprintf(stderr, "Unknown program type %d", prog->Target);
@ -932,6 +996,8 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
nvs->func->card_priv = &nvs->card_priv; nvs->func->card_priv = &nvs->card_priv;
ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
if (ret)
pass0_resolve_mesa_consts(nvs);
/*XXX: if (!ret) DESTROY TREE!!! */ /*XXX: if (!ret) DESTROY TREE!!! */
FREE(rec); FREE(rec);

View File

@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s)
static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
{ {
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
if (NOUVEAU_CARD_USING_SHADERS)
return;
plane -= GL_CLIP_PLANE0;
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4);
OUT_RING_CACHEf(equation[0]); OUT_RING_CACHEf(equation[0]);
OUT_RING_CACHEf(equation[1]); OUT_RING_CACHEf(equation[1]);
@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state)
case GL_CLIP_PLANE3: case GL_CLIP_PLANE3:
case GL_CLIP_PLANE4: case GL_CLIP_PLANE4:
case GL_CLIP_PLANE5: case GL_CLIP_PLANE5:
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); if (NOUVEAU_CARD_USING_SHADERS) {
OUT_RING_CACHE(state); nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current;
if (nvs)
nvs->translated = GL_FALSE;
} else {
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1);
OUT_RING_CACHE(state);
}
break; break;
case GL_COLOR_LOGIC_OP: case GL_COLOR_LOGIC_OP:
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1);

View File

@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); OUT_RING(nvs->card_priv.NV30VP.vp_in_reg);
OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); OUT_RING(nvs->card_priv.NV30VP.vp_out_reg);
BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables);
} }
static void static void

View File

@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result,
unsigned int *mask_ret) unsigned int *mask_ret)
{ {
unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg;
unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables;
*mask_ret = 0xf; *mask_ret = 0xf;
@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result,
return NV40_VP_INST_DEST_FOGC; return NV40_VP_INST_DEST_FOGC;
case NVS_FR_CLIP0: case NVS_FR_CLIP0:
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0;
(*clip_en) |= 0x00000002;
*mask_ret = 0x4; *mask_ret = 0x4;
return NV40_VP_INST_DEST_FOGC; return NV40_VP_INST_DEST_FOGC;
case NVS_FR_CLIP1: case NVS_FR_CLIP1:
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1;
(*clip_en) |= 0x00000020;
*mask_ret = 0x2; *mask_ret = 0x2;
return NV40_VP_INST_DEST_FOGC; return NV40_VP_INST_DEST_FOGC;
case NVS_FR_CLIP2: case NVS_FR_CLIP2:
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2;
(*clip_en) |= 0x00000200;
*mask_ret = 0x1; *mask_ret = 0x1;
return NV40_VP_INST_DEST_FOGC; return NV40_VP_INST_DEST_FOGC;
case NVS_FR_POINTSZ: case NVS_FR_POINTSZ:
@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result,
return NV40_VP_INST_DEST_PSZ; return NV40_VP_INST_DEST_PSZ;
case NVS_FR_CLIP3: case NVS_FR_CLIP3:
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3;
(*clip_en) |= 0x00002000;
*mask_ret = 0x4; *mask_ret = 0x4;
return NV40_VP_INST_DEST_PSZ; return NV40_VP_INST_DEST_PSZ;
case NVS_FR_CLIP4: case NVS_FR_CLIP4:
(*clip_en) |= 0x00020000;
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4;
*mask_ret = 0x2; *mask_ret = 0x2;
return NV40_VP_INST_DEST_PSZ; return NV40_VP_INST_DEST_PSZ;
case NVS_FR_CLIP5: case NVS_FR_CLIP5:
(*clip_en) |= 0x00200000;
(*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5;
*mask_ret = 0x1; *mask_ret = 0x1;
return NV40_VP_INST_DEST_PSZ; return NV40_VP_INST_DEST_PSZ;