From ba9fb96f86344f1631b82114bb0ce6f926d3853a Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 11 Jul 2014 22:11:21 -0400 Subject: st/mesa: add tessellation shader states additional fixes by Marek --- src/mesa/state_tracker/st_program.c | 192 ++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) (limited to 'src/mesa/state_tracker/st_program.c') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index fa792bc349b..99257949ba3 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -163,6 +163,68 @@ st_release_gp_variants(struct st_context *st, struct st_geometry_program *stgp) } +/** + * Delete a tessellation control program variant. Note the caller must unlink + * the variant from the linked list. + */ +static void +delete_tcp_variant(struct st_context *st, struct st_tcp_variant *tcpv) +{ + if (tcpv->driver_shader) + cso_delete_tessctrl_shader(st->cso_context, tcpv->driver_shader); + + free(tcpv); +} + + +/** + * Free all variants of a tessellation control program. + */ +void +st_release_tcp_variants(struct st_context *st, struct st_tessctrl_program *sttcp) +{ + struct st_tcp_variant *tcpv; + + for (tcpv = sttcp->variants; tcpv; ) { + struct st_tcp_variant *next = tcpv->next; + delete_tcp_variant(st, tcpv); + tcpv = next; + } + + sttcp->variants = NULL; +} + + +/** + * Delete a tessellation evaluation program variant. Note the caller must + * unlink the variant from the linked list. + */ +static void +delete_tep_variant(struct st_context *st, struct st_tep_variant *tepv) +{ + if (tepv->driver_shader) + cso_delete_tesseval_shader(st->cso_context, tepv->driver_shader); + + free(tepv); +} + + +/** + * Free all variants of a tessellation evaluation program. + */ +void +st_release_tep_variants(struct st_context *st, struct st_tesseval_program *sttep) +{ + struct st_tep_variant *tepv; + + for (tepv = sttep->variants; tepv; ) { + struct st_tep_variant *next = tepv->next; + delete_tep_variant(st, tepv); + tepv = next; + } + + sttep->variants = NULL; +} /** @@ -1167,6 +1229,92 @@ st_get_gp_variant(struct st_context *st, } +/** + * Translate a tessellation control program to create a new variant. + */ +static struct st_tcp_variant * +st_translate_tessctrl_program(struct st_context *st, + struct st_tessctrl_program *sttcp, + const struct st_tcp_variant_key *key) +{ + return NULL; /* will be updated in the next commit */ +} + + +/** + * Get/create tessellation control program variant. + */ +struct st_tcp_variant * +st_get_tcp_variant(struct st_context *st, + struct st_tessctrl_program *sttcp, + const struct st_tcp_variant_key *key) +{ + struct st_tcp_variant *tcpv; + + /* Search for existing variant */ + for (tcpv = sttcp->variants; tcpv; tcpv = tcpv->next) { + if (memcmp(&tcpv->key, key, sizeof(*key)) == 0) { + break; + } + } + + if (!tcpv) { + /* create new */ + tcpv = st_translate_tessctrl_program(st, sttcp, key); + if (tcpv) { + /* insert into list */ + tcpv->next = sttcp->variants; + sttcp->variants = tcpv; + } + } + + return tcpv; +} + + +/** + * Translate a tessellation evaluation program to create a new variant. + */ +static struct st_tep_variant * +st_translate_tesseval_program(struct st_context *st, + struct st_tesseval_program *sttep, + const struct st_tep_variant_key *key) +{ + return NULL; /* will be updated in the next commit */ +} + + +/** + * Get/create tessellation evaluation program variant. + */ +struct st_tep_variant * +st_get_tep_variant(struct st_context *st, + struct st_tesseval_program *sttep, + const struct st_tep_variant_key *key) +{ + struct st_tep_variant *tepv; + + /* Search for existing variant */ + for (tepv = sttep->variants; tepv; tepv = tepv->next) { + if (memcmp(&tepv->key, key, sizeof(*key)) == 0) { + break; + } + } + + if (!tepv) { + /* create new */ + tepv = st_translate_tesseval_program(st, sttep, key); + if (tepv) { + /* insert into list */ + tepv->next = sttep->variants; + sttep->variants = tepv; + } + } + + return tepv; +} + + /** * Vert/Geom/Frag programs have per-context variants. Free all the * variants attached to the given program which match the given context. @@ -1240,6 +1388,48 @@ destroy_program_variants(struct st_context *st, struct gl_program *program) } } break; + case GL_TESS_CONTROL_PROGRAM_NV: + { + struct st_tessctrl_program *sttcp = + (struct st_tessctrl_program *) program; + struct st_tcp_variant *tcpv, **prevPtr = &sttcp->variants; + + for (tcpv = sttcp->variants; tcpv; ) { + struct st_tcp_variant *next = tcpv->next; + if (tcpv->key.st == st) { + /* unlink from list */ + *prevPtr = next; + /* destroy this variant */ + delete_tcp_variant(st, tcpv); + } + else { + prevPtr = &tcpv->next; + } + tcpv = next; + } + } + break; + case GL_TESS_EVALUATION_PROGRAM_NV: + { + struct st_tesseval_program *sttep = + (struct st_tesseval_program *) program; + struct st_tep_variant *tepv, **prevPtr = &sttep->variants; + + for (tepv = sttep->variants; tepv; ) { + struct st_tep_variant *next = tepv->next; + if (tepv->key.st == st) { + /* unlink from list */ + *prevPtr = next; + /* destroy this variant */ + delete_tep_variant(st, tepv); + } + else { + prevPtr = &tepv->next; + } + tepv = next; + } + } + break; default: _mesa_problem(NULL, "Unexpected program target 0x%x in " "destroy_program_variants_cb()", program->Target); @@ -1276,6 +1466,8 @@ destroy_shader_program_variants_cb(GLuint key, void *data, void *userData) case GL_VERTEX_SHADER: case GL_FRAGMENT_SHADER: case GL_GEOMETRY_SHADER: + case GL_TESS_CONTROL_SHADER: + case GL_TESS_EVALUATION_SHADER: { destroy_program_variants(st, shader->Program); } -- cgit v1.2.3