st_program.c revision 44867da3543ca54ef245695cef72a6e305451d93
1f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian/**************************************************************************
2f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian *
3f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * All Rights Reserved.
5f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian *
6f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * Permission is hereby granted, free of charge, to any person obtaining a
7f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * copy of this software and associated documentation files (the
8f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * "Software"), to deal in the Software without restriction, including
9f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * without limitation the rights to use, copy, modify, merge, publish,
10f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * distribute, sub license, and/or sell copies of the Software, and to
11f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * permit persons to whom the Software is furnished to do so, subject to
12f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * the following conditions:
13f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian *
14f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * The above copyright notice and this permission notice (including the
15f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * next paragraph) shall be included in all copies or substantial portions
16f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * of the Software.
17f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian *
18f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian *
26f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian **************************************************************************/
27f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian /*
28f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian  * Authors:
29f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian  *   Keith Whitwell <keith@tungstengraphics.com>
30f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian  *   Brian Paul
31f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian  */
32f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
33f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
34b5051bf6bbe54269c78f4dd545791e51bc7ce9e0Brian#include "main/imports.h"
353d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#include "main/hash.h"
36edc09358f72cd48cb2315daf23c82e7646aeaea3Vinson Lee#include "main/mfeatures.h"
37b5051bf6bbe54269c78f4dd545791e51bc7ce9e0Brian#include "main/mtypes.h"
383d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#include "program/prog_parameter.h"
39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h"
40ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/programopt.h"
41f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
42f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian#include "pipe/p_context.h"
43f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian#include "pipe/p_defines.h"
44abd5e8e41d54f7f491f91af9354f19c8d24d3572Michal Krol#include "pipe/p_shader_tokens.h"
456acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "draw/draw_context.h"
46c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_dump.h"
471b8aa2176c4fc580cc31c57c7e50e7f39ef2cc04Vinson Lee#include "tgsi/tgsi_ureg.h"
48f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
49b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell#include "st_debug.h"
503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#include "st_cb_bitmap.h"
513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#include "st_cb_drawpixels.h"
52f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian#include "st_context.h"
53f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian#include "st_program.h"
54ef6940f17220f1149dce6daf548bd0103d91a281Brian#include "st_mesa_to_tgsi.h"
55339e7ec6805e6de8794514c0a935081b5d36d38fBrian#include "cso_cache/cso_context.h"
56f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
578468234bfa98be77cbceecc8e91325c00e4e424bBrian Paul
588468234bfa98be77cbceecc8e91325c00e4e424bBrian Paul
598468234bfa98be77cbceecc8e91325c00e4e424bBrian Paul/**
60aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Delete a vertex program variant.  Note the caller must unlink
61aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * the variant from the linked list.
623d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
633d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
64aa5ba96d294698809186cc4b59034abbd3076812Brian Pauldelete_vp_variant(struct st_context *st, struct st_vp_variant *vpv)
653d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
663d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (vpv->driver_shader)
673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#if FEATURE_feedback || FEATURE_rastpos
703d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (vpv->draw_shader)
713d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      draw_delete_vertex_shader( st->draw, vpv->draw_shader );
723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#endif
733d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
743d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (vpv->tgsi.tokens)
753d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      st_free_tokens(vpv->tgsi.tokens);
763d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
773d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   FREE( vpv );
783d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
793d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
803d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
838468234bfa98be77cbceecc8e91325c00e4e424bBrian Paul * Clean out any old compilations:
848468234bfa98be77cbceecc8e91325c00e4e424bBrian Paul */
8507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwellvoid
86aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_release_vp_variants( struct st_context *st,
8707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                        struct st_vertex_program *stvp )
8807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell{
89aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_vp_variant *vpv;
9007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
91aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (vpv = stvp->variants; vpv; ) {
92aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      struct st_vp_variant *next = vpv->next;
93aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      delete_vp_variant(st, vpv);
943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      vpv = next;
953d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
9607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
97aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   stvp->variants = NULL;
983d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
993d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1003d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1023d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
103aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Delete a fragment program variant.  Note the caller must unlink
104aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * the variant from the linked list.
1053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
1063d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
107aa5ba96d294698809186cc4b59034abbd3076812Brian Pauldelete_fp_variant(struct st_context *st, struct st_fp_variant *fpv)
1083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
1093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (fpv->driver_shader)
1103d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      cso_delete_fragment_shader(st->cso_context, fpv->driver_shader);
11180424700574e128070f457d79e1920d512a1efdaThomas Hellstrom   if (fpv->parameters)
11280424700574e128070f457d79e1920d512a1efdaThomas Hellstrom      _mesa_free_parameter_list(fpv->parameters);
11307fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
1143d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   FREE(fpv);
1153d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
1163d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1173d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1183d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
119aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Free all variants of a fragment program.
1203d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
1213d203b610045980853d26370ee21fb2ef4aed17eBrian Paulvoid
122aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_release_fp_variants(struct st_context *st, struct st_fragment_program *stfp)
1233d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
124aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_fp_variant *fpv;
1253d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
126aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (fpv = stfp->variants; fpv; ) {
127aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      struct st_fp_variant *next = fpv->next;
128aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      delete_fp_variant(st, fpv);
1293d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      fpv = next;
1303d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
1313d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
132aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   stfp->variants = NULL;
1333d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
1343d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1353d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1363d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
137aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Delete a geometry program variant.  Note the caller must unlink
138aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * the variant from the linked list.
1393d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
1403d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
141aa5ba96d294698809186cc4b59034abbd3076812Brian Pauldelete_gp_variant(struct st_context *st, struct st_gp_variant *gpv)
1423d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
1433d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (gpv->driver_shader)
1443d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      cso_delete_geometry_shader(st->cso_context, gpv->driver_shader);
14507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
1463d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   FREE(gpv);
1473d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
14807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
1493d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
151aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Free all variants of a geometry program.
1523d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
1533d203b610045980853d26370ee21fb2ef4aed17eBrian Paulvoid
154aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_release_gp_variants(struct st_context *st, struct st_geometry_program *stgp)
1553d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
156aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_gp_variant *gpv;
1573d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
158aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (gpv = stgp->variants; gpv; ) {
159aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      struct st_gp_variant *next = gpv->next;
160aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      delete_gp_variant(st, gpv);
1613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      gpv = next;
16207fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   }
16307fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
164aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   stgp->variants = NULL;
16507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell}
16607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
16707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
16807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
169f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
170f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian/**
171f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * Translate a Mesa vertex shader into a TGSI shader.
172e3f3e22cf7e9af4c5416d37329b7b8ee50f0cfcbBrian Paul * \param outputMapping  to map vertex program output registers (VERT_RESULT_x)
173e3f3e22cf7e9af4c5416d37329b7b8ee50f0cfcbBrian Paul *       to TGSI output slots
174f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * \param tokensOut  destination for TGSI tokens
175f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian * \return  pointer to cached pipe_shader object.
176f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian */
177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid
178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_prepare_vertex_program(struct gl_context *ctx,
17907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                            struct st_vertex_program *stvp)
180f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian{
18107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   GLuint attr;
182c5b52b5e0e6f6e47c3953076fa788921b1c5a5e2Brian Paul
18307fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   stvp->num_inputs = 0;
18407fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   stvp->num_outputs = 0;
185f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
186f3a62372bf155d14876f98b1a085841607bb344cBen Skeggs   if (stvp->Base.IsPositionInvariant)
187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      _mesa_insert_mvp_code(ctx, &stvp->Base);
188f3a62372bf155d14876f98b1a085841607bb344cBen Skeggs
18944867da3543ca54ef245695cef72a6e305451d93Bryan Cain   if (!stvp->glsl_to_tgsi)
19044867da3543ca54ef245695cef72a6e305451d93Bryan Cain      assert(stvp->Base.Base.NumInstructions > 1);
191325f045c04121b989bddfca02711e3d03f7f9c3fKeith Whitwell
192f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   /*
193f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian    * Determine number of inputs, the mappings between VERT_ATTRIB_x
194f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian    * and TGSI generic input indexes, plus input attrib semantic info.
195f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian    */
196f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
197f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian      if (stvp->Base.Base.InputsRead & (1 << attr)) {
19807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         stvp->input_to_index[attr] = stvp->num_inputs;
19907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         stvp->index_to_input[stvp->num_inputs] = attr;
20007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         stvp->num_inputs++;
201f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian      }
202f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   }
20350caff5675888c0063c73fa64b88129db7aa11ddRoland Scheidegger   /* bit of a hack, presetup potentially unused edgeflag input */
20450caff5675888c0063c73fa64b88129db7aa11ddRoland Scheidegger   stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs;
20550caff5675888c0063c73fa64b88129db7aa11ddRoland Scheidegger   stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG;
206f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
20707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   /* Compute mapping of vertex program outputs to slots.
208f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian    */
209f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
210b46750d601655c39ccb967ae525d4edcbb9fb9d2Ben Skeggs      if ((stvp->Base.Base.OutputsWritten & BITFIELD64_BIT(attr)) == 0) {
21107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         stvp->result_to_output[attr] = ~0;
21207fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell      }
21307fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell      else {
21407fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         unsigned slot = stvp->num_outputs++;
21507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
21607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell         stvp->result_to_output[attr] = slot;
217f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
218f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         switch (attr) {
219f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_HPOS:
22007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
22107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 0;
222f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
223f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_COL0:
22407fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
22507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 0;
226f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
227f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_COL1:
22807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
22907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 1;
230f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
231f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_BFC0:
23207fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
23307fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 0;
234f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
235f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_BFC1:
23607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
23707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 1;
238f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
239f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_FOGC:
24007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
24107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 0;
242f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
243f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_PSIZ:
24407fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
24507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = 0;
246f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
247f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_EDGE:
248f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            assert(0);
249f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian            break;
25007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
251f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX0:
252f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX1:
253f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX2:
254f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX3:
255f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX4:
256f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX5:
257f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX6:
258f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_TEX7:
25907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
26007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0;
26107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            break;
26207fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
263f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         case VERT_RESULT_VAR0:
264f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         default:
26507fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            assert(attr < VERT_RESULT_MAX);
26607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
26707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 -
26807fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                                                FRAG_ATTRIB_TEX0 +
26907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                                                attr -
27007fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                                                VERT_RESULT_VAR0);
27107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell            break;
272f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian         }
273f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian      }
274f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   }
275890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   /* similar hack to above, presetup potentially unused edgeflag output */
276890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs;
277890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG;
278890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   stvp->output_semantic_index[stvp->num_outputs] = 0;
27907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell}
280f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
281509d9eb686411254b24139012b7594e10a760b6cBrian Paul
2823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
283aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Translate a vertex program to create a new variant.
2843d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
285aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstatic struct st_vp_variant *
28607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwellst_translate_vertex_program(struct st_context *st,
28707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell                            struct st_vertex_program *stvp,
288aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                            const struct st_vp_variant_key *key)
28907fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell{
290aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_vp_variant *vpv = CALLOC_STRUCT(st_vp_variant);
29107fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   struct pipe_context *pipe = st->pipe;
292a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell   struct ureg_program *ureg;
293a0127b6ced257919180ba3a1bf534b68d9c750beRoland Scheidegger   enum pipe_error error;
294890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   unsigned num_outputs;
295a35c1ca3ad4361fee30d21ef13d8d37ae91aee66Brian
296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   st_prepare_vertex_program(st->ctx, stvp);
2973d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
29844867da3543ca54ef245695cef72a6e305451d93Bryan Cain   if (!stvp->glsl_to_tgsi)
29944867da3543ca54ef245695cef72a6e305451d93Bryan Cain   {
30044867da3543ca54ef245695cef72a6e305451d93Bryan Cain      _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
30144867da3543ca54ef245695cef72a6e305451d93Bryan Cain      _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING);
30244867da3543ca54ef245695cef72a6e305451d93Bryan Cain   }
30383baa8a6c5541829003bbffe1d2b8cee5a0263fdMarek Olšák
304a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell   ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
305b7eed19efec0cdaca42cabbc6f9fadcb892aee81Vinson Lee   if (ureg == NULL) {
306b7eed19efec0cdaca42cabbc6f9fadcb892aee81Vinson Lee      FREE(vpv);
307a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell      return NULL;
308b7eed19efec0cdaca42cabbc6f9fadcb892aee81Vinson Lee   }
309a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell
310c0c929cdac75a9a0077d74c87b525b65f0a3b6c8Marek Olšák   vpv->key = *key;
311c0c929cdac75a9a0077d74c87b525b65f0a3b6c8Marek Olšák
31250caff5675888c0063c73fa64b88129db7aa11ddRoland Scheidegger   vpv->num_inputs = stvp->num_inputs;
313890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   num_outputs = stvp->num_outputs;
314890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   if (key->passthrough_edgeflags) {
315890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger      vpv->num_inputs++;
316890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger      num_outputs++;
317890809d71b6ab40c56d341a5dad9f5e6b06469d0Roland Scheidegger   }
318a35c1ca3ad4361fee30d21ef13d8d37ae91aee66Brian
319ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul   if (ST_DEBUG & DEBUG_MESA) {
320ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul      _mesa_print_program(&stvp->Base.Base);
321ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul      _mesa_print_program_parameters(st->ctx, &stvp->Base.Base);
322ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul      debug_printf("\n");
323ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul   }
324ce0844b44cb3924323ed1fd2b75cda4dbd0013c7Brian Paul
325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   if (stvp->glsl_to_tgsi)
326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      error = st_translate_program(st->ctx,
327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   TGSI_PROCESSOR_VERTEX,
328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   ureg,
329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->glsl_to_tgsi,
330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   &stvp->Base.Base,
331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   /* inputs */
332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->num_inputs,
333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->input_to_index,
334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   NULL, /* input semantic name */
335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   NULL, /* input semantic index */
336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   NULL, /* interp mode */
337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   /* outputs */
338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->num_outputs,
339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->result_to_output,
340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->output_semantic_name,
341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   stvp->output_semantic_index,
342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                   key->passthrough_edgeflags );
343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   else
344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      error = st_translate_mesa_program(st->ctx,
345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        TGSI_PROCESSOR_VERTEX,
346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        ureg,
347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        &stvp->Base.Base,
348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        /* inputs */
349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        vpv->num_inputs,
350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        stvp->input_to_index,
351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        NULL, /* input semantic name */
352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        NULL, /* input semantic index */
353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        NULL,
354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        /* outputs */
355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        num_outputs,
356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        stvp->result_to_output,
357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        stvp->output_semantic_name,
358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        stvp->output_semantic_index,
359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                        key->passthrough_edgeflags );
36025b17b213b7ba0d1b93ec37211504ee489944ce8Zack Rusin
361a0127b6ced257919180ba3a1bf534b68d9c750beRoland Scheidegger   if (error)
362a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell      goto fail;
363a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell
364b9b4e7724e5ae80121a053ca66cee73942cc16b7Brian Paul   vpv->tgsi.tokens = ureg_get_tokens( ureg, NULL );
365b9b4e7724e5ae80121a053ca66cee73942cc16b7Brian Paul   if (!vpv->tgsi.tokens)
3669d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger      goto fail;
3679d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger
368a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell   ureg_destroy( ureg );
36925b17b213b7ba0d1b93ec37211504ee489944ce8Zack Rusin
370b9b4e7724e5ae80121a053ca66cee73942cc16b7Brian Paul   vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi);
371f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
372b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell   if (ST_DEBUG & DEBUG_TGSI) {
373b9b4e7724e5ae80121a053ca66cee73942cc16b7Brian Paul      tgsi_dump( vpv->tgsi.tokens, 0 );
374b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell      debug_printf("\n");
375b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell   }
37607fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell
37707fafc7c9346aa260829603bf3188596481e9e62Keith Whitwell   return vpv;
378a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell
379a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwellfail:
3809d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger   debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
3819d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger   _mesa_print_program(&stvp->Base.Base);
3829d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger   debug_assert(0);
3839d938e29f202552a98605906b71f31485af1ef60Roland Scheidegger
384a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell   ureg_destroy( ureg );
385a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell   return NULL;
386f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian}
387f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
388f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
3893d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
390aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Find/create a vertex program variant.
3913d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
392aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstruct st_vp_variant *
393aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_get_vp_variant(struct st_context *st,
3943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                  struct st_vertex_program *stvp,
395aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                  const struct st_vp_variant_key *key)
3963d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
397aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_vp_variant *vpv;
3983d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
399aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   /* Search for existing variant */
400aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (vpv = stvp->variants; vpv; vpv = vpv->next) {
4013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (memcmp(&vpv->key, key, sizeof(*key)) == 0) {
4023d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         break;
4033d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
4043d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
4053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
4063d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!vpv) {
4073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* create now */
4083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      vpv = st_translate_vertex_program(st, stvp, key);
4093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (vpv) {
4103d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         /* insert into list */
411aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         vpv->next = stvp->variants;
412aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         stvp->variants = vpv;
4133d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
4143d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
4153d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
4163d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   return vpv;
4173d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
4183d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/**
420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Translate Mesa fragment shader attributes to TGSI attributes.
421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \return GL_TRUE if color output should be written to all render targets,
422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain *         GL_FALSE if not
423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */
424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean
425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_prepare_fragment_program(struct gl_context *ctx,
426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                            struct st_fragment_program *stfp)
427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{
428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   GLuint attr;
429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   GLboolean write_all = GL_FALSE;
431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   /*
433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain    * Convert Mesa program inputs to TGSI input register semantics.
434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain    */
435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      if (inputsRead & (1 << attr)) {
437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         const GLuint slot = stfp->num_inputs++;
438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->input_to_index[attr] = slot;
440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         switch (attr) {
442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_WPOS:
443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = 0;
445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->interp_mode[slot] = TGSI_INTERPOLATE_LINEAR;
446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_COL0:
448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = 0;
450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->interp_mode[slot] = TGSI_INTERPOLATE_LINEAR;
451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_COL1:
453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = 1;
455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->interp_mode[slot] = TGSI_INTERPOLATE_LINEAR;
456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_FOGC:
458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = 0;
460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->interp_mode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_FACE:
463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = 0;
465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->interp_mode[slot] = TGSI_INTERPOLATE_CONSTANT;
466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            /* In most cases, there is nothing special about these
468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * inputs, so adopt a convention to use the generic
469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * semantic name and the mesa FRAG_ATTRIB_ number as the
470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * index.
471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             *
472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * All that is required is that the vertex shader labels
473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * its own outputs similarly, and that the vertex shader
474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * generates at least every output required by the
475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * fragment shader plus fixed-function hardware (such as
476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * BFC).
477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             *
478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * There is no requirement that semantic indexes start at
479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * zero or be restricted to a particular range -- nobody
480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * should be building tables based on semantic index.
481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             */
482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_PNTC:
483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX0:
484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX1:
485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX2:
486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX3:
487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX4:
488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX5:
489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX6:
490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_TEX7:
491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         case FRAG_ATTRIB_VAR0:
492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         default:
493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            /* Actually, let's try and zero-base this just for
494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             * readability of the generated TGSI.
495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain             */
496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            assert(attr >= FRAG_ATTRIB_TEX0);
497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            if (attr == FRAG_ATTRIB_PNTC)
500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               stfp->interp_mode[slot] = TGSI_INTERPOLATE_LINEAR;
501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            else
502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               stfp->interp_mode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            break;
504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         }
505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      }
506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      else {
507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->input_to_index[attr] = -1;
508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      }
509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   }
510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   /*
512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain    * Semantics and mapping for outputs
513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain    */
514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   {
515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      uint numColors = 0;
516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      /* if z is written, emit that first */
519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->output_semantic_name[stfp->num_outputs] = TGSI_SEMANTIC_POSITION;
521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->output_semantic_index[stfp->num_outputs] = 0;
522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->result_to_output[FRAG_RESULT_DEPTH] = stfp->num_outputs;
523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->num_outputs++;
524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      }
526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->output_semantic_name[stfp->num_outputs] = TGSI_SEMANTIC_STENCIL;
529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->output_semantic_index[stfp->num_outputs] = 0;
530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->result_to_output[FRAG_RESULT_STENCIL] = stfp->num_outputs;
531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         stfp->num_outputs++;
532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         outputsWritten &= ~(1 << FRAG_RESULT_STENCIL);
533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      }
534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      /* handle remaning outputs (color) */
536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         if (outputsWritten & BITFIELD64_BIT(attr)) {
538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            switch (attr) {
539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            case FRAG_RESULT_DEPTH:
540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            case FRAG_RESULT_STENCIL:
541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               /* handled above */
542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               assert(0);
543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               break;
544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            case FRAG_RESULT_COLOR:
545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               write_all = GL_TRUE; /* fallthrough */
546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            default:
547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               assert(attr == FRAG_RESULT_COLOR ||
548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                      (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               stfp->output_semantic_name[stfp->num_outputs] = TGSI_SEMANTIC_COLOR;
550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               stfp->output_semantic_index[stfp->num_outputs] = numColors;
551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               stfp->result_to_output[attr] = stfp->num_outputs;
552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               numColors++;
553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain               break;
554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            }
555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain            stfp->num_outputs++;
557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         }
558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      }
559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   }
560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain   return write_all;
562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}
563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
564f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
565f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian/**
5663d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Translate a Mesa fragment shader into a TGSI shader using extra info in
5673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * the key.
5683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * \return  new fragment program variant
569f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian */
570aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstatic struct st_fp_variant *
571f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrianst_translate_fragment_program(struct st_context *st,
5723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                              struct st_fragment_program *stfp,
573aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                              const struct st_fp_variant_key *key)
574f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian{
575339e7ec6805e6de8794514c0a935081b5d36d38fBrian   struct pipe_context *pipe = st->pipe;
576aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
5777230e1a22822ce91f2d2555da53404f195fa9aafBrian Paul   GLboolean deleteFP = GL_FALSE;
578f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
579aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   if (!variant)
5803d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      return NULL;
581fa9e7e9a8debb68611909ac2ffab527c6c39a3e5Brian Paul
5823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   assert(!(key->bitmap && key->drawpixels));
583fa9e7e9a8debb68611909ac2ffab527c6c39a3e5Brian Paul
584c94996f0570c729b9cb2b55329ababb9877fbbeaBrian Paul#if FEATURE_drawpix
5853d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (key->bitmap) {
5863d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* glBitmap drawing */
5875cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul      struct gl_fragment_program *fp; /* we free this temp program below */
58883baa8a6c5541829003bbffe1d2b8cee5a0263fdMarek Olšák
5893d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      st_make_bitmap_fragment_program(st, &stfp->Base,
590aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                                      &fp, &variant->bitmap_sampler);
591f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
592aa5ba96d294698809186cc4b59034abbd3076812Brian Paul      variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
59343125694109b01b9d99ed73ca340fcf19b831cd5Brian Paul      stfp = st_fragment_program(fp);
5947230e1a22822ce91f2d2555da53404f195fa9aafBrian Paul      deleteFP = GL_TRUE;
5953d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
5963d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   else if (key->drawpixels) {
5973d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* glDrawPixels drawing */
5985cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul      struct gl_fragment_program *fp; /* we free this temp program below */
599e785f190f0d49f0367f7468c22b77962d0f14ea0Brian
6003d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (key->drawpixels_z || key->drawpixels_stencil) {
6013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         fp = st_make_drawpix_z_stencil_program(st, key->drawpixels_z,
6023d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                                key->drawpixels_stencil);
603f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian      }
604e1906ae98ef4d8f153553056552c06ac4292d1f5Keith Whitwell      else {
6053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         /* RGBA */
6063d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
607aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
6087230e1a22822ce91f2d2555da53404f195fa9aafBrian Paul         deleteFP = GL_TRUE;
609e1906ae98ef4d8f153553056552c06ac4292d1f5Keith Whitwell      }
61043125694109b01b9d99ed73ca340fcf19b831cd5Brian Paul      stfp = st_fragment_program(fp);
611f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian   }
612c94996f0570c729b9cb2b55329ababb9877fbbeaBrian Paul#endif
613f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
6143d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!stfp->tgsi.tokens) {
6153d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* need to translate Mesa instructions to TGSI now */
6163d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      enum pipe_error error;
6173d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      struct ureg_program *ureg;
618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      GLboolean write_all = st_prepare_fragment_program(st->ctx, stfp);
619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain
62044867da3543ca54ef245695cef72a6e305451d93Bryan Cain      if (!stfp->glsl_to_tgsi)
62144867da3543ca54ef245695cef72a6e305451d93Bryan Cain         _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
6223d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
6233d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
6243d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (ureg == NULL)
6253d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         return NULL;
626a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell
6273d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (ST_DEBUG & DEBUG_MESA) {
6283d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         _mesa_print_program(&stfp->Base.Base);
6293d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
6303d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         debug_printf("\n");
6313d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
63207498075b5de14955958da44a90eb7ee203218a1Dave Airlie      if (write_all == GL_TRUE)
63307498075b5de14955958da44a90eb7ee203218a1Dave Airlie         ureg_property_fs_color0_writes_all_cbufs(ureg, 1);
634a08e348a84f57ed5e8bf5888f1ce13934d2ce8faKeith Whitwell
635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      if (stfp->glsl_to_tgsi)
636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         error = st_translate_program(st->ctx,
637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      TGSI_PROCESSOR_FRAGMENT,
638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      ureg,
639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->glsl_to_tgsi,
640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      &stfp->Base.Base,
641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      /* inputs */
642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->num_inputs,
643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->input_to_index,
644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->input_semantic_name,
645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->input_semantic_index,
646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->interp_mode,
647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      /* outputs */
648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->num_outputs,
649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->result_to_output,
650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->output_semantic_name,
651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                      stfp->output_semantic_index, FALSE );
652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain      else
653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain         error = st_translate_mesa_program(st->ctx,
654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           TGSI_PROCESSOR_FRAGMENT,
655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           ureg,
656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           &stfp->Base.Base,
657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           /* inputs */
658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->num_inputs,
659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->input_to_index,
660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->input_semantic_name,
661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->input_semantic_index,
662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->interp_mode,
663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           /* outputs */
664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->num_outputs,
665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->result_to_output,
666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->output_semantic_name,
667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain                                           stfp->output_semantic_index, FALSE );
6683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
6693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
6703d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      ureg_destroy( ureg );
6713d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
6724295b34d25f40f38b8cfd3ebdc64aef29d0666dbKeith Whitwell
673aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   /* fill in variant */
674aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   variant->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
675aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   variant->key = *key;
676f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
677b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell   if (ST_DEBUG & DEBUG_TGSI) {
678b9b4e7724e5ae80121a053ca66cee73942cc16b7Brian Paul      tgsi_dump( stfp->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
679b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell      debug_printf("\n");
680b02ef740b90029bc40629e5b81270a8cf77101d3Keith Whitwell   }
6813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
6827230e1a22822ce91f2d2555da53404f195fa9aafBrian Paul   if (deleteFP) {
6835cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul      /* Free the temporary program made above */
6845cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul      struct gl_fragment_program *fp = &stfp->Base;
6855cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul      _mesa_reference_fragprog(st->ctx, &fp, NULL);
6865cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul   }
6875cbff0932e498f49b57cbb71037b93416bfe30e0Brian Paul
688aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   return variant;
689f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian}
690f9ed2fdaace0d4d7f091a4423a8638945e920b0dBrian
6913d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
6923d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
6933d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Translate fragment program if needed.
6943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
695aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstruct st_fp_variant *
696aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_get_fp_variant(struct st_context *st,
6973d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                  struct st_fragment_program *stfp,
698aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                  const struct st_fp_variant_key *key)
6993d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
700aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_fp_variant *fpv;
7013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
702aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   /* Search for existing variant */
703aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (fpv = stfp->variants; fpv; fpv = fpv->next) {
7043d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (memcmp(&fpv->key, key, sizeof(*key)) == 0) {
7053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         break;
7063d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
7073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
7083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
7093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!fpv) {
7103d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* create new */
7113d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      fpv = st_translate_fragment_program(st, stfp, key);
7123d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (fpv) {
7133d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         /* insert into list */
714aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         fpv->next = stfp->variants;
715aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         stfp->variants = fpv;
7163d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
7173d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
7183d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
7193d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   return fpv;
7203d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
7213d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
7223d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
7233d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
724aa5ba96d294698809186cc4b59034abbd3076812Brian Paul * Translate a geometry program to create a new variant.
7253d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
726aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstatic struct st_gp_variant *
727da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusinst_translate_geometry_program(struct st_context *st,
7283d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                              struct st_geometry_program *stgp,
729aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                              const struct st_gp_variant_key *key)
730da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin{
731da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint inputMapping[GEOM_ATTRIB_MAX];
732da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint outputMapping[GEOM_RESULT_MAX];
733da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   struct pipe_context *pipe = st->pipe;
734da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   enum pipe_error error;
735da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint attr;
736da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   const GLbitfield inputsRead = stgp->Base.Base.InputsRead;
737da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint vslot = 0;
738da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint num_generic = 0;
739da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
740da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   uint gs_num_inputs = 0;
741da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   uint gs_builtin_inputs = 0;
742da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   uint gs_array_offset = 0;
743da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
744da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
745da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
746da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   uint gs_num_outputs = 0;
747da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
748da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLint i;
749da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   GLuint maxSlot = 0;
750da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   struct ureg_program *ureg;
751da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
752aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_gp_variant *gpv;
7533d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
754aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   gpv = CALLOC_STRUCT(st_gp_variant);
7553d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!gpv)
7563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      return NULL;
7573d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
75883baa8a6c5541829003bbffe1d2b8cee5a0263fdMarek Olšák   _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
75983baa8a6c5541829003bbffe1d2b8cee5a0263fdMarek Olšák   _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_VARYING);
76083baa8a6c5541829003bbffe1d2b8cee5a0263fdMarek Olšák
761da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
762da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   if (ureg == NULL) {
7633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      FREE(gpv);
7643d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      return NULL;
765da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
766da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
767da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /* which vertex output goes to the first geometry input */
7687c42390453e611367cf1ba11446692ec04e0abfbZack Rusin   vslot = 0;
769da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
770425870c5fdb40f7daf2e25323fa28c90c4367baeZack Rusin   memset(inputMapping, 0, sizeof(inputMapping));
771425870c5fdb40f7daf2e25323fa28c90c4367baeZack Rusin   memset(outputMapping, 0, sizeof(outputMapping));
772425870c5fdb40f7daf2e25323fa28c90c4367baeZack Rusin
773da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /*
774da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin    * Convert Mesa program inputs to TGSI input register semantics.
775da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin    */
776da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   for (attr = 0; attr < GEOM_ATTRIB_MAX; attr++) {
777da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      if (inputsRead & (1 << attr)) {
778da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         const GLuint slot = gs_num_inputs;
779da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
780da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         gs_num_inputs++;
781da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
782da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         inputMapping[attr] = slot;
783da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
784da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         stgp->input_map[slot + gs_array_offset] = vslot - gs_builtin_inputs;
785da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         stgp->input_to_index[attr] = vslot;
786da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         stgp->index_to_input[vslot] = attr;
787da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         ++vslot;
788da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
7897c42390453e611367cf1ba11446692ec04e0abfbZack Rusin         if (attr != GEOM_ATTRIB_PRIMITIVE_ID) {
790da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_array_offset += 2;
791da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         } else
792da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            ++gs_builtin_inputs;
793da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
7943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul#if 0
795da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         debug_printf("input map at %d = %d\n",
796da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin                      slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
797da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin#endif
798da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
799da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         switch (attr) {
800da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_PRIMITIVE_ID:
801da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
802da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = 0;
803da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
804da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_POSITION:
805da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
806da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = 0;
807da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
808da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_COLOR0:
809da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
810da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = 0;
811da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
812da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_COLOR1:
813da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
814da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = 1;
815da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
816da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_FOG_FRAG_COORD:
817da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
818da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = 0;
819da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
820da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_TEX_COORD:
821da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
822da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = num_generic++;
823da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
824da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_ATTRIB_VAR0:
825da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            /* fall-through */
826da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         default:
827da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
828da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            stgp->input_semantic_index[slot] = num_generic++;
829da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         }
830da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      }
831da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
832da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
833da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /* initialize output semantics to defaults */
834da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
835da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
836da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      gs_output_semantic_index[i] = 0;
837da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
838da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
839da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   num_generic = 0;
840da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /*
841da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin    * Determine number of outputs, the (default) output register
842da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin    * mapping and the semantic information for each output.
843da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin    */
844da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
845aa878f94ab77fe3be352d820aaa950b32836c814Brian Paul      if (stgp->Base.Base.OutputsWritten & BITFIELD64_BIT(attr)) {
846da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         GLuint slot;
847da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
848da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         slot = gs_num_outputs;
849da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         gs_num_outputs++;
850da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         outputMapping[attr] = slot;
851da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
852da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         switch (attr) {
853da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_POS:
854da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            assert(slot == 0);
855da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
856da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 0;
857da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
858da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_COL0:
859da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
860da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 0;
861da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
862da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_COL1:
863da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
864da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 1;
865da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
866da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_SCOL0:
867da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
868da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 0;
869da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
870da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_SCOL1:
871da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
872da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 1;
873da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
874da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_FOGC:
875da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
876da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 0;
877da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
878da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_PSIZ:
879da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
880da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = 0;
881da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            break;
882da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX0:
883da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX1:
884da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX2:
885da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX3:
886da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX4:
887da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX5:
888da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX6:
889da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_TEX7:
890da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            /* fall-through */
891da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         case GEOM_RESULT_VAR0:
892da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            /* fall-through */
893da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         default:
894da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            assert(slot < Elements(gs_output_semantic_name));
895da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            /* use default semantic info */
896da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
897da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            gs_output_semantic_index[slot] = num_generic++;
898da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         }
899da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      }
900da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
901da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
902da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
903da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
904da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /* find max output slot referenced to compute gs_num_outputs */
905da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
906da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
907da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         maxSlot = outputMapping[attr];
908da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
909da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   gs_num_outputs = maxSlot + 1;
910da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
911da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin#if 0 /* debug */
912da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   {
913da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      GLuint i;
914da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      printf("outputMapping? %d\n", outputMapping ? 1 : 0);
915da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      if (outputMapping) {
916da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         printf("attr -> slot\n");
917da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         for (i = 0; i < 16;  i++) {
918da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin            printf(" %2d       %3d\n", i, outputMapping[i]);
919da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         }
920da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      }
921da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      printf("slot    sem_name  sem_index\n");
922da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      for (i = 0; i < gs_num_outputs; i++) {
923da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin         printf(" %2d         %d         %d\n",
924da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin                i,
925da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin                gs_output_semantic_name[i],
926da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin                gs_output_semantic_index[i]);
927da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      }
928da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
929da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin#endif
930da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
931da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   /* free old shader state, if any */
932da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   if (stgp->tgsi.tokens) {
933da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      st_free_tokens(stgp->tgsi.tokens);
934da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      stgp->tgsi.tokens = NULL;
935da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
936da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
937da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
938da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
939da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
940da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
9413d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   error = st_translate_mesa_program(st->ctx,
9423d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     TGSI_PROCESSOR_GEOMETRY,
9433d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     ureg,
9443d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     &stgp->Base.Base,
9453d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     /* inputs */
9463d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     gs_num_inputs,
9473d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     inputMapping,
9483d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     stgp->input_semantic_name,
9493d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     stgp->input_semantic_index,
9503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     NULL,
9513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     /* outputs */
9523d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     gs_num_outputs,
9533d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     outputMapping,
9543d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     gs_output_semantic_name,
9553d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     gs_output_semantic_index,
9563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                     FALSE);
957da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
958da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   stgp->num_inputs = gs_num_inputs;
959da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
960da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   ureg_destroy( ureg );
9613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
962aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   /* fill in new variant */
9633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
9643d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   gpv->key = *key;
965da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
966da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
967da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      _mesa_print_program(&stgp->Base.Base);
968da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      debug_printf("\n");
969da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
970da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin
971da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   if (ST_DEBUG & DEBUG_TGSI) {
972da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      tgsi_dump(stgp->tgsi.tokens, 0);
973da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin      debug_printf("\n");
974da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin   }
9753d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
9763d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   return gpv;
9773d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
9783d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
9793d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
9803d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
9813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Get/create geometry program variant.
9823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
983aa5ba96d294698809186cc4b59034abbd3076812Brian Paulstruct st_gp_variant *
984aa5ba96d294698809186cc4b59034abbd3076812Brian Paulst_get_gp_variant(struct st_context *st,
9853d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                  struct st_geometry_program *stgp,
986aa5ba96d294698809186cc4b59034abbd3076812Brian Paul                  const struct st_gp_variant_key *key)
9873d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
988aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   struct st_gp_variant *gpv;
9893d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
990aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   /* Search for existing variant */
991aa5ba96d294698809186cc4b59034abbd3076812Brian Paul   for (gpv = stgp->variants; gpv; gpv = gpv->next) {
9923d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (memcmp(&gpv->key, key, sizeof(*key)) == 0) {
9933d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         break;
9943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
9953d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
9963d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
9973d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!gpv) {
9983d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      /* create new */
9993d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      gpv = st_translate_geometry_program(st, stgp, key);
10003d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      if (gpv) {
10013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         /* insert into list */
1002aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         gpv->next = stgp->variants;
1003aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         stgp->variants = gpv;
10043d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
10053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
10063d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   return gpv;
1008da7bd6a90e1fee5c16327338fd251c0f6be34e36Zack Rusin}
1009678f80b347801d925c07a774faee1ed3f716de15Brian Paul
10103d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10113d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10123d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1013678f80b347801d925c07a774faee1ed3f716de15Brian Paul/**
1014678f80b347801d925c07a774faee1ed3f716de15Brian Paul * Debug- print current shader text
1015678f80b347801d925c07a774faee1ed3f716de15Brian Paul */
1016678f80b347801d925c07a774faee1ed3f716de15Brian Paulvoid
1017f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergst_print_shaders(struct gl_context *ctx)
1018678f80b347801d925c07a774faee1ed3f716de15Brian Paul{
101984eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick   struct gl_shader_program *shProg[3] = {
102084eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      ctx->Shader.CurrentVertexProgram,
102184eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      ctx->Shader.CurrentGeometryProgram,
102284eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      ctx->Shader.CurrentFragmentProgram,
102384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick   };
102484eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick   unsigned j;
102584eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick
102684eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick   for (j = 0; j < 3; j++) {
102784eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      unsigned i;
102884eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick
102984eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      if (shProg[j] == NULL)
103084eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 continue;
103184eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick
103284eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick      for (i = 0; i < shProg[j]->NumShaders; i++) {
103384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 struct gl_shader *sh;
103484eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick
103584eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 switch (shProg[j]->Shaders[i]->Type) {
103684eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 case GL_VERTEX_SHADER:
103784eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    sh = (i != 0) ? NULL : shProg[j]->Shaders[i];
103884eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    break;
103984eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 case GL_GEOMETRY_SHADER_ARB:
104084eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    sh = (i != 1) ? NULL : shProg[j]->Shaders[i];
104184eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    break;
104284eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 case GL_FRAGMENT_SHADER:
104384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    sh = (i != 2) ? NULL : shProg[j]->Shaders[i];
104484eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    break;
1045a54ab4960b86839f73e7c16fdde00670a67ee80eVinson Lee	 default:
1046a54ab4960b86839f73e7c16fdde00670a67ee80eVinson Lee	    assert(0);
1047a54ab4960b86839f73e7c16fdde00670a67ee80eVinson Lee	    sh = NULL;
1048a54ab4960b86839f73e7c16fdde00670a67ee80eVinson Lee	    break;
104984eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 }
105084eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick
105184eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 if (sh != NULL) {
105284eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    printf("GLSL shader %u of %u:\n", i, shProg[j]->NumShaders);
105384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	    printf("%s\n", sh->Source);
105484eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick	 }
1055678f80b347801d925c07a774faee1ed3f716de15Brian Paul      }
1056678f80b347801d925c07a774faee1ed3f716de15Brian Paul   }
1057678f80b347801d925c07a774faee1ed3f716de15Brian Paul}
10583d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10593d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10603d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
10613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Vert/Geom/Frag programs have per-context variants.  Free all the
10623d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * variants attached to the given program which match the given context.
10633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
10643d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
10653d203b610045980853d26370ee21fb2ef4aed17eBrian Pauldestroy_program_variants(struct st_context *st, struct gl_program *program)
10663d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
10673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   if (!program)
10683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      return;
10693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
10703d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   switch (program->Target) {
10713d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_VERTEX_PROGRAM_ARB:
10723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      {
10733d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         struct st_vertex_program *stvp = (struct st_vertex_program *) program;
1074aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         struct st_vp_variant *vpv, **prevPtr = &stvp->variants;
10753d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1076aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         for (vpv = stvp->variants; vpv; ) {
1077aa5ba96d294698809186cc4b59034abbd3076812Brian Paul            struct st_vp_variant *next = vpv->next;
10783d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            if (vpv->key.st == st) {
10793d203b610045980853d26370ee21fb2ef4aed17eBrian Paul               /* unlink from list */
1080a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               *prevPtr = next;
10813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul               /* destroy this variant */
1082aa5ba96d294698809186cc4b59034abbd3076812Brian Paul               delete_vp_variant(st, vpv);
10833d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            }
10843d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            else {
1085a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               prevPtr = &vpv->next;
10863d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            }
10873d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            vpv = next;
10883d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         }
10893d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
10903d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      break;
10913d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_FRAGMENT_PROGRAM_ARB:
10923d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      {
10933d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         struct st_fragment_program *stfp =
10943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            (struct st_fragment_program *) program;
1095aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         struct st_fp_variant *fpv, **prevPtr = &stfp->variants;
10963d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
1097aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         for (fpv = stfp->variants; fpv; ) {
1098aa5ba96d294698809186cc4b59034abbd3076812Brian Paul            struct st_fp_variant *next = fpv->next;
10993d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            if (fpv->key.st == st) {
11003d203b610045980853d26370ee21fb2ef4aed17eBrian Paul               /* unlink from list */
1101a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               *prevPtr = next;
11023d203b610045980853d26370ee21fb2ef4aed17eBrian Paul               /* destroy this variant */
1103aa5ba96d294698809186cc4b59034abbd3076812Brian Paul               delete_fp_variant(st, fpv);
11043d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            }
11053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            else {
1106a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               prevPtr = &fpv->next;
11073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            }
11083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            fpv = next;
11093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         }
11103d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
11113d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      break;
1112c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul   case MESA_GEOMETRY_PROGRAM:
1113c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul      {
1114c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul         struct st_geometry_program *stgp =
1115c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            (struct st_geometry_program *) program;
1116aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         struct st_gp_variant *gpv, **prevPtr = &stgp->variants;
1117c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul
1118aa5ba96d294698809186cc4b59034abbd3076812Brian Paul         for (gpv = stgp->variants; gpv; ) {
1119aa5ba96d294698809186cc4b59034abbd3076812Brian Paul            struct st_gp_variant *next = gpv->next;
1120c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            if (gpv->key.st == st) {
1121c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul               /* unlink from list */
1122a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               *prevPtr = next;
1123c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul               /* destroy this variant */
1124aa5ba96d294698809186cc4b59034abbd3076812Brian Paul               delete_gp_variant(st, gpv);
1125c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            }
1126c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            else {
1127a8ca30bc58b73203a83799149ca9d21bcdce74b5Brian Paul               prevPtr = &gpv->next;
1128c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            }
1129c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul            gpv = next;
1130c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul         }
1131c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul      }
1132c21807d2f7329a363f2c68cd8ef4dfc46575d52fBrian Paul      break;
11333d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   default:
1134e37e196151bd8c10a8475680ed91a82de8f7aad3Brian Paul      _mesa_problem(NULL, "Unexpected program target 0x%x in "
1135e37e196151bd8c10a8475680ed91a82de8f7aad3Brian Paul                    "destroy_program_variants_cb()", program->Target);
11363d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
11373d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
11383d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11393d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11403d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
11413d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Callback for _mesa_HashWalk.  Free all the shader's program variants
11423d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * which match the given context.
11433d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
11443d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
11453d203b610045980853d26370ee21fb2ef4aed17eBrian Pauldestroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
11463d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
11473d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   struct st_context *st = (struct st_context *) userData;
11483d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   struct gl_shader *shader = (struct gl_shader *) data;
11493d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11503d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   switch (shader->Type) {
11513d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_SHADER_PROGRAM_MESA:
11523d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      {
11533d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         struct gl_shader_program *shProg = (struct gl_shader_program *) data;
11543d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         GLuint i;
11553d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11563d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         for (i = 0; i < shProg->NumShaders; i++) {
11573d203b610045980853d26370ee21fb2ef4aed17eBrian Paul            destroy_program_variants(st, shProg->Shaders[i]->Program);
11583d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         }
11593d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11603d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         destroy_program_variants(st, (struct gl_program *)
11613d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                  shProg->VertexProgram);
11623d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         destroy_program_variants(st, (struct gl_program *)
11633d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                  shProg->FragmentProgram);
11643d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         destroy_program_variants(st, (struct gl_program *)
11653d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                                  shProg->GeometryProgram);
11663d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
11673d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      break;
11683d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_VERTEX_SHADER:
11693d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_FRAGMENT_SHADER:
11703d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   case GL_GEOMETRY_SHADER:
11713d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      {
11723d203b610045980853d26370ee21fb2ef4aed17eBrian Paul         destroy_program_variants(st, shader->Program);
11733d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      }
11743d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      break;
11753d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   default:
11763d203b610045980853d26370ee21fb2ef4aed17eBrian Paul      assert(0);
11773d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   }
11783d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
11793d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11803d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11813d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
11823d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Callback for _mesa_HashWalk.  Free all the program variants which match
11833d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * the given context.
11843d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
11853d203b610045980853d26370ee21fb2ef4aed17eBrian Paulstatic void
11863d203b610045980853d26370ee21fb2ef4aed17eBrian Pauldestroy_program_variants_cb(GLuint key, void *data, void *userData)
11873d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
11883d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   struct st_context *st = (struct st_context *) userData;
11893d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   struct gl_program *program = (struct gl_program *) data;
11903d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   destroy_program_variants(st, program);
11913d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
11923d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11933d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
11943d203b610045980853d26370ee21fb2ef4aed17eBrian Paul/**
11953d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * Walk over all shaders and programs to delete any variants which
11963d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * belong to the given context.
11973d203b610045980853d26370ee21fb2ef4aed17eBrian Paul * This is called during context tear-down.
11983d203b610045980853d26370ee21fb2ef4aed17eBrian Paul */
11993d203b610045980853d26370ee21fb2ef4aed17eBrian Paulvoid
12003d203b610045980853d26370ee21fb2ef4aed17eBrian Paulst_destroy_program_variants(struct st_context *st)
12013d203b610045980853d26370ee21fb2ef4aed17eBrian Paul{
12023d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   /* ARB vert/frag program */
12033d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   _mesa_HashWalk(st->ctx->Shared->Programs,
12043d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                  destroy_program_variants_cb, st);
12053d203b610045980853d26370ee21fb2ef4aed17eBrian Paul
12063d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   /* GLSL vert/frag/geom shaders */
12073d203b610045980853d26370ee21fb2ef4aed17eBrian Paul   _mesa_HashWalk(st->ctx->Shared->ShaderObjects,
12083d203b610045980853d26370ee21fb2ef4aed17eBrian Paul                  destroy_shader_program_variants_cb, st);
12093d203b610045980853d26370ee21fb2ef4aed17eBrian Paul}
1210