Hello,
On nv40 hardware, fixed-function glClipPlane must be implemented in a
vertex program.
Attached is a patch which adds support for the clip distance vtxprog
outputs as described in GL_NV_vertex_program{2,3,4}. The patch also
allows the driver to configure whether it wants the fixed-function vp
generator to insert clip planes, and the style of matrix multiplications
it prefers.
If there's no objection I'd like to commit this as it's required for
implementing clip planes in the nv40 gallium driver.
Cheers,
Ben.
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 8fcb9e5..ead8b69 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -47,6 +47,8 @@
struct state_key {
+ unsigned matrix_dp4;
+
unsigned light_global_enabled:1;
unsigned light_local_viewer:1;
unsigned light_twoside:1;
@@ -77,6 +79,8 @@ struct state_key {
unsigned texgen_mode2:4;
unsigned texgen_mode3:4;
} unit[8];
+
+ unsigned clip_planes:6;
};
@@ -167,6 +171,8 @@ static struct state_key *make_state_key( GLcontext *ctx )
*/
assert(fp);
+ key->matrix_dp4 = ctx->VertexProgram._TnlProgramOptions.MatrixDP4;
+
key->fragprog_inputs_read = fp->Base.InputsRead;
if (ctx->RenderMode == GL_FEEDBACK) {
@@ -260,6 +266,13 @@ static struct state_key *make_state_key( GLcontext *ctx )
texUnit->GenModeQ );
}
}
+
+ if (ctx->VertexProgram._TnlProgramOptions.BuildClipPlanes) {
+ for (i = 0; i < MAX_CLIP_PLANES; i++) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << i))
+ key->clip_planes |= (1 << i);
+ }
+ }
return key;
}
@@ -272,12 +285,6 @@ static struct state_key *make_state_key( GLcontext *ctx )
*/
#define DISASSEM (MESA_VERBOSE&VERBOSE_DISASSEM)
-/* Should be tunable by the driver - do we want to do matrix
- * multiplications with DP4's or with MUL/MAD's? SSE works better
- * with the latter, drivers may differ.
- */
-#define PREFER_DP4 0
-
#define MAX_INSN 256
/* Use uregs to represent registers internally, translate to Mesa's
@@ -675,7 +682,7 @@ static struct ureg get_eye_position( struct tnl_program *p )
p->eye_position = reserve_temp(p);
- if (PREFER_DP4) {
+ if (p->state->matrix_dp4) {
register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3,
0, modelview );
@@ -737,15 +744,13 @@ static struct ureg get_eye_normal( struct tnl_program *p )
return p->eye_normal;
}
-
-
static void build_hpos( struct tnl_program *p )
{
struct ureg pos = register_input( p, VERT_ATTRIB_POS );
struct ureg hpos = register_output( p, VERT_RESULT_HPOS );
struct ureg mvp[4];
- if (PREFER_DP4) {
+ if (p->state->matrix_dp4) {
register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3,
0, mvp );
emit_matrix_transform_vec4( p, hpos, mvp, pos );
@@ -757,6 +762,21 @@ static void build_hpos( struct tnl_program *p )
}
}
+static void build_clip_planes( struct tnl_program *p )
+{
+ struct ureg eye = get_eye_position( p );
+ struct ureg user_plane, clip;
+ int i;
+
+ for (i = 0; i < MAX_CLIP_PLANES; i++) {
+ if (!(p->state->clip_planes & (1 << i)))
+ continue;
+
+ register_matrix_param5( p, STATE_CLIPPLANE, i, 0, 0, 0, &user_plane );
+ clip = register_output( p, VERT_RESULT_CLIP0 + i );
+ emit_op2( p, OPCODE_DP4, clip, WRITEMASK_X, eye, user_plane );
+ }
+}
static GLuint material_attrib( GLuint side, GLuint property )
{
@@ -1358,7 +1378,7 @@ static void build_texture_transform( struct tnl_program *p )
struct ureg in = (!is_undef(out_texgen) ?
out_texgen :
register_input(p, VERT_ATTRIB_TEX0+i));
- if (PREFER_DP4) {
+ if (p->state->matrix_dp4) {
register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3,
0, texmat );
emit_matrix_transform_vec4( p, out, texmat, in );
@@ -1427,6 +1447,10 @@ static void build_tnl_program( struct tnl_program *p )
*/
build_hpos(p);
+ /* User clipping planes */
+ if (p->state->clip_planes)
+ build_clip_planes(p);
+
/* Lighting calculations:
*/
if (p->state->fragprog_inputs_read & (FRAG_BIT_COL0|FRAG_BIT_COL1)) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 8e49431..6538ec2 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -243,7 +243,13 @@ enum
#define VERT_RESULT_BFC0 13
#define VERT_RESULT_BFC1 14
#define VERT_RESULT_EDGE 15
-#define VERT_RESULT_VAR0 16 /**< shader varying */
+#define VERT_RESULT_CLIP0 16
+#define VERT_RESULT_CLIP1 17
+#define VERT_RESULT_CLIP2 18
+#define VERT_RESULT_CLIP3 19
+#define VERT_RESULT_CLIP4 20
+#define VERT_RESULT_CLIP5 21
+#define VERT_RESULT_VAR0 22 /**< shader varying */
#define VERT_RESULT_MAX (VERT_RESULT_VAR0 + MAX_VARYING)
/[EMAIL PROTECTED]/
@@ -1987,6 +1993,12 @@ struct gl_vertex_program_state
/** Program to emulate fixed-function T&L (see above) */
struct gl_vertex_program *_TnlProgram;
+ /** Driver control over generated fixed-function T&L programs */
+ struct {
+ GLboolean MatrixDP4;
+ GLboolean BuildClipPlanes;
+ } _TnlProgramOptions;
+
/** Cache of fixed-function programs */
struct gl_program_cache *Cache;
diff --git a/src/mesa/pipe/p_defines.h b/src/mesa/pipe/p_defines.h
index d3afef9..e52ed63 100644
--- a/src/mesa/pipe/p_defines.h
+++ b/src/mesa/pipe/p_defines.h
@@ -261,6 +261,8 @@
#define PIPE_CAP_MAX_POINT_WIDTH_AA 17
#define PIPE_CAP_MAX_TEXTURE_ANISOTROPY 18
#define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19
+#define PIPE_CAP_FFVP_MATRIX_DP4 20
+#define PIPE_CAP_FFVP_CLIP_PLANES 21
#endif
diff --git a/src/mesa/pipe/p_shader_tokens.h b/src/mesa/pipe/p_shader_tokens.h
index e5922b4..cb36edd 100644
--- a/src/mesa/pipe/p_shader_tokens.h
+++ b/src/mesa/pipe/p_shader_tokens.h
@@ -109,7 +109,8 @@ struct tgsi_declaration_interpolation
#define TGSI_SEMANTIC_FOG 3
#define TGSI_SEMANTIC_PSIZE 4
#define TGSI_SEMANTIC_GENERIC 5
-#define TGSI_SEMANTIC_COUNT 6 /**< number of semantic values */
+#define TGSI_SEMANTIC_CLIP 6
+#define TGSI_SEMANTIC_COUNT 7 /**< number of semantic values */
struct tgsi_declaration_semantic
{
diff --git a/src/mesa/pipe/tgsi/util/tgsi_dump.c b/src/mesa/pipe/tgsi/util/tgsi_dump.c
index 3f4d930..1893876 100644
--- a/src/mesa/pipe/tgsi/util/tgsi_dump.c
+++ b/src/mesa/pipe/tgsi/util/tgsi_dump.c
@@ -297,6 +297,7 @@ static const char *TGSI_SEMANTICS[] =
"SEMANTIC_FOG",
"SEMANTIC_PSIZE",
"SEMANTIC_GENERIC,"
+ "SEMANTIC_CLIP,"
};
static const char *TGSI_SEMANTICS_SHORT[] =
@@ -307,6 +308,7 @@ static const char *TGSI_SEMANTICS_SHORT[] =
"FOG",
"PSIZE",
"GENERIC",
+ "CLIP",
};
static const char *TGSI_IMMS[] =
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 4ec10ba..fc8c3ec 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -223,6 +223,15 @@ find_translated_vp(struct st_context *st,
}
}
+ /* Clip distance regs don't have a corresponding fragprog input,
+ * assign these an output slot here.
+ */
+ for (outAttr = VERT_RESULT_CLIP0; outAttr < VERT_RESULT_CLIP5; outAttr++) {
+ if (outputsWritten & (1 << outAttr)) {
+ xvp->output_to_slot[outAttr] = stfp->num_input_slots++;
+ }
+ }
+
/* Unneeded vertex program outputs will go to this slot.
* We could use this info to do dead code elimination in the
* vertex program.
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 524e06f..7538efd 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -49,6 +49,7 @@
#include "st_extensions.h"
#include "st_program.h"
#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
#include "pipe/draw/draw_context.h"
#include "pipe/cso_cache/cso_cache.h"
@@ -102,6 +103,10 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st->ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE;
st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
+ if (pipe->get_param(pipe, PIPE_CAP_FFVP_MATRIX_DP4))
+ st->ctx->VertexProgram._TnlProgramOptions.MatrixDP4 = GL_TRUE;
+ if (pipe->get_param(pipe, PIPE_CAP_FFVP_CLIP_PLANES))
+ st->ctx->VertexProgram._TnlProgramOptions.BuildClipPlanes = GL_TRUE;
st->haveFramebufferSurfaces = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index e64bf14..e5f922d 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -47,7 +47,7 @@
#include "st_mesa_to_tgsi.h"
-#define TGSI_DEBUG 0
+#define TGSI_DEBUG 1
/**
@@ -208,6 +208,15 @@ st_translate_vertex_program(struct st_context *st,
vs.output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
vs.output_semantic_index[slot] = attr - VERT_RESULT_TEX0;
break;
+ case VERT_RESULT_CLIP0:
+ case VERT_RESULT_CLIP1:
+ case VERT_RESULT_CLIP2:
+ case VERT_RESULT_CLIP3:
+ case VERT_RESULT_CLIP4:
+ case VERT_RESULT_CLIP5:
+ vs.output_semantic_name[slot] = TGSI_SEMANTIC_CLIP;
+ vs.output_semantic_index[slot] = attr - VERT_RESULT_CLIP0;
+ break;
case VERT_RESULT_VAR0:
/* fall-through */
default:
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev