ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

atifragshader.c
Go to the documentation of this file.
00001 
00024 #include "main/glheader.h"
00025 #include "main/context.h"
00026 #include "main/hash.h"
00027 #include "main/imports.h"
00028 #include "main/macros.h"
00029 #include "main/enums.h"
00030 #include "main/mtypes.h"
00031 #include "atifragshader.h"
00032 
00033 #define MESA_DEBUG_ATI_FS 0
00034 
00035 static struct ati_fragment_shader DummyShader;
00036 
00037 
00041 struct ati_fragment_shader *
00042 _mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
00043 {
00044    struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
00045    (void) ctx;
00046    if (s) {
00047       s->Id = id;
00048       s->RefCount = 1;
00049    }
00050    return s;
00051 }
00052 
00053 
00057 void
00058 _mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
00059 {
00060    GLuint i;
00061    for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
00062       if (s->Instructions[i])
00063          _mesa_free(s->Instructions[i]);
00064       if (s->SetupInst[i])
00065          _mesa_free(s->SetupInst[i]);
00066    }
00067    _mesa_free(s);
00068 }
00069 
00070 
00071 
00072 static void
00073 new_arith_inst(struct ati_fragment_shader *prog)
00074 {
00075 /* set "default" instruction as not all may get defined.
00076    there is no specified way to express a nop with ati fragment shaders we use
00077    GL_NONE as the op enum and just set some params to 0 - so nothing to do here */
00078    prog->numArithInstr[prog->cur_pass >> 1]++;
00079 }
00080 
00081 static void
00082 new_tex_inst(struct ati_fragment_shader *prog)
00083 {
00084 }
00085 
00086 static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype)
00087 {
00088    if (optype == curProg->last_optype) {
00089       curProg->last_optype = 1;
00090    }
00091 }
00092 
00093 #if MESA_DEBUG_ATI_FS
00094 static char *
00095 create_dst_mod_str(GLuint mod)
00096 {
00097    static char ret_str[1024];
00098 
00099    _mesa_memset(ret_str, 0, 1024);
00100    if (mod & GL_2X_BIT_ATI)
00101       _mesa_strncat(ret_str, "|2X", 1024);
00102 
00103    if (mod & GL_4X_BIT_ATI)
00104       _mesa_strncat(ret_str, "|4X", 1024);
00105 
00106    if (mod & GL_8X_BIT_ATI)
00107       _mesa_strncat(ret_str, "|8X", 1024);
00108    if (mod & GL_HALF_BIT_ATI)
00109       _mesa_strncat(ret_str, "|HA", 1024);
00110    if (mod & GL_QUARTER_BIT_ATI)
00111       _mesa_strncat(ret_str, "|QU", 1024);
00112    if (mod & GL_EIGHTH_BIT_ATI)
00113       _mesa_strncat(ret_str, "|EI", 1024);
00114 
00115    if (mod & GL_SATURATE_BIT_ATI)
00116       _mesa_strncat(ret_str, "|SAT", 1024);
00117 
00118    if (_mesa_strlen(ret_str) == 0)
00119       _mesa_strncat(ret_str, "NONE", 1024);
00120    return ret_str;
00121 }
00122 
00123 static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 
00124                 "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" };
00125 
00126 static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
00127              GLuint dstMask, GLuint dstMod, GLuint arg1,
00128              GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
00129              GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
00130              GLuint arg3Rep, GLuint arg3Mod)
00131 {
00132   char *op_name;
00133 
00134   op_name = atifs_ops[(arg_count-1)+(optype?3:0)];
00135   
00136   fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),
00137           _mesa_lookup_enum_by_nr(dst));
00138   if (!optype)
00139     fprintf(stderr, ", %d", dstMask);
00140   
00141   fprintf(stderr, ", %s", create_dst_mod_str(dstMod));
00142   
00143   fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),
00144           _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);
00145   if (arg_count>1)
00146     fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),
00147           _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);
00148   if (arg_count>2)
00149     fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),
00150           _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);
00151 
00152   fprintf(stderr,")\n");
00153 
00154 }
00155 #endif
00156 
00157 static int check_arith_arg(struct ati_fragment_shader *curProg,
00158             GLuint optype, GLuint arg, GLuint argRep)
00159 {
00160    GET_CURRENT_CONTEXT(ctx);
00161 
00162    if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&
00163       ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&
00164       (arg != GL_ZERO) && (arg != GL_ONE) &&
00165       (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) {
00166       _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");
00167       return 0;
00168    }
00169    if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
00170       ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
00171       _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
00172       return 0;
00173    }
00174    if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
00175       ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
00176       _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
00177       return 0;
00178    }
00179    if ((curProg->cur_pass == 1) &&
00180       ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) {
00181       curProg->interpinp1 = GL_TRUE;
00182    }
00183    return 1;
00184 }
00185 
00186 GLuint GLAPIENTRY
00187 _mesa_GenFragmentShadersATI(GLuint range)
00188 {
00189    GLuint first;
00190    GLuint i;
00191    GET_CURRENT_CONTEXT(ctx);
00192 
00193    if (range == 0) {
00194       _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)");
00195       return 0;
00196    }
00197 
00198    if (ctx->ATIFragmentShader.Compiling) {
00199       _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)");
00200       return 0;
00201    }
00202 
00203    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
00204    for (i = 0; i < range; i++) {
00205       _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
00206    }
00207 
00208    return first;
00209 }
00210 
00211 void GLAPIENTRY
00212 _mesa_BindFragmentShaderATI(GLuint id)
00213 {
00214    GET_CURRENT_CONTEXT(ctx);
00215    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00216    struct ati_fragment_shader *newProg;
00217 
00218    if (ctx->ATIFragmentShader.Compiling) {
00219       _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
00220       return;
00221    }
00222 
00223    FLUSH_VERTICES(ctx, _NEW_PROGRAM);
00224 
00225    if (curProg->Id == id) {
00226       return;
00227    }
00228 
00229    /* unbind current */
00230    if (curProg->Id != 0) {
00231       curProg->RefCount--;
00232       if (curProg->RefCount <= 0) {
00233      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
00234       }
00235    }
00236 
00237    /* find new shader */
00238    if (id == 0) {
00239       newProg = ctx->Shared->DefaultFragmentShader;
00240    }
00241    else {
00242       newProg = (struct ati_fragment_shader *)
00243          _mesa_HashLookup(ctx->Shared->ATIShaders, id);
00244       if (!newProg || newProg == &DummyShader) {
00245      /* allocate a new program now */
00246      newProg = _mesa_new_ati_fragment_shader(ctx, id);
00247      if (!newProg) {
00248         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
00249         return;
00250      }
00251      _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
00252       }
00253 
00254    }
00255 
00256    /* do actual bind */
00257    ctx->ATIFragmentShader.Current = newProg;
00258 
00259    ASSERT(ctx->ATIFragmentShader.Current);
00260    if (newProg)
00261       newProg->RefCount++;
00262 
00263    /*if (ctx->Driver.BindProgram)
00264       ctx->Driver.BindProgram(ctx, target, prog); */
00265 }
00266 
00267 void GLAPIENTRY
00268 _mesa_DeleteFragmentShaderATI(GLuint id)
00269 {
00270    GET_CURRENT_CONTEXT(ctx);
00271 
00272    if (ctx->ATIFragmentShader.Compiling) {
00273       _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)");
00274       return;
00275    }
00276 
00277    if (id != 0) {
00278       struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
00279      _mesa_HashLookup(ctx->Shared->ATIShaders, id);
00280       if (prog == &DummyShader) {
00281      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
00282       }
00283       else if (prog) {
00284      if (ctx->ATIFragmentShader.Current &&
00285          ctx->ATIFragmentShader.Current->Id == id) {
00286          FLUSH_VERTICES(ctx, _NEW_PROGRAM);
00287         _mesa_BindFragmentShaderATI(0);
00288      }
00289       }
00290 
00291       /* The ID is immediately available for re-use now */
00292       _mesa_HashRemove(ctx->Shared->ATIShaders, id);
00293       prog->RefCount--;
00294       if (prog->RefCount <= 0) {
00295          _mesa_free(prog);
00296       }
00297    }
00298 }
00299 
00300 
00301 void GLAPIENTRY
00302 _mesa_BeginFragmentShaderATI(void)
00303 {
00304    GLint i;
00305    GET_CURRENT_CONTEXT(ctx);
00306 
00307    if (ctx->ATIFragmentShader.Compiling) {
00308       _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)");
00309       return;
00310    }
00311 
00312    FLUSH_VERTICES(ctx, _NEW_PROGRAM);
00313 
00314    /* if the shader was already defined free instructions and get new ones
00315       (or, could use the same mem but would need to reinitialize) */
00316    /* no idea if it's allowed to redefine a shader */
00317    for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
00318          if (ctx->ATIFragmentShader.Current->Instructions[i])
00319             _mesa_free(ctx->ATIFragmentShader.Current->Instructions[i]);
00320          if (ctx->ATIFragmentShader.Current->SetupInst[i])
00321             _mesa_free(ctx->ATIFragmentShader.Current->SetupInst[i]);
00322    }
00323 
00324    /* malloc the instructions here - not sure if the best place but its
00325       a start */
00326    for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
00327       ctx->ATIFragmentShader.Current->Instructions[i] =
00328      (struct atifs_instruction *)
00329      _mesa_calloc(sizeof(struct atifs_instruction) *
00330            (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI));
00331       ctx->ATIFragmentShader.Current->SetupInst[i] =
00332      (struct atifs_setupinst *)
00333      _mesa_calloc(sizeof(struct atifs_setupinst) *
00334            (MAX_NUM_FRAGMENT_REGISTERS_ATI));
00335    }
00336 
00337 /* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
00338    ctx->ATIFragmentShader.Current->LocalConstDef = 0;
00339    ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
00340    ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
00341    ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
00342    ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;
00343    ctx->ATIFragmentShader.Current->NumPasses = 0;
00344    ctx->ATIFragmentShader.Current->cur_pass = 0;
00345    ctx->ATIFragmentShader.Current->last_optype = 0;
00346    ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;
00347    ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
00348    ctx->ATIFragmentShader.Current->swizzlerq = 0;
00349    ctx->ATIFragmentShader.Compiling = 1;
00350 }
00351 
00352 void GLAPIENTRY
00353 _mesa_EndFragmentShaderATI(void)
00354 {
00355    GET_CURRENT_CONTEXT(ctx);
00356    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00357 #if MESA_DEBUG_ATI_FS
00358    GLint i, j;
00359 #endif
00360 
00361    if (!ctx->ATIFragmentShader.Compiling) {
00362       _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)");
00363       return;
00364    }
00365    if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {
00366       _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)");
00367    /* according to spec, DON'T return here */
00368    }
00369 
00370    match_pair_inst(curProg, 0);
00371    ctx->ATIFragmentShader.Compiling = 0;
00372    ctx->ATIFragmentShader.Current->isValid = GL_TRUE;
00373    if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||
00374       (ctx->ATIFragmentShader.Current->cur_pass == 2)) {
00375       _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)");
00376    }
00377    if (ctx->ATIFragmentShader.Current->cur_pass > 1)
00378       ctx->ATIFragmentShader.Current->NumPasses = 2;
00379    else ctx->ATIFragmentShader.Current->NumPasses = 1;
00380    ctx->ATIFragmentShader.Current->cur_pass=0;
00381 #if MESA_DEBUG_ATI_FS
00382    for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
00383       for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
00384      GLuint op = curProg->SetupInst[j][i].Opcode;
00385      const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0";
00386      GLuint src = curProg->SetupInst[j][i].src;
00387      GLuint swizzle = curProg->SetupInst[j][i].swizzle;
00388      fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
00389           swizzle);
00390       }
00391       for (i = 0; i < curProg->numArithInstr[j]; i++) {
00392      GLuint op0 = curProg->Instructions[j][i].Opcode[0];
00393      GLuint op1 = curProg->Instructions[j][i].Opcode[1];
00394      const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0";
00395      const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0";
00396      GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
00397      GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
00398      fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0,
00399           op1, op1_enum, count1);
00400       }
00401    }
00402 #endif
00403    if (ctx->Driver.ProgramStringNotify)
00404       ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL );
00405 }
00406 
00407 void GLAPIENTRY
00408 _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
00409 {
00410    GET_CURRENT_CONTEXT(ctx);
00411    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00412    struct atifs_setupinst *curI;
00413 
00414    if (!ctx->ATIFragmentShader.Compiling) {
00415       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)");
00416       return;
00417    }
00418 
00419    if (curProg->cur_pass == 1) {
00420       match_pair_inst(curProg, 0);
00421       curProg->cur_pass = 2;
00422    }
00423    if ((curProg->cur_pass > 2) ||
00424       ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
00425       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
00426       return;
00427    }
00428    if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
00429       ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
00430       _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
00431       return;
00432    }
00433    if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
00434        ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
00435        ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
00436       _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
00437       return;
00438    }
00439    if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
00440       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
00441       return;
00442    }
00443    if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
00444       _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
00445       return;
00446    }
00447    if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) {
00448       _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
00449       return;
00450    }
00451    if (coord <= GL_TEXTURE7_ARB) {
00452       GLuint tmp = coord - GL_TEXTURE0_ARB;
00453       if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
00454        (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
00455      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
00456      return;
00457       } else {
00458      curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
00459       }
00460    }
00461 
00462    curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
00463    new_tex_inst(curProg);
00464 
00465    /* add the instructions */
00466    curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
00467 
00468    curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP;
00469    curI->src = coord;
00470    curI->swizzle = swizzle;
00471 
00472 #if MESA_DEBUG_ATI_FS
00473    _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
00474            _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
00475            _mesa_lookup_enum_by_nr(swizzle));
00476 #endif
00477 }
00478 
00479 void GLAPIENTRY
00480 _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
00481 {
00482    GET_CURRENT_CONTEXT(ctx);
00483    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00484    struct atifs_setupinst *curI;
00485 
00486    if (!ctx->ATIFragmentShader.Compiling) {
00487       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)");
00488       return;
00489    }
00490 
00491    if (curProg->cur_pass == 1) {
00492       match_pair_inst(curProg, 0);
00493       curProg->cur_pass = 2;
00494    }
00495    if ((curProg->cur_pass > 2) ||
00496       ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
00497       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
00498       return;
00499    }
00500    if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
00501       ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
00502       _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
00503       return;
00504    }
00505    if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
00506        ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
00507        ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
00508    /* is this texture5 or texture7? spec is a bit unclear there */
00509       _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
00510       return;
00511    }
00512    if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
00513       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
00514       return;
00515    }
00516    if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
00517       _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
00518       return;
00519    }
00520    if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) {
00521       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
00522       return;
00523    }
00524    if (interp <= GL_TEXTURE7_ARB) {
00525       GLuint tmp = interp - GL_TEXTURE0_ARB;
00526       if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
00527        (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
00528      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
00529      return;
00530       } else {
00531      curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
00532       }
00533    }
00534 
00535    curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
00536    new_tex_inst(curProg);
00537 
00538    /* add the instructions */
00539    curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
00540 
00541    curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP;
00542    curI->src = interp;
00543    curI->swizzle = swizzle;
00544 
00545 #if MESA_DEBUG_ATI_FS
00546    _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
00547            _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
00548            _mesa_lookup_enum_by_nr(swizzle));
00549 #endif
00550 }
00551 
00552 static void
00553 _mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
00554              GLuint dstMask, GLuint dstMod, GLuint arg1,
00555              GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
00556              GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
00557              GLuint arg3Rep, GLuint arg3Mod)
00558 {
00559    GET_CURRENT_CONTEXT(ctx);
00560    struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00561    GLint ci;
00562    struct atifs_instruction *curI;
00563    GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI;
00564 
00565    if (!ctx->ATIFragmentShader.Compiling) {
00566       _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)");
00567       return;
00568    }
00569 
00570    if (curProg->cur_pass==0)
00571       curProg->cur_pass=1;
00572 
00573    else if (curProg->cur_pass==2)
00574       curProg->cur_pass=3;
00575 
00576    /* decide whether this is a new instruction or not ... all color instructions are new,
00577       and alpha instructions might also be new if there was no preceding color inst */
00578    if ((optype == 0) || (curProg->last_optype == optype)) {
00579       if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) {
00580      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)");
00581      return;
00582       }
00583       /* easier to do that here slight side effect invalid instr will still be inserted as nops */
00584       match_pair_inst(curProg, optype);
00585       new_arith_inst(curProg);
00586    }
00587    curProg->last_optype = optype;
00588    ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1;
00589 
00590    /* add the instructions */
00591    curI = &curProg->Instructions[curProg->cur_pass >> 1][ci];
00592 
00593    /* error checking */
00594    if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
00595       _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)");
00596       return;
00597    }
00598    if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) &&
00599       (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) &&
00600       (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) &&
00601       (modtemp != GL_EIGHTH_BIT_ATI)) {
00602       _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp);
00603       return;
00604    }
00605    /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */
00606    if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) {
00607       _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)");
00608       return;
00609    }
00610    if (optype == 1) {
00611       if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) ||
00612      ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) ||
00613      ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) ||
00614      ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) {
00615      _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)");
00616      return;
00617       }
00618    }
00619    if ((op == GL_DOT4_ATI) &&
00620       (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) ||
00621       (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) {
00622       _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
00623    }
00624 
00625    if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) {
00626       return;
00627    }
00628    if (arg2) {
00629       if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) {
00630      return;
00631       }
00632    }
00633    if (arg3) {
00634       if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) {
00635      return;
00636       }
00637       if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) &&
00638       (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) &&
00639       (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) &&
00640       (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) {
00641      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)");
00642      return;
00643       }
00644    }
00645 
00646    /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */
00647 
00648    curI->Opcode[optype] = op;
00649    curI->SrcReg[optype][0].Index = arg1;
00650    curI->SrcReg[optype][0].argRep = arg1Rep;
00651    curI->SrcReg[optype][0].argMod = arg1Mod;
00652    curI->ArgCount[optype] = arg_count;
00653 
00654    if (arg2) {
00655       curI->SrcReg[optype][1].Index = arg2;
00656       curI->SrcReg[optype][1].argRep = arg2Rep;
00657       curI->SrcReg[optype][1].argMod = arg2Mod;
00658    }
00659 
00660    if (arg3) {
00661       curI->SrcReg[optype][2].Index = arg3;
00662       curI->SrcReg[optype][2].argRep = arg3Rep;
00663       curI->SrcReg[optype][2].argMod = arg3Mod;
00664    }
00665 
00666    curI->DstReg[optype].Index = dst;
00667    curI->DstReg[optype].dstMod = dstMod;
00668    curI->DstReg[optype].dstMask = dstMask;
00669 
00670 #if MESA_DEBUG_ATI_FS
00671    debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);
00672 #endif
00673 
00674 }
00675 
00676 void GLAPIENTRY
00677 _mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
00678               GLuint dstMod, GLuint arg1, GLuint arg1Rep,
00679               GLuint arg1Mod)
00680 {
00681    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask,
00682             dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
00683 }
00684 
00685 void GLAPIENTRY
00686 _mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
00687               GLuint dstMod, GLuint arg1, GLuint arg1Rep,
00688               GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
00689               GLuint arg2Mod)
00690 {
00691    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask,
00692             dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
00693             arg2Mod, 0, 0, 0);
00694 }
00695 
00696 void GLAPIENTRY
00697 _mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
00698               GLuint dstMod, GLuint arg1, GLuint arg1Rep,
00699               GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
00700               GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
00701               GLuint arg3Mod)
00702 {
00703    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask,
00704             dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
00705             arg2Mod, arg3, arg3Rep, arg3Mod);
00706 }
00707 
00708 void GLAPIENTRY
00709 _mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
00710               GLuint arg1Rep, GLuint arg1Mod)
00711 {
00712    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod,
00713             arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
00714 }
00715 
00716 void GLAPIENTRY
00717 _mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
00718               GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
00719               GLuint arg2Rep, GLuint arg2Mod)
00720 {
00721    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod,
00722             arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0,
00723             0);
00724 }
00725 
00726 void GLAPIENTRY
00727 _mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
00728               GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
00729               GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
00730               GLuint arg3Rep, GLuint arg3Mod)
00731 {
00732    _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod,
00733             arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3,
00734             arg3Rep, arg3Mod);
00735 }
00736 
00737 void GLAPIENTRY
00738 _mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value)
00739 {
00740    GLuint dstindex;
00741    GET_CURRENT_CONTEXT(ctx);
00742 
00743    if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) {
00744       /* spec says nothing about what should happen here but we can't just segfault...*/
00745       _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)");
00746       return;
00747    }
00748 
00749    dstindex = dst - GL_CON_0_ATI;
00750    if (ctx->ATIFragmentShader.Compiling) {
00751       struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
00752       COPY_4V(curProg->Constants[dstindex], value);
00753       curProg->LocalConstDef |= 1 << dstindex;
00754    }
00755    else {
00756       FLUSH_VERTICES(ctx, _NEW_PROGRAM);
00757       COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
00758    }
00759 }

Generated on Sun May 27 2012 04:20:33 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.