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]; + 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 * 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; -- 2.1.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev