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

s_atifragshader.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004  David Airlie   All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00017  * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020  */
00021 
00022 #include "main/glheader.h"
00023 #include "main/colormac.h"
00024 #include "main/context.h"
00025 #include "main/macros.h"
00026 #include "shader/program.h"
00027 #include "shader/atifragshader.h"
00028 #include "swrast/s_atifragshader.h"
00029 
00030 
00034 struct atifs_machine
00035 {
00036    GLfloat Registers[6][4];         
00037    GLfloat PrevPassRegisters[6][4];
00038    GLfloat Inputs[2][4];   
00039 };
00040 
00041 
00042 
00046 static void
00047 fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda,
00048         GLuint unit, GLfloat color[4])
00049 {
00050    GLchan rgba[4];
00051    SWcontext *swrast = SWRAST_CONTEXT(ctx);
00052 
00053    /* XXX use a float-valued TextureSample routine here!!! */
00054    swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current,
00055                                1, (const GLfloat(*)[4]) texcoord,
00056                                &lambda, &rgba);
00057    color[0] = CHAN_TO_FLOAT(rgba[0]);
00058    color[1] = CHAN_TO_FLOAT(rgba[1]);
00059    color[2] = CHAN_TO_FLOAT(rgba[2]);
00060    color[3] = CHAN_TO_FLOAT(rgba[3]);
00061 }
00062 
00063 static void
00064 apply_swizzle(GLfloat values[4], GLuint swizzle)
00065 {
00066    GLfloat s, t, r, q;
00067 
00068    s = values[0];
00069    t = values[1];
00070    r = values[2];
00071    q = values[3];
00072 
00073    switch (swizzle) {
00074    case GL_SWIZZLE_STR_ATI:
00075       values[0] = s;
00076       values[1] = t;
00077       values[2] = r;
00078       break;
00079    case GL_SWIZZLE_STQ_ATI:
00080       values[0] = s;
00081       values[1] = t;
00082       values[2] = q;
00083       break;
00084    case GL_SWIZZLE_STR_DR_ATI:
00085       values[0] = s / r;
00086       values[1] = t / r;
00087       values[2] = 1 / r;
00088       break;
00089    case GL_SWIZZLE_STQ_DQ_ATI:
00090 /* make sure q is not 0 to avoid problems later with infinite values (texture lookup)? */
00091       if (q == 0.0F) q = 0.000000001;
00092       values[0] = s / q;
00093       values[1] = t / q;
00094       values[2] = 1 / q;
00095       break;
00096    }
00097    values[3] = 0.0;
00098 }
00099 
00100 static void
00101 apply_src_rep(GLint optype, GLuint rep, GLfloat * val)
00102 {
00103    GLint i;
00104    GLint start, end;
00105    if (!rep)
00106       return;
00107 
00108    start = optype ? 3 : 0;
00109    end = 4;
00110 
00111    for (i = start; i < end; i++) {
00112       switch (rep) {
00113       case GL_RED:
00114      val[i] = val[0];
00115      break;
00116       case GL_GREEN:
00117      val[i] = val[1];
00118      break;
00119       case GL_BLUE:
00120      val[i] = val[2];
00121      break;
00122       case GL_ALPHA:
00123      val[i] = val[3];
00124      break;
00125       }
00126    }
00127 }
00128 
00129 static void
00130 apply_src_mod(GLint optype, GLuint mod, GLfloat * val)
00131 {
00132    GLint i;
00133    GLint start, end;
00134 
00135    if (!mod)
00136       return;
00137 
00138    start = optype ? 3 : 0;
00139    end = 4;
00140 
00141    for (i = start; i < end; i++) {
00142       if (mod & GL_COMP_BIT_ATI)
00143      val[i] = 1 - val[i];
00144 
00145       if (mod & GL_BIAS_BIT_ATI)
00146      val[i] = val[i] - 0.5;
00147 
00148       if (mod & GL_2X_BIT_ATI)
00149      val[i] = 2 * val[i];
00150 
00151       if (mod & GL_NEGATE_BIT_ATI)
00152      val[i] = -val[i];
00153    }
00154 }
00155 
00156 static void
00157 apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val)
00158 {
00159    GLint i;
00160    GLint has_sat = mod & GL_SATURATE_BIT_ATI;
00161    GLint start, end;
00162 
00163    mod &= ~GL_SATURATE_BIT_ATI;
00164 
00165    start = optype ? 3 : 0;
00166    end = optype ? 4 : 3;
00167 
00168    for (i = start; i < end; i++) {
00169       switch (mod) {
00170       case GL_2X_BIT_ATI:
00171      val[i] = 2 * val[i];
00172      break;
00173       case GL_4X_BIT_ATI:
00174      val[i] = 4 * val[i];
00175      break;
00176       case GL_8X_BIT_ATI:
00177      val[i] = 8 * val[i];
00178      break;
00179       case GL_HALF_BIT_ATI:
00180      val[i] = val[i] * 0.5;
00181      break;
00182       case GL_QUARTER_BIT_ATI:
00183      val[i] = val[i] * 0.25;
00184      break;
00185       case GL_EIGHTH_BIT_ATI:
00186      val[i] = val[i] * 0.125;
00187      break;
00188       }
00189 
00190       if (has_sat) {
00191      if (val[i] < 0.0)
00192         val[i] = 0;
00193      else if (val[i] > 1.0)
00194         val[i] = 1.0;
00195       }
00196       else {
00197      if (val[i] < -8.0)
00198         val[i] = -8.0;
00199      else if (val[i] > 8.0)
00200         val[i] = 8.0;
00201       }
00202    }
00203 }
00204 
00205 
00206 static void
00207 write_dst_addr(GLuint optype, GLuint mod, GLuint mask, GLfloat * src,
00208            GLfloat * dst)
00209 {
00210    GLint i;
00211    apply_dst_mod(optype, mod, src);
00212 
00213    if (optype == ATI_FRAGMENT_SHADER_COLOR_OP) {
00214       if (mask) {
00215      if (mask & GL_RED_BIT_ATI)
00216         dst[0] = src[0];
00217 
00218      if (mask & GL_GREEN_BIT_ATI)
00219         dst[1] = src[1];
00220 
00221      if (mask & GL_BLUE_BIT_ATI)
00222         dst[2] = src[2];
00223       }
00224       else {
00225      for (i = 0; i < 3; i++)
00226         dst[i] = src[i];
00227       }
00228    }
00229    else
00230       dst[3] = src[3];
00231 }
00232 
00233 static void
00234 finish_pass(struct atifs_machine *machine)
00235 {
00236    GLint i;
00237 
00238    for (i = 0; i < 6; i++) {
00239       COPY_4V(machine->PrevPassRegisters[i], machine->Registers[i]);
00240    }
00241 }
00242 
00243 struct ati_fs_opcode_st ati_fs_opcodes[] = {
00244    {GL_ADD_ATI, 2},
00245    {GL_SUB_ATI, 2},
00246    {GL_MUL_ATI, 2},
00247    {GL_MAD_ATI, 3},
00248    {GL_LERP_ATI, 3},
00249    {GL_MOV_ATI, 1},
00250    {GL_CND_ATI, 3},
00251    {GL_CND0_ATI, 3},
00252    {GL_DOT2_ADD_ATI, 3},
00253    {GL_DOT3_ATI, 2},
00254    {GL_DOT4_ATI, 2}
00255 };
00256 
00257 
00258 
00259 static void
00260 handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst,
00261            const SWspan *span, GLuint column, GLuint idx)
00262 {
00263    GLuint swizzle = texinst->swizzle;
00264    GLuint pass_tex = texinst->src;
00265 
00266    if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
00267       pass_tex -= GL_TEXTURE0_ARB;
00268       COPY_4V(machine->Registers[idx],
00269           span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]);
00270    }
00271    else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) {
00272       pass_tex -= GL_REG_0_ATI;
00273       COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]);
00274    }
00275    apply_swizzle(machine->Registers[idx], swizzle);
00276 
00277 }
00278 
00279 static void
00280 handle_sample_op(GLcontext * ctx, struct atifs_machine *machine,
00281          struct atifs_setupinst *texinst, const SWspan *span,
00282          GLuint column, GLuint idx)
00283 {
00284 /* sample from unit idx using texinst->src as coords */
00285    GLuint swizzle = texinst->swizzle;
00286    GLuint coord_source = texinst->src;
00287    GLfloat tex_coords[4];
00288 
00289    if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) {
00290       coord_source -= GL_TEXTURE0_ARB;
00291       COPY_4V(tex_coords,
00292               span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]);
00293    }
00294    else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) {
00295       coord_source -= GL_REG_0_ATI;
00296       COPY_4V(tex_coords, machine->PrevPassRegisters[coord_source]);
00297    }
00298    apply_swizzle(tex_coords, swizzle);
00299    fetch_texel(ctx, tex_coords, 0.0F, idx, machine->Registers[idx]);
00300 }
00301 
00302 #define SETUP_SRC_REG(optype, i, x)     \
00303 do {                        \
00304    COPY_4V(src[optype][i], x);          \
00305 } while (0)
00306 
00307 
00308 
00318 static void
00319 execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader,
00320            struct atifs_machine *machine, const SWspan *span,
00321                GLuint column)
00322 {
00323    GLuint pc;
00324    struct atifs_instruction *inst;
00325    struct atifs_setupinst *texinst;
00326    GLint optype;
00327    GLuint i;
00328    GLint j, pass;
00329    GLint dstreg;
00330    GLfloat src[2][3][4];
00331    GLfloat zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
00332    GLfloat ones[4] = { 1.0, 1.0, 1.0, 1.0 };
00333    GLfloat dst[2][4], *dstp;
00334 
00335    for (pass = 0; pass < shader->NumPasses; pass++) {
00336       if (pass > 0)
00337      finish_pass(machine);
00338       for (j = 0; j < MAX_NUM_FRAGMENT_REGISTERS_ATI; j++) {
00339      texinst = &shader->SetupInst[pass][j];
00340      if (texinst->Opcode == ATI_FRAGMENT_SHADER_PASS_OP)
00341         handle_pass_op(machine, texinst, span, column, j);
00342      else if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP)
00343         handle_sample_op(ctx, machine, texinst, span, column, j);
00344       }
00345 
00346       for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
00347      inst = &shader->Instructions[pass][pc];
00348 
00349      /* setup the source registers for color and alpha ops */
00350      for (optype = 0; optype < 2; optype++) {
00351         for (i = 0; i < inst->ArgCount[optype]; i++) {
00352            GLint index = inst->SrcReg[optype][i].Index;
00353 
00354            if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
00355           SETUP_SRC_REG(optype, i,
00356                 machine->Registers[index - GL_REG_0_ATI]);
00357            else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
00358           if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
00359              SETUP_SRC_REG(optype, i,
00360                 shader->Constants[index - GL_CON_0_ATI]);
00361           } else {
00362              SETUP_SRC_REG(optype, i,
00363                 ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]);
00364           }
00365            }
00366            else if (index == GL_ONE)
00367           SETUP_SRC_REG(optype, i, ones);
00368            else if (index == GL_ZERO)
00369           SETUP_SRC_REG(optype, i, zeros);
00370            else if (index == GL_PRIMARY_COLOR_EXT)
00371           SETUP_SRC_REG(optype, i,
00372                 machine->Inputs[ATI_FS_INPUT_PRIMARY]);
00373            else if (index == GL_SECONDARY_INTERPOLATOR_ATI)
00374           SETUP_SRC_REG(optype, i,
00375                 machine->Inputs[ATI_FS_INPUT_SECONDARY]);
00376 
00377            apply_src_rep(optype, inst->SrcReg[optype][i].argRep,
00378                  src[optype][i]);
00379            apply_src_mod(optype, inst->SrcReg[optype][i].argMod,
00380                  src[optype][i]);
00381         }
00382      }
00383 
00384      /* Execute the operations - color then alpha */
00385      for (optype = 0; optype < 2; optype++) {
00386         if (inst->Opcode[optype]) {
00387            switch (inst->Opcode[optype]) {
00388            case GL_ADD_ATI:
00389           if (!optype)
00390              for (i = 0; i < 3; i++) {
00391             dst[optype][i] =
00392                src[optype][0][i] + src[optype][1][i];
00393              }
00394           else
00395              dst[optype][3] = src[optype][0][3] + src[optype][1][3];
00396           break;
00397            case GL_SUB_ATI:
00398           if (!optype)
00399              for (i = 0; i < 3; i++) {
00400             dst[optype][i] =
00401                src[optype][0][i] - src[optype][1][i];
00402              }
00403           else
00404              dst[optype][3] = src[optype][0][3] - src[optype][1][3];
00405           break;
00406            case GL_MUL_ATI:
00407           if (!optype)
00408              for (i = 0; i < 3; i++) {
00409             dst[optype][i] =
00410                src[optype][0][i] * src[optype][1][i];
00411              }
00412           else
00413              dst[optype][3] = src[optype][0][3] * src[optype][1][3];
00414           break;
00415            case GL_MAD_ATI:
00416           if (!optype)
00417              for (i = 0; i < 3; i++) {
00418             dst[optype][i] =
00419                src[optype][0][i] * src[optype][1][i] +
00420                src[optype][2][i];
00421              }
00422           else
00423              dst[optype][3] =
00424             src[optype][0][3] * src[optype][1][3] +
00425             src[optype][2][3];
00426           break;
00427            case GL_LERP_ATI:
00428           if (!optype)
00429              for (i = 0; i < 3; i++) {
00430             dst[optype][i] =
00431                src[optype][0][i] * src[optype][1][i] + (1 -
00432                                     src
00433                                     [optype]
00434                                     [0][i]) *
00435                src[optype][2][i];
00436              }
00437           else
00438              dst[optype][3] =
00439             src[optype][0][3] * src[optype][1][3] + (1 -
00440                                  src[optype]
00441                                  [0][3]) *
00442             src[optype][2][3];
00443           break;
00444 
00445            case GL_MOV_ATI:
00446           if (!optype)
00447              for (i = 0; i < 3; i++) {
00448             dst[optype][i] = src[optype][0][i];
00449              }
00450           else
00451              dst[optype][3] = src[optype][0][3];
00452           break;
00453            case GL_CND_ATI:
00454           if (!optype) {
00455              for (i = 0; i < 3; i++) {
00456             dst[optype][i] =
00457                (src[optype][2][i] >
00458                 0.5) ? src[optype][0][i] : src[optype][1][i];
00459              }
00460           }
00461           else {
00462              dst[optype][3] =
00463             (src[optype][2][3] >
00464              0.5) ? src[optype][0][3] : src[optype][1][3];
00465           }
00466           break;
00467 
00468            case GL_CND0_ATI:
00469           if (!optype)
00470              for (i = 0; i < 3; i++) {
00471             dst[optype][i] =
00472                (src[optype][2][i] >=
00473                 0) ? src[optype][0][i] : src[optype][1][i];
00474              }
00475           else {
00476              dst[optype][3] =
00477             (src[optype][2][3] >=
00478              0) ? src[optype][0][3] : src[optype][1][3];
00479           }
00480           break;
00481            case GL_DOT2_ADD_ATI:
00482           {
00483              GLfloat result;
00484 
00485              /* DOT 2 always uses the source from the color op */
00486              /* could save recalculation of dot products for alpha inst */
00487              result = src[0][0][0] * src[0][1][0] +
00488             src[0][0][1] * src[0][1][1] + src[0][2][2];
00489              if (!optype) {
00490             for (i = 0; i < 3; i++) {
00491                dst[optype][i] = result;
00492             }
00493              }
00494              else
00495             dst[optype][3] = result;
00496           }
00497           break;
00498            case GL_DOT3_ATI:
00499           {
00500              GLfloat result;
00501 
00502              /* DOT 3 always uses the source from the color op */
00503              result = src[0][0][0] * src[0][1][0] +
00504             src[0][0][1] * src[0][1][1] +
00505             src[0][0][2] * src[0][1][2];
00506 
00507              if (!optype) {
00508             for (i = 0; i < 3; i++) {
00509                dst[optype][i] = result;
00510             }
00511              }
00512              else
00513             dst[optype][3] = result;
00514           }
00515           break;
00516            case GL_DOT4_ATI:
00517           {
00518              GLfloat result;
00519 
00520              /* DOT 4 always uses the source from the color op */
00521              result = src[0][0][0] * src[0][1][0] +
00522             src[0][0][1] * src[0][1][1] +
00523             src[0][0][2] * src[0][1][2] +
00524             src[0][0][3] * src[0][1][3];
00525              if (!optype) {
00526             for (i = 0; i < 3; i++) {
00527                dst[optype][i] = result;
00528             }
00529              }
00530              else
00531             dst[optype][3] = result;
00532           }
00533           break;
00534 
00535            }
00536         }
00537      }
00538 
00539      /* write out the destination registers */
00540      for (optype = 0; optype < 2; optype++) {
00541         if (inst->Opcode[optype]) {
00542            dstreg = inst->DstReg[optype].Index;
00543            dstp = machine->Registers[dstreg - GL_REG_0_ATI];
00544 
00545            if ((optype == 0) || ((inst->Opcode[1] != GL_DOT2_ADD_ATI) &&
00546           (inst->Opcode[1] != GL_DOT3_ATI) && (inst->Opcode[1] != GL_DOT4_ATI)))
00547               write_dst_addr(optype, inst->DstReg[optype].dstMod,
00548                   inst->DstReg[optype].dstMask, dst[optype],
00549                   dstp);
00550            else
00551           write_dst_addr(1, inst->DstReg[0].dstMod, 0, dst[1], dstp);
00552         }
00553      }
00554       }
00555    }
00556 }
00557 
00558 
00562 static void
00563 init_machine(GLcontext * ctx, struct atifs_machine *machine,
00564          const struct ati_fragment_shader *shader,
00565          const SWspan *span, GLuint col)
00566 {
00567    GLfloat (*inputs)[4] = machine->Inputs;
00568    GLint i, j;
00569 
00570    for (i = 0; i < 6; i++) {
00571       for (j = 0; j < 4; j++)
00572      machine->Registers[i][j] = 0.0;
00573    }
00574 
00575    COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]);
00576    COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]);
00577 }
00578 
00579 
00580 
00584 void
00585 _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span)
00586 {
00587    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
00588    struct atifs_machine machine;
00589    GLuint i;
00590 
00591    /* incoming colors should be floats */
00592    ASSERT(span->array->ChanType == GL_FLOAT);
00593 
00594    ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI;
00595 
00596    for (i = 0; i < span->end; i++) {
00597       if (span->array->mask[i]) {
00598      init_machine(ctx, &machine, shader, span, i);
00599 
00600      execute_shader(ctx, shader, &machine, span, i);
00601 
00602          /* store result color */
00603      {
00604         const GLfloat *colOut = machine.Registers[0];
00605             /*fprintf(stderr,"outputs %f %f %f %f\n",
00606               colOut[0], colOut[1], colOut[2], colOut[3]); */
00607             COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut);
00608      }
00609       }
00610    }
00611 
00612    ctx->_CurrentProgram = 0;
00613 }

Generated on Sat May 26 2012 04:19:30 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.