On 09/20/2014 06:40 PM, Chris Forbes wrote: > From: Fabian Bieler <fabianbie...@fastmail.fm> > > --- > src/mesa/main/context.c | 6 +++++ > src/mesa/main/mtypes.h | 3 ++- > src/mesa/main/shaderapi.c | 29 ++++++++++++++++++++ > src/mesa/main/state.c | 67 > +++++++++++++++++++++++++++++++++++++++++++++-- > 4 files changed, 102 insertions(+), 3 deletions(-) > > diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c > index d9be2f5..d4190b6 100644 > --- a/src/mesa/main/context.c > +++ b/src/mesa/main/context.c > @@ -1904,6 +1904,12 @@ _mesa_valid_to_render(struct gl_context *ctx, const > char *where) > */ > (void) from_glsl_shader[MESA_SHADER_GEOMETRY]; > > + /* FINISHME: If GL_NV_tessellation_program is ever supported, the current > + * FINISHME: tessellation control and evaluation programs should > validated here. > + */ > + (void) from_glsl_shader[GL_TESS_CONTROL_PROGRAM_NV]; > + (void) from_glsl_shader[GL_TESS_EVALUATION_PROGRAM_NV];
I think you mean MESA_. > + > if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) { > if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { > _mesa_error(ctx, GL_INVALID_OPERATION, > diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h > index 9088e97..9bd78e4 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -2566,7 +2566,8 @@ struct gl_sl_pragmas > */ > struct gl_shader > { > - /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB. > + /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || > + * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. > * Must be the first field. > */ > GLenum Type; > diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c > index 8160062..7ef9f74 100644 > --- a/src/mesa/main/shaderapi.c > +++ b/src/mesa/main/shaderapi.c > @@ -206,6 +206,10 @@ _mesa_validate_shader_target(const struct gl_context > *ctx, GLenum type) > return ctx == NULL || ctx->Extensions.ARB_vertex_shader; > case GL_GEOMETRY_SHADER_ARB: > return ctx == NULL || _mesa_has_geometry_shaders(ctx); > + case GL_TESS_CONTROL_SHADER: > + return ctx == NULL || ctx->Extensions.ARB_tessellation_shader; > + case GL_TESS_EVALUATION_SHADER: > + return ctx == NULL || ctx->Extensions.ARB_tessellation_shader; > case GL_COMPUTE_SHADER: > return ctx == NULL || ctx->Extensions.ARB_compute_shader; > default: > @@ -423,6 +427,8 @@ detach_shader(struct gl_context *ctx, GLuint program, > GLuint shader) > /* sanity check - make sure the new list's entries are sensible */ > for (j = 0; j < shProg->NumShaders; j++) { > assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || > + shProg->Shaders[j]->Type == GL_TESS_CONTROL_SHADER || > + shProg->Shaders[j]->Type == GL_TESS_EVALUATION_SHADER || > shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER || > shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); > assert(shProg->Shaders[j]->RefCount > 0); > @@ -1041,6 +1047,12 @@ print_shader_info(const struct gl_shader_program > *shProg) > if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) > printf(" geom prog %u\n", > shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id); > + if (shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) > + printf(" tesc prog %u\n", > + shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program->Id); > + if (shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) > + printf(" tese prog %u\n", > + shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program->Id); > } > > > @@ -1117,6 +1129,8 @@ void > _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) > { > use_shader_program(ctx, GL_VERTEX_SHADER, shProg, &ctx->Shader); > + use_shader_program(ctx, GL_TESS_CONTROL_SHADER, shProg, &ctx->Shader); > + use_shader_program(ctx, GL_TESS_EVALUATION_SHADER, shProg, &ctx->Shader); > use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg, &ctx->Shader); > use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, &ctx->Shader); > use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, &ctx->Shader); > @@ -1959,6 +1973,21 @@ _mesa_copy_linked_program_data(gl_shader_stage type, > case MESA_SHADER_VERTEX: > dst->UsesClipDistanceOut = src->Vert.UsesClipDistance; > break; > + case MESA_SHADER_TESS_CTRL: { > + struct gl_tess_ctrl_program *dst_tcp = > + (struct gl_tess_ctrl_program *) dst; > + dst_tcp->VerticesOut = src->TessCtrl.VerticesOut; > + } > + break; > + case MESA_SHADER_TESS_EVAL: { > + struct gl_tess_eval_program *dst_tep = > + (struct gl_tess_eval_program *) dst; > + dst_tep->PrimitiveMode = src->TessEval.PrimitiveMode; > + dst_tep->Spacing = src->TessEval.Spacing; > + dst_tep->VertexOrder = src->TessEval.VertexOrder; > + dst_tep->PointMode = src->TessEval.PointMode; > + } > + break; > case MESA_SHADER_GEOMETRY: { > struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) > dst; > dst_gp->VerticesIn = src->Geom.VerticesIn; > diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c > index 80287c4..44f9ed9 100644 > --- a/src/mesa/main/state.c > +++ b/src/mesa/main/state.c > @@ -78,8 +78,9 @@ update_program_enables(struct gl_context *ctx) > > > /** > - * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point > - * to the current/active programs. Then call ctx->Driver.BindProgram() to > + * Update the ctx->Vertex/Tessellation Control/Tessellation Evaluation/ > + * Geometry/FragmentProgram._Current pointers to point to the > + * current/active programs. Then call ctx->Driver.BindProgram() to Maybe just say "Update the ctx->*Program._Current pointers...". > * tell the driver which programs to use. > * > * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment > @@ -96,6 +97,10 @@ update_program(struct gl_context *ctx) > { > const struct gl_shader_program *vsProg = > ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; > + const struct gl_shader_program *tcsProg = > + ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; > + const struct gl_shader_program *tesProg = > + ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; > const struct gl_shader_program *gsProg = > ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; > struct gl_shader_program *fsProg = > @@ -103,6 +108,8 @@ update_program(struct gl_context *ctx) > const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; > const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; > const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; > + const struct gl_tess_ctrl_program *prevTCP = > ctx->TessCtrlProgram._Current; > + const struct gl_tess_eval_program *prevTEP = > ctx->TessEvalProgram._Current; > GLbitfield new_state = 0x0; > > /* > @@ -171,6 +178,26 @@ update_program(struct gl_context *ctx) > _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); > } > > + if (tesProg && tesProg->LinkStatus > + && tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) { > + /* Use GLSL tessellation evaluation shader */ > + _mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current, > + > gl_tess_eval_program(tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program)); > + } else { > + /* No tessellation evaluation program */ > + _mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current, NULL); > + } > + > + if (tcsProg && tcsProg->LinkStatus > + && tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) { > + /* Use GLSL tessellation control shader */ > + _mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current, > + > gl_tess_ctrl_program(tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program)); > + } else { > + /* No tessellation control program */ > + _mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current, NULL); > + } > + > /* Examine vertex program after fragment program as > * _mesa_get_fixed_func_vertex_program() needs to know active > * fragprog inputs. > @@ -216,6 +243,22 @@ update_program(struct gl_context *ctx) > } > } > > + if (ctx->TessEvalProgram._Current != prevTEP) { > + new_state |= _NEW_PROGRAM; > + if (ctx->Driver.BindProgram) { > + ctx->Driver.BindProgram(ctx, GL_TESS_EVALUATION_PROGRAM_NV, > + (struct gl_program *) > ctx->TessEvalProgram._Current); > + } > + } > + > + if (ctx->TessCtrlProgram._Current != prevTCP) { > + new_state |= _NEW_PROGRAM; > + if (ctx->Driver.BindProgram) { > + ctx->Driver.BindProgram(ctx, GL_TESS_CONTROL_PROGRAM_NV, > + (struct gl_program *) > ctx->TessCtrlProgram._Current); > + } > + } > + > if (ctx->VertexProgram._Current != prevVP) { > new_state |= _NEW_PROGRAM; > if (ctx->Driver.BindProgram) { > @@ -254,6 +297,26 @@ update_program_constants(struct gl_context *ctx) > } > } > > + if (ctx->TessEvalProgram._Current) { > + const struct gl_program_parameter_list *params = > + ctx->TessEvalProgram._Current->Base.Parameters; > + /*FIXME: StateFlags is always 0 because we have unnamed constant > + * not state changes */ > + if (params /*&& params->StateFlags & ctx->NewState*/) { > + new_state |= _NEW_PROGRAM_CONSTANTS; > + } > + } > + > + if (ctx->TessCtrlProgram._Current) { > + const struct gl_program_parameter_list *params = > + ctx->TessCtrlProgram._Current->Base.Parameters; > + /*FIXME: StateFlags is always 0 because we have unnamed constant > + * not state changes */ > + if (params /*&& params->StateFlags & ctx->NewState*/) { > + new_state |= _NEW_PROGRAM_CONSTANTS; > + } > + } > + > if (ctx->VertexProgram._Current) { > const struct gl_program_parameter_list *params = > ctx->VertexProgram._Current->Base.Parameters; > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev