[Mesa-dev] [RFC PATCH 15/56] mesa/main: Add misc tessellation shader stuff.

Ian Romanick idr at freedesktop.org
Tue Sep 30 09:19:51 PDT 2014


On 09/20/2014 06:40 PM, Chris Forbes wrote:
> From: Fabian Bieler <fabianbieler at 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;
> 



More information about the mesa-dev mailing list