st_program.c File Reference

Include dependency graph for st_program.c:

Go to the source code of this file.

Defines

#define ST_MAX_SHADER_TOKENS   4096
#define TGSI_DEBUG   0

Functions

static void * mem_dup (const void *src, uint size)
 XXX we should use the version of this from u_memory.h but including that header causes symbol collisions.
void st_translate_vertex_program (struct st_context *st, struct st_vertex_program *stvp, const GLuint outputMapping[], const ubyte *outputSemanticName, const ubyte *outputSemanticIndex)
 Translate a Mesa vertex shader into a TGSI shader.
void st_translate_fragment_program (struct st_context *st, struct st_fragment_program *stfp, const GLuint inputMapping[])
 Translate a Mesa fragment shader into a TGSI shader.
void st_print_shaders (GLcontext *ctx)
 Debug- print current shader text.


Define Documentation

#define ST_MAX_SHADER_TOKENS   4096

Definition at line 52 of file st_program.c.

#define TGSI_DEBUG   0

Definition at line 55 of file st_program.c.


Function Documentation

static void* mem_dup ( const void *  src,
uint  size 
) [static]

XXX we should use the version of this from u_memory.h but including that header causes symbol collisions.

Definition at line 62 of file st_program.c.

References MALLOC.

00063 {
00064    void *dup = MALLOC(size);
00065    if (dup)
00066       memcpy(dup, src, size);
00067    return dup;
00068 }

void st_print_shaders ( GLcontext *  ctx  ) 

Debug- print current shader text.

Definition at line 544 of file st_program.c.

00545 {
00546    struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
00547    if (shProg) {
00548       GLuint i;
00549       for (i = 0; i < shProg->NumShaders; i++) {
00550          printf("GLSL shader %u of %u:\n", i, shProg->NumShaders);
00551          printf("%s\n", shProg->Shaders[i]->Source);
00552       }
00553    }
00554 }

void st_translate_fragment_program ( struct st_context st,
struct st_fragment_program stfp,
const GLuint  inputMapping[] 
)

Translate a Mesa fragment shader into a TGSI shader.

Parameters:
inputMapping to map fragment program input registers to TGSI input slots
tokensOut destination for TGSI tokens
Returns:
pointer to cached pipe_shader object.

Definition at line 364 of file st_program.c.

References assert, st_fragment_program::Base, pipe_context::create_fs_state, st_fragment_program::driver_shader, st_fragment_program::input_map, st_fragment_program::input_semantic_index, st_fragment_program::input_semantic_name, mem_dup(), st_context::pipe, PIPE_MAX_SHADER_OUTPUTS, st_translate_mesa_program(), st_fragment_program::state, TGSI_DEBUG, tgsi_dump(), TGSI_INTERPOLATE_LINEAR, TGSI_INTERPOLATE_PERSPECTIVE, TGSI_PROCESSOR_FRAGMENT, TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_FOG, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, and pipe_shader_state::tokens.

