diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/ffvertex_prog.c | 2 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.c | 64 | ||||
-rw-r--r-- | src/mesa/shader/prog_statevars.h | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_rasterizer.c | 29 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_extensions.c | 9 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_mesa_to_tgsi.c | 36 |
6 files changed, 126 insertions, 16 deletions
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 2d1db29cbfe..867a55242c0 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -1496,7 +1496,7 @@ static void build_texture_transform( struct tnl_program *p ) static void build_atten_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position_z(p); - struct ureg state_size = register_param1(p, STATE_POINT_SIZE); + struct ureg state_size = register_param2(p, STATE_INTERNAL, STATE_POINT_SIZE_CLAMPED); struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 20321dd01f6..a0be1acfcab 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -445,6 +445,61 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2); return; + case STATE_POINT_SIZE_CLAMPED: + { + /* this includes implementation dependent limits, to avoid + * another potentially necessary clamp. + * Note: for sprites, point smooth (point AA) is ignored + * and we'll clamp to MinPointSizeAA and MaxPointSize, because we + * expect drivers will want to say their minimum for AA size is 0.0 + * but for non-AA it's 1.0 (because normal points with size below 1.0 + * need to get rounded up to 1.0, hence never disappear). GL does + * not specify max clamp size for sprites, other than it needs to be + * at least as large as max AA size, hence use non-AA size there. + */ + GLfloat minImplSize; + GLfloat maxImplSize; + if (ctx->Point.PointSprite) { + minImplSize = ctx->Const.MinPointSizeAA; + maxImplSize = ctx->Const.MaxPointSize; + } + else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { + minImplSize = ctx->Const.MinPointSizeAA; + maxImplSize = ctx->Const.MaxPointSizeAA; + } + else { + minImplSize = ctx->Const.MinPointSize; + maxImplSize = ctx->Const.MaxPointSize; + } + value[0] = ctx->Point.Size; + value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize; + value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize; + value[3] = ctx->Point.Threshold; + } + return; + case STATE_POINT_SIZE_IMPL_CLAMP: + { + /* for implementation clamp only in vs */ + GLfloat minImplSize; + GLfloat maxImplSize; + if (ctx->Point.PointSprite) { + minImplSize = ctx->Const.MinPointSizeAA; + maxImplSize = ctx->Const.MaxPointSize; + } + else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { + minImplSize = ctx->Const.MinPointSizeAA; + maxImplSize = ctx->Const.MaxPointSizeAA; + } + else { + minImplSize = ctx->Const.MinPointSize; + maxImplSize = ctx->Const.MaxPointSize; + } + value[0] = ctx->Point.Size; + value[1] = minImplSize; + value[2] = maxImplSize; + value[3] = ctx->Point.Threshold; + } + return; case STATE_LIGHT_SPOT_DIR_NORMALIZED: { /* here, state[2] is the light number */ @@ -640,6 +695,9 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) return _NEW_TEXTURE; case STATE_FOG_PARAMS_OPTIMIZED: return _NEW_FOG; + case STATE_POINT_SIZE_CLAMPED: + case STATE_POINT_SIZE_IMPL_CLAMP: + return _NEW_POINT | _NEW_MULTISAMPLE; case STATE_LIGHT_SPOT_DIR_NORMALIZED: case STATE_LIGHT_POSITION: case STATE_LIGHT_POSITION_NORMALIZED: @@ -831,6 +889,12 @@ append_token(char *dst, gl_state_index k) case STATE_FOG_PARAMS_OPTIMIZED: append(dst, "fogParamsOptimized"); break; + case STATE_POINT_SIZE_CLAMPED: + append(dst, "pointSizeClamped"); + break; + case STATE_POINT_SIZE_IMPL_CLAMP: + append(dst, "pointSizeImplClamp"); + break; case STATE_LIGHT_SPOT_DIR_NORMALIZED: append(dst, "lightSpotDirNormalized"); break; diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 1180d9eaa4a..1753471ffb6 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -108,6 +108,8 @@ typedef enum gl_state_index_ { STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ + STATE_POINT_SIZE_CLAMPED, /* includes implementation dependent size clamp */ + STATE_POINT_SIZE_IMPL_CLAMP, /* for implementation clamp only in vs */ STATE_LIGHT_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ STATE_LIGHT_POSITION, /* object vs eye space */ STATE_LIGHT_POSITION_NORMALIZED, /* object vs eye space */ diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 36b28cb4df9..9c9a99bcfc6 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -183,27 +183,26 @@ static void update_raster_state( struct st_context *st ) if (ctx->Polygon.StippleFlag) raster->poly_stipple_enable = 1; - + /* _NEW_POINT */ raster->point_size = ctx->Point.Size; - raster->point_size_min = 0; /* temporary, will go away */ - raster->point_size_max = 1000; /* temporary, will go away */ + if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag) + raster->point_smooth = 1; - raster->point_smooth = ctx->Point.SmoothFlag; - raster->point_sprite = ctx->Point.PointSprite; - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - if (ctx->Point.CoordReplace[i]) { - if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ - (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM)) - raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT; - else - raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT; - } - else { - raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE; + if (ctx->Point.PointSprite) { + if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ + (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM)) + raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; + else + raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT; + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { + if (ctx->Point.CoordReplace[i]) { + raster->sprite_coord_enable |= 1 << i; + } } + raster->point_quad_rasterization = 1; } /* ST_NEW_VERTEX_PROGRAM diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index f2a62f9b690..d5f58546613 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -113,6 +113,15 @@ 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)); + /* called after _mesa_create_context/_mesa_init_point, fix default user + * settable max point size up + */ + st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA); + /* 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 06cf6d21c67..537a6a86482 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -62,6 +62,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; @@ -150,6 +154,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: @@ -816,6 +822,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);*/ @@ -928,6 +936,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 ); @@ -995,6 +1018,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: |