mesa: add misc tessellation shader stuff

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Fabian Bieler 2014-03-07 10:39:39 +01:00 committed by Marek Olšák
parent 6823d713c6
commit 550a570c53
4 changed files with 80 additions and 5 deletions

View File

@ -1331,6 +1331,8 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);
_mesa_reference_tesscprog(ctx, &ctx->TessCtrlProgram._Current, NULL);
_mesa_reference_tesseprog(ctx, &ctx->TessEvalProgram._Current, NULL);
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);

View File

@ -2410,7 +2410,8 @@ struct gl_ati_fragment_shader_state
*/
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;

View File

@ -206,6 +206,9 @@ _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:
case GL_TESS_EVALUATION_SHADER:
return ctx == NULL || _mesa_has_tessellation(ctx);
case GL_COMPUTE_SHADER:
return ctx == NULL || ctx->Extensions.ARB_compute_shader;
default:
@ -422,6 +425,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);
@ -1083,6 +1088,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);
}
@ -2035,6 +2046,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;

View File

@ -79,8 +79,8 @@ 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->*Program._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
@ -97,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 =
@ -106,6 +110,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;
const struct gl_compute_program *prevCP = ctx->ComputeProgram._Current;
GLbitfield new_state = 0x0;
@ -175,6 +181,30 @@ 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.
@ -230,6 +260,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) {
@ -266,8 +312,8 @@ update_program_constants(struct gl_context *ctx)
}
}
/* Don't handle geometry shaders here. They don't use any state
* constants.
/* Don't handle tessellation and geometry shaders here. They don't use
* any state constants.
*/
if (ctx->VertexProgram._Current) {