00367 {
00368    struct pipe_context *pipe = st->pipe;
00369    struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
00370    GLuint outputMapping[FRAG_RESULT_MAX];
00371    GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
00372    struct pipe_shader_state fs;
00373    GLuint interpMode[16];  /* XXX size? */
00374    GLuint attr;
00375    const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
00376    GLuint vslot = 0;
00377    GLuint num_generic = 0;
00378    GLuint num_tokens;
00379 
00380    uint fs_num_inputs = 0;
00381 
00382    ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
00383    ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
00384    uint fs_num_outputs = 0;
00385 
00386    GLbitfield input_flags[MAX_PROGRAM_INPUTS];
00387    GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
00388 
00389    memset(&fs, 0, sizeof(fs));
00390    memset(input_flags, 0, sizeof(input_flags));
00391    memset(output_flags, 0, sizeof(output_flags));
00392 
00393    /* which vertex output goes to the first fragment input: */
00394    if (inputsRead & FRAG_BIT_WPOS)
00395       vslot = 0;
00396    else
00397       vslot = 1;
00398 
00399    /*
00400     * Convert Mesa program inputs to TGSI input register semantics.
00401     */
00402    for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
00403       if (inputsRead & (1 << attr)) {
00404          const GLuint slot = fs_num_inputs;
00405 
00406          defaultInputMapping[attr] = slot;
00407 
00408          stfp->input_map[slot] = vslot++;
00409 
00410          fs_num_inputs++;
00411 
00412          switch (attr) {
00413          case FRAG_ATTRIB_WPOS:
00414             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
00415             stfp->input_semantic_index[slot] = 0;
00416             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
00417             break;
00418          case FRAG_ATTRIB_COL0:
00419             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00420             stfp->input_semantic_index[slot] = 0;
00421             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
00422             break;
00423          case FRAG_ATTRIB_COL1:
00424             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00425             stfp->input_semantic_index[slot] = 1;
00426             interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
00427             break;
00428          case FRAG_ATTRIB_FOGC:
00429             if (stfp->Base.UsesPointCoord)
00430                stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00431             else
00432                stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
00433             stfp->input_semantic_index[slot] = 0;
00434             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
00435             break;
00436          case FRAG_ATTRIB_TEX0:
00437          case FRAG_ATTRIB_TEX1:
00438          case FRAG_ATTRIB_TEX2:
00439          case FRAG_ATTRIB_TEX3:
00440          case FRAG_ATTRIB_TEX4:
00441          case FRAG_ATTRIB_TEX5:
00442          case FRAG_ATTRIB_TEX6:
00443          case FRAG_ATTRIB_TEX7:
00444             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00445             stfp->input_semantic_index[slot] = num_generic++;
00446             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
00447             break;
00448          case FRAG_ATTRIB_VAR0:
00449             /* fall-through */
00450          default:
00451             stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00452             stfp->input_semantic_index[slot] = num_generic++;
00453             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
00454          }
00455 
00456          input_flags[slot] = stfp->Base.Base.InputFlags[attr];
00457       }
00458    }
00459 
00460    /*
00461     * Semantics and mapping for outputs
00462     */
00463    {
00464       uint numColors = 0;
00465       GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
00466 
00467       /* if z is written, emit that first */
00468       if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
00469          fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
00470          fs_output_semantic_index[fs_num_outputs] = 0;
00471          outputMapping[FRAG_RESULT_DEPR] = fs_num_outputs;
00472          fs_num_outputs++;
00473          outputsWritten &= ~(1 << FRAG_RESULT_DEPR);
00474       }
00475 
00476       /* handle remaning outputs (color) */
00477       for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
00478          if (outputsWritten & (1 << attr)) {
00479             switch (attr) {
00480             case FRAG_RESULT_DEPR:
00481                /* handled above */
00482                assert(0);
00483                break;
00484             case FRAG_RESULT_COLR:
00485                fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
00486                fs_output_semantic_index[fs_num_outputs] = numColors;
00487                outputMapping[attr] = fs_num_outputs;
00488                numColors++;
00489                break;
00490             default:
00491                assert(0);
00492             }
00493 
00494             output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
00495 
00496             fs_num_outputs++;
00497          }
00498       }
00499    }
00500 
00501    if (!inputMapping)
00502       inputMapping = defaultInputMapping;
00503 
00504    /* XXX: fix static allocation of tokens:
00505     */
00506    num_tokens = st_translate_mesa_program(TGSI_PROCESSOR_FRAGMENT,
00507                                           &stfp->Base.Base,
00508                                           /* inputs */
00509                                           fs_num_inputs,
00510                                           inputMapping,
00511                                           stfp->input_semantic_name,
00512                                           stfp->input_semantic_index,
00513                                           interpMode,
00514                                           input_flags,
00515                                           /* outputs */
00516                                           fs_num_outputs,
00517                                           outputMapping,
00518                                           fs_output_semantic_name,
00519                                           fs_output_semantic_index,
00520                                           output_flags,
00521                                           /* tokenized result */
00522                                           tokens, ST_MAX_SHADER_TOKENS);
00523 
00524    assert(num_tokens < ST_MAX_SHADER_TOKENS);
00525 
00526    fs.tokens = (struct tgsi_token *)
00527       mem_dup(tokens, num_tokens * sizeof(tokens[0]));
00528 
00529    stfp->state = fs; /* struct copy */
00530    stfp->driver_shader = pipe->create_fs_state(pipe, &fs);
00531 
00532    if (0)
00533       _mesa_print_program(&stfp->Base.Base);
00534 
00535    if (TGSI_DEBUG)
00536       tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
00537 }

