summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2010-02-04 19:23:09 +0100
committerRoland Scheidegger <sroland@vmware.com>2010-02-04 19:23:09 +0100
commit2c326e72664e65166c68b027b26aaf373f3be36d (patch)
tree936c473da596c90f7a649f25da93dc7a07d7157b /src/mesa/state_tracker
parent8091e73cc2142945c297191a9b746be71360ef26 (diff)
gallium: add point size clamp to implementation limits in vertex shader
The point size min/max registers (unused by mesa state tracker) were removed since most hardware couldn't do much with them. However, we don't want to have to rely on hw to do point size clamping correctly to implementation dependent limits, hence have to do that in the vertex shader. This should also solve a potential problem with (non-AA) points smaller than 1.0 which according to OGL still have size 1.0. Note that OGL point rendering is odd, in particular point sprites are rasterized differently to points. Some hardware might support those different modes, but in any case the different clamping values used for smooth/multisampled/sprite enabled points might help a bit for hw which rasterizes points the same as point sprites. Also tweak mesa's ff to vertex shader translation so don't have to clamp twice in case of point attenuation.
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_extensions.c5
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c36
2 files changed, 41 insertions, 0 deletions
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 35e08749df..7684ccd702 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -114,6 +114,11 @@ void st_init_limits(struct st_context *st)
= _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH));
c->MaxPointSizeAA
= _maxf(1.0f, screen->get_paramf(screen, PIPE_CAP_MAX_POINT_WIDTH_AA));
+ /* these are not queryable. Note that GL basically mandates a 1.0 minimum
+ * for non-aa sizes, but we can go down to 0.0 for aa points.
+ */
+ c->MinPointSize = 1.0f;
+ c->MinPointSizeAA = 0.0f;
c->MaxTextureMaxAnisotropy
= _maxf(2.0f, screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_ANISOTROPY));
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index e788008dfe..4830a8f383 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -57,6 +57,10 @@ struct st_translate {
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
struct ureg_dst address[1];
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
+ struct ureg_dst psizregreal;
+ struct ureg_src pointSizeConst;
+ GLint psizoutindex;
+ GLboolean prevInstWrotePsiz;
const GLuint *inputMapping;
const GLuint *outputMapping;
@@ -145,6 +149,8 @@ dst_register( struct st_translate *t,
return t->temps[index];
case PROGRAM_OUTPUT:
+ if (index == t->psizoutindex)
+ t->prevInstWrotePsiz = GL_TRUE;
return t->outputs[t->outputMapping[index]];
case PROGRAM_ADDRESS:
@@ -787,6 +793,8 @@ st_translate_mesa_program(
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
t->ureg = ureg;
+ t->psizoutindex = -1;
+ t->prevInstWrotePsiz = GL_FALSE;
/*_mesa_print_program(program);*/
@@ -845,6 +853,21 @@ st_translate_mesa_program(
t->outputs[i] = ureg_DECL_output( ureg,
outputSemanticName[i],
outputSemanticIndex[i] );
+ if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE) && program->Id) {
+ static const gl_state_index pointSizeClampState[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_POINT_SIZE_IMPL_CLAMP, 0, 0, 0 };
+ /* XXX: note we are modifying the incoming shader here! Need to
+ * do this before emitting the constant decls below, or this
+ * will be missed:
+ */
+ unsigned pointSizeClampConst = _mesa_add_state_reference(program->Parameters,
+ pointSizeClampState);
+ struct ureg_dst psizregtemp = ureg_DECL_temporary( ureg );
+ t->pointSizeConst = ureg_DECL_constant( ureg, pointSizeClampConst );
+ t->psizregreal = t->outputs[i];
+ t->psizoutindex = i;
+ t->outputs[i] = psizregtemp;
+ }
}
if (passthrough_edgeflags)
emit_edgeflags( t, program );
@@ -910,6 +933,19 @@ st_translate_mesa_program(
for (i = 0; i < program->NumInstructions; i++) {
set_insn_start( t, ureg_get_instruction_number( ureg ));
compile_instruction( t, &program->Instructions[i] );
+
+ /* note can't do that easily at the end of prog due to
+ possible early return */
+ if (t->prevInstWrotePsiz && program->Id) {
+ set_insn_start( t, ureg_get_instruction_number( ureg ));
+ ureg_MAX( t->ureg, ureg_writemask(t->outputs[t->psizoutindex], WRITEMASK_X),
+ ureg_src(t->outputs[t->psizoutindex]),
+ ureg_swizzle(t->pointSizeConst, 1,1,1,1));
+ ureg_MIN( t->ureg, ureg_writemask(t->psizregreal, WRITEMASK_X),
+ ureg_src(t->outputs[t->psizoutindex]),
+ ureg_swizzle(t->pointSizeConst, 2,2,2,2));
+ }
+ t->prevInstWrotePsiz = GL_FALSE;
}
/* Fix up all emitted labels: