From d2c4d9ff9beb36895bb8ee7aabb65e70c3068816 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:00:20 +1100 Subject: [PATCH] nouveau: NV40 glClipPlane support. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 88 +++++++++++++++++++++---- src/mesa/drivers/dri/nouveau/nv30_state.c | 15 ++++- src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 3 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 7 ++ 5 files changed, 101 insertions(+), 13 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 68007dd..b2df354 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -32,6 +32,7 @@ typedef union { struct { uint32_t vp_in_reg; uint32_t vp_out_reg; + uint32_t clip_enables; } NV30VP; } nvsCardPriv; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index fb6e0b0..73c1f7c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -811,12 +811,65 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) } 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<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 gl_program *prog = &nvs->mesa.vp.Base; struct prog_instruction *inst = prog->Instructions; - struct gl_program_parameter_list *plist = prog->Parameters; int i; /*XXX: not a good idea, params->hw_index is malloc'd */ @@ -848,10 +901,23 @@ pass0_prealloc_mesa_consts(nouveauShader *nvs) 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 - * than doing it as we translate the program. Otherwise we can't get - * at the correct constant info when relative addressing is being used. + * than doing it as we translate the program. Otherwise: + * 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; nvs->param_high = rec->mesa_const_last; @@ -907,12 +973,10 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif + if (!prog->String && ctx->Transform.ClipPlanesEnabled) + pass0_vp_insert_ff_clip_planes(ctx, nvs); pass0_build_attrib_map(nvs, vp); break; @@ -921,7 +985,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); break; default: 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; ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + if (ret) + pass0_resolve_mesa_consts(nvs); /*XXX: if (!ret) DESTROY TREE!!! */ FREE(rec); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 55b6463..db13ec7 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { 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); OUT_RING_CACHEf(equation[0]); 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_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING_CACHE(state); + if (NOUVEAU_CARD_USING_SHADERS) { + 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; case GL_COLOR_LOGIC_OP: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index afcacf3..d023e84 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) 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_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 diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 6cb7e1c..d054140 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, unsigned int *mask_ret) { unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables; *mask_ret = 0xf; @@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP0: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + (*clip_en) |= 0x00000002; *mask_ret = 0x4; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP1: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + (*clip_en) |= 0x00000020; *mask_ret = 0x2; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP2: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + (*clip_en) |= 0x00000200; *mask_ret = 0x1; return NV40_VP_INST_DEST_FOGC; case NVS_FR_POINTSZ: @@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP3: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + (*clip_en) |= 0x00002000; *mask_ret = 0x4; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP4: + (*clip_en) |= 0x00020000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; *mask_ret = 0x2; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP5: + (*clip_en) |= 0x00200000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; *mask_ret = 0x1; return NV40_VP_INST_DEST_PSZ; -- 2.7.4