void st_translate_vertex_program ( struct st_context st,
struct st_vertex_program stvp,
const GLuint  outputMapping[],
const ubyte outputSemanticName,
const ubyte outputSemanticIndex 
)

Translate a Mesa vertex shader into a TGSI shader.

Parameters:
outputMapping to map vertex program output registers (VERT_RESULT_x) to TGSI output slots
tokensOut destination for TGSI tokens
Returns:
pointer to cached pipe_shader object.

Definition at line 80 of file st_program.c.

References assert, st_vertex_program::Base, pipe_context::create_vs_state, st_context::cso_context, cso_delete_vertex_shader(), st_context::ctx, st_vertex_program::driver_shader, FREE, st_vertex_program::index_to_input, st_vertex_program::input_to_index, mem_dup(), st_vertex_program::num_inputs, st_context::pipe, PIPE_MAX_SHADER_INPUTS, PIPE_MAX_SHADER_OUTPUTS, st_translate_mesa_program(), st_vertex_program::state, TGSI_DEBUG, tgsi_dump(), TGSI_PROCESSOR_VERTEX, TGSI_SEMANTIC_BCOLOR, TGSI_SEMANTIC_COLOR, TGSI_SEMANTIC_COUNT, TGSI_SEMANTIC_FOG, TGSI_SEMANTIC_GENERIC, TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_PSIZE, and pipe_shader_state::tokens.

