From b5cd34aa21b9f22e063d214a5d5c39d9553ade0a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 6 Feb 2008 07:54:24 -0700 Subject: Fix bug 9871: enable user-defined clip planes for R300 Patch provided by Erkin Bahceci --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 13 ++++++- src/mesa/drivers/dri/r300/r300_context.h | 10 ++++- src/mesa/drivers/dri/r300/r300_ioctl.c | 4 +- src/mesa/drivers/dri/r300/r300_reg.h | 21 ++++++++++- src/mesa/drivers/dri/r300/r300_state.c | 63 +++++++++++++++++++++++++++++++- 5 files changed, 103 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index d13649ddc0d..3befa58a399 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -316,8 +316,8 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_INPUT_CNTL_0, 2); ALLOC_STATE(unk21DC, always, 2, 0); r300->hw.unk21DC.cmd[0] = cmdpacket0(0x21DC, 1); - ALLOC_STATE(unk221C, always, 2, 0); - r300->hw.unk221C.cmd[0] = cmdpacket0(R300_VAP_UNKNOWN_221C, 1); + ALLOC_STATE(vap_clip_cntl, always, 2, 0); + r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(R300_VAP_CLIP_CNTL, 1); ALLOC_STATE(unk2220, always, 5, 0); r300->hw.unk2220.cmd[0] = cmdpacket0(0x2220, 4); ALLOC_STATE(unk2288, always, 2, 0); @@ -438,15 +438,24 @@ void r300InitCmdBuf(r300ContextPtr r300) /* VPU only on TCL */ if (has_tcl) { + int i; ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); r300->hw.vpi.cmd[R300_VPI_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PROGRAM, 0); + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); r300->hw.vpp.cmd[R300_VPP_CMD_0] = cmdvpu(R300_PVS_UPLOAD_PARAMETERS, 0); + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); r300->hw.vps.cmd[R300_VPS_CMD_0] = cmdvpu(R300_PVS_UPLOAD_POINTSIZE, 1); + + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); + r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = + cmdvpu(R300_PVS_UPLOAD_CLIP_PLANE0+i, 1); + } } /* Textures */ diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 41498678331..6b0a5887d05 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -421,6 +421,13 @@ struct r300_state_atom { #define R300_VPP_PARAM_0 1 #define R300_VPP_CMDSIZE 1025 /* 256 4-component parameters */ +#define R300_VPUCP_CMD_0 0 +#define R300_VPUCP_X 1 +#define R300_VPUCP_Y 2 +#define R300_VPUCP_Z 3 +#define R300_VPUCP_W 4 +#define R300_VPUCP_CMDSIZE 5 /* 256 4-component parameters */ + #define R300_VPS_CMD_0 0 #define R300_VPS_ZERO_0 1 #define R300_VPS_ZERO_1 2 @@ -454,7 +461,7 @@ struct r300_hw_state { struct r300_state_atom vir[2]; /* vap input route (2150/21E0) */ struct r300_state_atom vic; /* vap input control (2180) */ struct r300_state_atom unk21DC; /* (21DC) */ - struct r300_state_atom unk221C; /* (221C) */ + struct r300_state_atom vap_clip_cntl; struct r300_state_atom unk2220; /* (2220) */ struct r300_state_atom unk2288; /* (2288) */ struct r300_state_atom pvs; /* pvs_cntl (22D0) */ @@ -508,6 +515,7 @@ struct r300_hw_state { struct r300_state_atom vpi; /* vp instructions */ struct r300_state_atom vpp; /* vp parameters */ struct r300_state_atom vps; /* vertex point size (?) */ + struct r300_state_atom vpucp[6]; /* vp user clip plane - 6 */ /* 8 texture units */ /* the state is grouped by function and not by texture unit. This makes single unit updates diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 416ea7f231d..ea94ce252ab 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -266,8 +266,8 @@ static void r300EmitClearState(GLcontext * ctx) e32(0x0); e32(0x0); - R300_STATECHANGE(r300, unk221C); - reg_start(R300_VAP_UNKNOWN_221C, 0); + R300_STATECHANGE(r300, vap_clip_cntl); + reg_start(R300_VAP_CLIP_CNTL, 0); e32(R300_221C_CLEAR); R300_STATECHANGE(r300, ps); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 0a31f0b9785..e5501b65008 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -281,8 +281,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 # define R300_PVS_UPLOAD_PROGRAM 0x00000000 # define R300_PVS_UPLOAD_PARAMETERS 0x00000200 +# define R300_PVS_UPLOAD_CLIP_PLANE0 0x00000400 +# define R300_PVS_UPLOAD_CLIP_PLANE1 0x00000401 +# define R300_PVS_UPLOAD_CLIP_PLANE2 0x00000402 +# define R300_PVS_UPLOAD_CLIP_PLANE3 0x00000403 +# define R300_PVS_UPLOAD_CLIP_PLANE4 0x00000404 +# define R300_PVS_UPLOAD_CLIP_PLANE5 0x00000405 # define R300_PVS_UPLOAD_POINTSIZE 0x00000406 +# define R500_PVS_UPLOAD_CLIP_PLANE0 0x00000600 +# define R500_PVS_UPLOAD_CLIP_PLANE1 0x00000601 +# define R500_PVS_UPLOAD_CLIP_PLANE2 0x00000602 +# define R500_PVS_UPLOAD_CLIP_PLANE3 0x00000603 +# define R500_PVS_UPLOAD_CLIP_PLANE4 0x00000604 +# define R500_PVS_UPLOAD_CLIP_PLANE5 0x00000605 + /* gap */ #define R300_VAP_PVS_UPLOAD_DATA 0x2208 @@ -294,10 +307,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* I do not know the purpose of this register. However, I do know that * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL * for normal rendering. + * + * 2007-11-05: This register is the user clip plane control register, but there + * also seems to be a rendering mode control; the NORMAL/CLEAR defines. + * + * See bug #9871. http://bugs.freedesktop.org/attachment.cgi?id=10672&action=view */ -#define R300_VAP_UNKNOWN_221C 0x221C +#define R300_VAP_CLIP_CNTL 0x221C # define R300_221C_NORMAL 0x00000000 # define R300_221C_CLEAR 0x0001C000 +#define R300_VAP_UCP_ENABLE_0 (1 << 0) /* gap */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e8d67f9aec1..2aaf041d6d1 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -462,6 +462,8 @@ static void r300SetDepthState(GLcontext * ctx) r300SetEarlyZState(ctx); } +static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ); + /** * Handle glEnable()/glDisable(). * @@ -470,7 +472,7 @@ static void r300SetDepthState(GLcontext * ctx) static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); - + GLuint p; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr(cap), @@ -510,6 +512,27 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) r300SetBlendState(ctx); break; + + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + /* no VAP UCP on non-TCL chipsets */ + if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) + return; + + p = cap-GL_CLIP_PLANE0; + R300_STATECHANGE( r300, vap_clip_cntl ); + if (state) { + r300->hw.vap_clip_cntl.cmd[1] |= (R300_VAP_UCP_ENABLE_0<hw.vap_clip_cntl.cmd[1] &= ~(R300_VAP_UCP_ENABLE_0<hw.unk21DC.cmd[1] = 0xAAAAAAAA; - r300->hw.unk221C.cmd[1] = R300_221C_NORMAL; + r300->hw.vap_clip_cntl.cmd[1] = R300_221C_NORMAL; r300->hw.unk2220.cmd[1] = r300PackFloat32(1.0); r300->hw.unk2220.cmd[2] = r300PackFloat32(1.0); @@ -2254,6 +2277,8 @@ void r300InitState(r300ContextPtr r300) depth_fmt = R300_DEPTH_FORMAT_24BIT_INT_Z; r300->state.stencil.clear = 0x00ff0000; break; + + default: fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits); @@ -2276,6 +2301,38 @@ static void r300RenderMode(GLcontext * ctx, GLenum mode) (void)mode; } +static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0; + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + R300_STATECHANGE( rmesa, vpucp[p] ); + rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_Z] = ip[2]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_W] = ip[3]; +} + + +void r300UpdateClipPlanes( GLcontext *ctx ) +{ + r300ContextPtr rmesa = R300_CONTEXT(ctx); + GLuint p; + + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { + GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; + + R300_STATECHANGE( rmesa, vpucp[p] ); + rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_Z] = ip[2]; + rmesa->hw.vpucp[p].cmd[R300_VPUCP_W] = ip[3]; + } + } +} + /** * Initialize driver's state callback functions */ @@ -2313,4 +2370,6 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->PolygonMode = r300PolygonMode; functions->RenderMode = r300RenderMode; + + functions->ClipPlane = r300ClipPlane; } -- cgit v1.2.3