00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00040 #include "main/imports.h"
00041 #include "main/mtypes.h"
00042 #include "main/macros.h"
00043 #include "shader/program.h"
00044
00045 #include "pipe/p_context.h"
00046 #include "pipe/p_shader_tokens.h"
00047
00048 #include "util/u_simple_shaders.h"
00049
00050 #include "cso_cache/cso_context.h"
00051
00052 #include "st_context.h"
00053 #include "st_atom.h"
00054 #include "st_program.h"
00055 #include "st_atom_shader.h"
00056 #include "st_mesa_to_tgsi.h"
00057
00058
00063 struct translated_vertex_program
00064 {
00065 struct st_vertex_program *master;
00066
00068 GLbitfield frag_inputs;
00069
00071 GLuint serialNo;
00072
00074 GLuint output_to_slot[VERT_RESULT_MAX];
00075 ubyte output_to_semantic_name[VERT_RESULT_MAX];
00076 ubyte output_to_semantic_index[VERT_RESULT_MAX];
00077
00079 struct st_vertex_program *vp;
00080
00081 struct translated_vertex_program *next;
00082 };
00083
00084
00085
00091 static GLint
00092 vp_out_to_fp_in(GLuint vertResult)
00093 {
00094 if (vertResult >= VERT_RESULT_TEX0 &&
00095 vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
00096 return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0);
00097
00098 if (vertResult >= VERT_RESULT_VAR0 &&
00099 vertResult < VERT_RESULT_VAR0 + MAX_VARYING)
00100 return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0);
00101
00102 switch (vertResult) {
00103 case VERT_RESULT_HPOS:
00104 return FRAG_ATTRIB_WPOS;
00105 case VERT_RESULT_COL0:
00106 return FRAG_ATTRIB_COL0;
00107 case VERT_RESULT_COL1:
00108 return FRAG_ATTRIB_COL1;
00109 case VERT_RESULT_FOGC:
00110 return FRAG_ATTRIB_FOGC;
00111 default:
00112
00113 return -1;
00114 }
00115 }
00116
00117
00123 static struct translated_vertex_program *
00124 find_translated_vp(struct st_context *st,
00125 struct st_vertex_program *stvp,
00126 struct st_fragment_program *stfp)
00127 {
00128 static const GLuint UNUSED = ~0;
00129 struct translated_vertex_program *xvp;
00130 const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
00131
00132
00133
00134
00135 if (!stfp->state.tokens) {
00136 GLuint inAttr, numIn = 0;
00137
00138 for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) {
00139 if (fragInputsRead & (1 << inAttr)) {
00140 stfp->input_to_slot[inAttr] = numIn;
00141 numIn++;
00142 }
00143 else {
00144 stfp->input_to_slot[inAttr] = UNUSED;
00145 }
00146 }
00147
00148 stfp->num_input_slots = numIn;
00149
00150 assert(stfp->Base.Base.NumInstructions > 1);
00151
00152 st_translate_fragment_program(st, stfp, stfp->input_to_slot);
00153 }
00154
00155
00156
00157
00158
00159
00160 for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) {
00161 if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
00162 break;
00163 }
00164 }
00165
00166
00167 if (!xvp) {
00168 xvp = CALLOC_STRUCT(translated_vertex_program);
00169 xvp->frag_inputs = fragInputsRead;
00170 xvp->master = stvp;
00171
00172 xvp->next = stfp->vertex_programs;
00173 stfp->vertex_programs = xvp;
00174 }
00175
00176
00177 if (xvp->serialNo != stvp->serialNo) {
00178 GLuint outAttr, dummySlot;
00179 const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
00180 GLuint numVpOuts = 0;
00181 GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
00182 GLint maxGeneric;
00183
00184
00185
00186
00187 for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
00188
00189 xvp->output_to_slot[outAttr] = UNUSED;
00190 xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
00191 xvp->output_to_semantic_index[outAttr] = 99;
00192
00193 if (outAttr == VERT_RESULT_HPOS) {
00194
00195 xvp->output_to_slot[VERT_RESULT_HPOS] = 0;
00196 xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
00197 xvp->output_to_semantic_index[outAttr] = 0;
00198 numVpOuts++;
00199 }
00200 else if (outputsWritten & (1 << outAttr)) {
00201
00202 GLint fpInAttrib = vp_out_to_fp_in(outAttr);
00203 if (fpInAttrib >= 0) {
00204 GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
00205 if (fpInSlot != ~0) {
00206
00207 GLuint vpOutSlot = stfp->input_map[fpInSlot];
00208 xvp->output_to_slot[outAttr] = vpOutSlot;
00209 xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
00210 xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
00211 numVpOuts++;
00212 }
00213 }
00214 else if (outAttr == VERT_RESULT_PSIZ)
00215 emitPntSize = GL_TRUE;
00216 else if (outAttr == VERT_RESULT_BFC0)
00217 emitBFC0 = GL_TRUE;
00218 else if (outAttr == VERT_RESULT_BFC1)
00219 emitBFC1 = GL_TRUE;
00220 }
00221 #if 0
00222 printf("assign vp output_to_slot[%d] = %d\n", outAttr,
00223 xvp->output_to_slot[outAttr]);
00224 #endif
00225 }
00226
00227
00228 if (emitPntSize) {
00229 xvp->output_to_slot[VERT_RESULT_PSIZ] = numVpOuts++;
00230 xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
00231 xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
00232 }
00233 if (emitBFC0) {
00234 xvp->output_to_slot[VERT_RESULT_BFC0] = numVpOuts++;
00235 xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
00236 xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
00237 }
00238 if (emitBFC1) {
00239 xvp->output_to_slot[VERT_RESULT_BFC1] = numVpOuts++;
00240 xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
00241 xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 1;
00242 }
00243
00244
00245
00246
00247
00248 dummySlot = numVpOuts;
00249
00250
00251 maxGeneric = -1;
00252 for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
00253 if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
00254 maxGeneric = MAX2(maxGeneric,
00255 xvp->output_to_semantic_index[outAttr]);
00256 }
00257 }
00258
00259
00260
00261
00262 for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
00263 if (outputsWritten & (1 << outAttr)) {
00264 if (xvp->output_to_slot[outAttr] == UNUSED) {
00265 xvp->output_to_slot[outAttr] = dummySlot;
00266 xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
00267 xvp->output_to_semantic_index[outAttr] = maxGeneric + 1;
00268 }
00269 }
00270
00271 #if 0
00272 printf("vp output_to_slot[%d] = %d\n", outAttr,
00273 xvp->output_to_slot[outAttr]);
00274 #endif
00275 }
00276
00277 assert(stvp->Base.Base.NumInstructions > 1);
00278
00279 st_translate_vertex_program(st, stvp, xvp->output_to_slot,
00280 xvp->output_to_semantic_name,
00281 xvp->output_to_semantic_index);
00282
00283 xvp->vp = stvp;
00284
00285
00286 xvp->serialNo = stvp->serialNo;
00287 }
00288
00289 return xvp;
00290 }
00291
00292
00293 void
00294 st_free_translated_vertex_programs(struct st_context *st,
00295 struct translated_vertex_program *xvp)
00296 {
00297 struct translated_vertex_program *next;
00298
00299 while (xvp) {
00300 next = xvp->next;
00301 free(xvp);
00302 xvp = next;
00303 }
00304 }
00305
00306
00307 static void *
00308 get_passthrough_fs(struct st_context *st)
00309 {
00310 struct pipe_shader_state shader;
00311
00312 if (!st->passthrough_fs) {
00313 st->passthrough_fs =
00314 util_make_fragment_passthrough_shader(st->pipe, &shader);
00315 #if 0
00316 util_free_shader(&shader);
00317 #endif
00318 }
00319
00320 return st->passthrough_fs;
00321 }
00322
00323
00324 static void
00325 update_linkage( struct st_context *st )
00326 {
00327 struct st_vertex_program *stvp;
00328 struct st_fragment_program *stfp;
00329 struct translated_vertex_program *xvp;
00330
00331
00332
00333
00334 assert(st->ctx->VertexProgram._Current);
00335 stvp = st_vertex_program(st->ctx->VertexProgram._Current);
00336 assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
00337
00338 assert(st->ctx->FragmentProgram._Current);
00339 stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
00340 assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
00341
00342 xvp = find_translated_vp(st, stvp, stfp);
00343
00344 st_reference_vertprog(st, &st->vp, stvp);
00345 st_reference_fragprog(st, &st->fp, stfp);
00346
00347 cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
00348
00349 if (st->missing_textures) {
00350
00351 void *fs = get_passthrough_fs(st);
00352 cso_set_fragment_shader_handle(st->cso_context, fs);
00353 }
00354 else {
00355 cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
00356 }
00357
00358 st->vertex_result_to_slot = xvp->output_to_slot;
00359 }
00360
00361
00362 const struct st_tracked_state st_update_shader = {
00363 "st_update_shader",
00364 {
00365 0,
00366 ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM
00367 },
00368 update_linkage
00369 };