00085 {
00086    struct pipe_context *pipe = st->pipe;
00087    struct tgsi_token tokens[ST_MAX_SHADER_TOKENS];
00088    GLuint defaultOutputMapping[VERT_RESULT_MAX];
00089    struct pipe_shader_state vs;
00090    GLuint attr, i;
00091    GLuint num_generic = 0;
00092    GLuint num_tokens;
00093 
00094    ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
00095    ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
00096    uint vs_num_inputs = 0;
00097 
00098    ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
00099    ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
00100    uint vs_num_outputs = 0;
00101 
00102    GLbitfield input_flags[MAX_PROGRAM_INPUTS];
00103    GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
00104 
00105    memset(&vs, 0, sizeof(vs));
00106    memset(input_flags, 0, sizeof(input_flags));
00107    memset(output_flags, 0, sizeof(output_flags));
00108 
00109    if (stvp->Base.IsPositionInvariant)
00110       _mesa_insert_mvp_code(st->ctx, &stvp->Base);
00111 
00112    /*
00113     * Determine number of inputs, the mappings between VERT_ATTRIB_x
00114     * and TGSI generic input indexes, plus input attrib semantic info.
00115     */
00116    for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
00117       if (stvp->Base.Base.InputsRead & (1 << attr)) {
00118          const GLuint slot = vs_num_inputs;
00119 
00120          vs_num_inputs++;
00121 
00122          stvp->input_to_index[attr] = slot;
00123          stvp->index_to_input[slot] = attr;
00124 
00125          switch (attr) {
00126          case VERT_ATTRIB_POS:
00127             vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
00128             vs_input_semantic_index[slot] = 0;
00129             break;
00130          case VERT_ATTRIB_WEIGHT:
00131             /* fall-through */
00132          case VERT_ATTRIB_NORMAL:
00133             /* just label as a generic */
00134             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00135             vs_input_semantic_index[slot] = 0;
00136             break;
00137          case VERT_ATTRIB_COLOR0:
00138             vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00139             vs_input_semantic_index[slot] = 0;
00140             break;
00141          case VERT_ATTRIB_COLOR1:
00142             vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00143             vs_input_semantic_index[slot] = 1;
00144             break;
00145          case VERT_ATTRIB_FOG:
00146             vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
00147             vs_input_semantic_index[slot] = 0;
00148             break;
00149          case VERT_ATTRIB_POINT_SIZE:
00150             vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
00151             vs_input_semantic_index[slot] = 0;
00152             break;
00153          case VERT_ATTRIB_TEX0:
00154          case VERT_ATTRIB_TEX1:
00155          case VERT_ATTRIB_TEX2:
00156          case VERT_ATTRIB_TEX3:
00157          case VERT_ATTRIB_TEX4:
00158          case VERT_ATTRIB_TEX5:
00159          case VERT_ATTRIB_TEX6:
00160          case VERT_ATTRIB_TEX7:
00161             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00162             vs_input_semantic_index[slot] = num_generic++;
00163             break;
00164          case VERT_ATTRIB_GENERIC0:
00165          case VERT_ATTRIB_GENERIC1:
00166          case VERT_ATTRIB_GENERIC2:
00167          case VERT_ATTRIB_GENERIC3:
00168          case VERT_ATTRIB_GENERIC4:
00169          case VERT_ATTRIB_GENERIC5:
00170          case VERT_ATTRIB_GENERIC6:
00171          case VERT_ATTRIB_GENERIC7:
00172             assert(attr < VERT_ATTRIB_MAX);
00173             vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00174             vs_input_semantic_index[slot] = num_generic++;
00175             break;
00176          default:
00177             assert(0);
00178          }
00179 
00180          input_flags[slot] = stvp->Base.Base.InputFlags[attr];
00181       }
00182    }
00183 
00184 #if 0
00185    if (outputMapping && outputSemanticName) {
00186       printf("VERT_RESULT  written  out_slot  semantic_name  semantic_index\n");
00187       for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
00188          printf("    %-2d          %c       %3d          %2d              %2d\n",
00189                 attr, 
00190                 ((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
00191                 outputMapping[attr],
00192                 outputSemanticName[attr],
00193                 outputSemanticIndex[attr]);
00194       }
00195    }
00196 #endif
00197 
00198    /* initialize output semantics to defaults */
00199    for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
00200       vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
00201       vs_output_semantic_index[i] = 0;
00202       output_flags[i] = 0x0;
00203    }
00204 
00205    num_generic = 0;
00206    /*
00207     * Determine number of outputs, the (default) output register
00208     * mapping and the semantic information for each output.
00209     */
00210    for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
00211       if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
00212          GLuint slot;
00213 
00214          /* XXX
00215           * Pass in the fragment program's input's semantic info.
00216           * Use the generic semantic indexes from there, instead of
00217           * guessing below.
00218           */
00219 
00220          if (outputMapping) {
00221             slot = outputMapping[attr];
00222             assert(slot != ~0);
00223          }
00224          else {
00225             slot = vs_num_outputs;
00226             vs_num_outputs++;
00227             defaultOutputMapping[attr] = slot;
00228          }
00229 
00230          switch (attr) {
00231          case VERT_RESULT_HPOS:
00232             assert(slot == 0);
00233             vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
00234             vs_output_semantic_index[slot] = 0;
00235             break;
00236          case VERT_RESULT_COL0:
00237             vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00238             vs_output_semantic_index[slot] = 0;
00239             break;
00240          case VERT_RESULT_COL1:
00241             vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
00242             vs_output_semantic_index[slot] = 1;
00243             break;
00244          case VERT_RESULT_BFC0:
00245             vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
00246             vs_output_semantic_index[slot] = 0;
00247             break;
00248          case VERT_RESULT_BFC1:
00249             vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
00250             vs_output_semantic_index[slot] = 1;
00251             break;
00252          case VERT_RESULT_FOGC:
00253             vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
00254             vs_output_semantic_index[slot] = 0;
00255             break;
00256          case VERT_RESULT_PSIZ:
00257             vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
00258             vs_output_semantic_index[slot] = 0;
00259             break;
00260          case VERT_RESULT_EDGE:
00261             assert(0);
00262             break;
00263          case VERT_RESULT_TEX0:
00264          case VERT_RESULT_TEX1:
00265          case VERT_RESULT_TEX2:
00266          case VERT_RESULT_TEX3:
00267          case VERT_RESULT_TEX4:
00268          case VERT_RESULT_TEX5:
00269          case VERT_RESULT_TEX6:
00270          case VERT_RESULT_TEX7:
00271             /* fall-through */
00272          case VERT_RESULT_VAR0:
00273             /* fall-through */
00274          default:
00275             if (outputSemanticName) {
00276                /* use provided semantic into */
00277                assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
00278                vs_output_semantic_name[slot] = outputSemanticName[attr];
00279                vs_output_semantic_index[slot] = outputSemanticIndex[attr];
00280             }
00281             else {
00282                /* use default semantic info */
00283                vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
00284                vs_output_semantic_index[slot] = num_generic++;
00285             }
00286          }
00287 
00288          output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
00289       }
00290    }
00291 
00292    assert(vs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
00293 
00294 
00295    if (outputMapping) {
00296       /* find max output slot referenced to compute vs_num_outputs */
00297       GLuint maxSlot = 0;
00298       for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
00299          if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
00300             maxSlot = outputMapping[attr];
00301       }
00302       vs_num_outputs = maxSlot + 1;
00303    }
00304    else {
00305       outputMapping = defaultOutputMapping;
00306    }
00307 
00308    /* free old shader state, if any */
00309    if (stvp->state.tokens) {
00310       FREE((void *) stvp->state.tokens);
00311       stvp->state.tokens = NULL;
00312    }
00313    if (stvp->driver_shader) {
00314       cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
00315       stvp->driver_shader = NULL;
00316    }
00317 
00318    /* XXX: fix static allocation of tokens:
00319     */
00320    num_tokens = st_translate_mesa_program(TGSI_PROCESSOR_VERTEX,
00321                                           &stvp->Base.Base,
00322                                           /* inputs */
00323                                           vs_num_inputs,
00324                                           stvp->input_to_index,
00325                                           vs_input_semantic_name,
00326                                           vs_input_semantic_index,
00327                                           NULL,
00328                                           input_flags,
00329                                           /* outputs */
00330                                           vs_num_outputs,
00331                                           outputMapping,
00332                                           vs_output_semantic_name,
00333                                           vs_output_semantic_index,
00334                                           output_flags,
00335                                           /* tokenized result */
00336                                           tokens, ST_MAX_SHADER_TOKENS);
00337 
00338    assert(num_tokens < ST_MAX_SHADER_TOKENS);
00339 
00340    vs.tokens = (struct tgsi_token *)
00341       mem_dup(tokens, num_tokens * sizeof(tokens[0]));
00342 
00343    stvp->num_inputs = vs_num_inputs;
00344    stvp->state = vs; /* struct copy */
00345    stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
00346 
00347    if (0)
00348       _mesa_print_program(&stvp->Base.Base);
00349 
00350    if (TGSI_DEBUG)
00351       tgsi_dump( vs.tokens, 0 );
00352 }


Generated on Tue Sep 29 06:25:55 2009 for Gallium3D by  doxygen 1.5.4