Home | History | Annotate | Download | only in pixelflinger2
      1 /**
      2  **
      3  ** Copyright 2010, The Android Open Source Project
      4  **
      5  ** Licensed under the Apache License, Version 2.0 (the "License");
      6  ** you may not use this file except in compliance with the License.
      7  ** You may obtain a copy of the License at
      8  **
      9  **     http://www.apache.org/licenses/LICENSE-2.0
     10  **
     11  ** Unless required by applicable law or agreed to in writing, software
     12  ** distributed under the License is distributed on an "AS IS" BASIS,
     13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  ** See the License for the specific language governing permissions and
     15  ** limitations under the License.
     16  */
     17 
     18 #include <assert.h>
     19 #include <stdio.h>
     20 #include <string.h>
     21 
     22 #include "src/pixelflinger2/pixelflinger2.h"
     23 #include "src/pixelflinger2/texture.h"
     24 #include "src/mesa/main/mtypes.h"
     25 
     26 #if !USE_LLVM_SCANLINE
     27 
     28 static void Saturate(Vec4<BlendComp_t> * color)
     29 {
     30    color->r = MIN2(MAX2(color->r, 0), 255);
     31    color->g = MIN2(MAX2(color->g, 0), 255);
     32    color->b = MIN2(MAX2(color->b, 0), 255);
     33    color->a = MIN2(MAX2(color->a, 0), 255);
     34 }
     35 
     36 static inline void RGBAIntToRGBAIntx4(unsigned rgba, Vec4<BlendComp_t> * color) __attribute__((always_inline));
     37 static inline void RGBAIntToRGBAIntx4(unsigned rgba, Vec4<BlendComp_t> * color)
     38 {
     39    color->r = rgba & 0xff;
     40    color->g = (rgba >>= 8) & 0xff;
     41    color->b = (rgba >>= 8) & 0xff;
     42    color->a = (rgba >>= 8);
     43 }
     44 
     45 static inline void RGBAFloatx4ToRGBAIntx4(Vector4 * v, Vec4<BlendComp_t> * color)
     46 {
     47    color->r = v->r * 255;
     48    color->g = v->g * 255;
     49    color->b = v->b * 255;
     50    color->a = v->a * 255;
     51 }
     52 
     53 static inline unsigned RGBAIntx4ToRGBAInt(const Vec4<BlendComp_t> * color);
     54 static inline unsigned RGBAIntx4ToRGBAInt(const Vec4<BlendComp_t> * color)
     55 {
     56    return color->r | (color->g << 8) | (color->b << 16) | (color->a << 24);
     57 }
     58 
     59 
     60 
     61 //static inline Pixel Vector4ToPixelRGBA(const Vector4 * color) __attribute__((always_inline));
     62 //static inline Pixel Vector4ToPixelRGBA(const Vector4 * color)
     63 //{
     64 //    Pixel pixel;
     65 //#if defined(__ARM_HAVE_NEON) && USE_NEON
     66 //    int32x4_t  c = vcvtq_s32_f32(vmulq_n_f32(color->f4, 255.0f));
     67 //    c = vminq_s32(c, vdupq_n_s32(255));
     68 //    c = vmaxq_s32(c, vdupq_n_s32(0));
     69 //    pixel.channels[0] = (unsigned char)vgetq_lane_s32(c, 0);
     70 //    pixel.channels[1] = (unsigned char)vgetq_lane_s32(c, 1);
     71 //    pixel.channels[2] = (unsigned char)vgetq_lane_s32(c, 2);
     72 //    pixel.channels[3] = (unsigned char)vgetq_lane_s32(c, 3);
     73 //#else
     74 //    pixel.channels[0] = (unsigned char)MIN2(MAX2((short)(color->r * 255), 0), 255);
     75 //	pixel.channels[1] = (unsigned char)MIN2(MAX2((short)(color->g * 255), 0), 255);
     76 //	pixel.channels[2] = (unsigned char)MIN2(MAX2((short)(color->b * 255), 0), 255);
     77 //	pixel.channels[3] = (unsigned char)MIN2(MAX2((short)(color->a * 255), 0), 255);
     78 //#endif //#if USE_FIXED_POINT
     79 //	return pixel;
     80 //}
     81 
     82 template<typename T>
     83 static inline void BlendFactor(const unsigned mode, T & factor, const T & src,
     84                                const T & dst, const T & constant, const T & one,
     85                                const T & zero, const BlendComp_t & srcA, const BlendComp_t & dstA,
     86                                const BlendComp_t & constantA, const BlendComp_t & sOne) __attribute__((always_inline));
     87 template<typename T>
     88 static inline void BlendFactor(const unsigned mode, T & factor, const T & src,
     89                                const T & dst, const T & constant, const T & one,
     90                                const T & zero, const BlendComp_t & srcA, const BlendComp_t & dstA,
     91                                const BlendComp_t & constantA, const BlendComp_t & sOne)
     92 {
     93    switch (mode) {
     94    case 0: // GL_ZERO
     95       factor = zero;
     96       return;
     97    case 1: // GL_ONE
     98       factor = one;
     99       return;
    100    case 2: // GL_SRC_COLOR:
    101       factor = src;
    102       return;
    103    case 3: // GL_ONE_MINUS_SRC_COLOR:
    104       factor = one;
    105       factor -= src;
    106       return;
    107    case 4: // GL_DST_COLOR:
    108       factor = dst;
    109       return;
    110    case 5: // GL_ONE_MINUS_DST_COLOR:
    111       factor = one;
    112       factor -= dst;
    113       return;
    114    case 6: // GL_SRC_ALPHA:
    115       factor = srcA;
    116       return;
    117    case 7: // GL_ONE_MINUS_SRC_ALPHA:
    118       factor = sOne - srcA;
    119       return;
    120    case 8: // GL_DST_ALPHA:
    121       factor = dstA;
    122       return;
    123    case 9: // GL_ONE_MINUS_DST_ALPHA:
    124       factor = sOne - dstA;
    125       return;
    126    case 10: // GL_SRC_ALPHA_SATURATE: // valid only for source color; src alpha = 1
    127       factor = MIN2(srcA, sOne - dstA);
    128       return;
    129    case 11: // GL_CONSTANT_COLOR:
    130       factor = constant;
    131       return;
    132    case 12: // GL_ONE_MINUS_CONSTANT_COLOR:
    133       factor = one;
    134       factor -= constant;
    135       return;
    136    case 13: // GL_CONSTANT_ALPHA:
    137       factor = constantA;
    138       return;
    139    case 14: // GL_ONE_MINUS_CONSTANT_ALPHA:
    140       factor = sOne - constantA;
    141       return;
    142    default:
    143       assert(0);
    144       return;
    145    }
    146 }
    147 
    148 unsigned char StencilOp(const unsigned op, unsigned char s, const unsigned char ref)
    149 {
    150    switch (op) {
    151    case 0: // GL_ZERO
    152       return 0;
    153    case 1: // GL_KEEP
    154       return s;
    155    case 2: // GL_REPLACE
    156       return ref;
    157    case 3: // GL_INCR
    158       if (s < 255)
    159          return ++s;
    160       return s;
    161    case 4: // GL_DECR
    162       if (s > 0)
    163          return --s;
    164       return 0;
    165    case 5: // GL_INVERT
    166       return ~s;
    167    case 6: // GL_INCR_WRAP
    168       return ++s;
    169    case 7: // GL_DECR_WRAP
    170       return --s;
    171    default:
    172       assert(0);
    173       return s;
    174    }
    175 }
    176 
    177 #endif // #if !USE_LLVM_SCANLINE
    178 
    179 #ifdef USE_LLVM_SCANLINE
    180 typedef void (* ScanLineFunction_t)(VertexOutput * start, VertexOutput * step,
    181                                     const float (*constants)[4], void * frame,
    182                                     int * depth, unsigned char * stencil,
    183                                     GGLActiveStencil *, unsigned count);
    184 #endif
    185 
    186 void GGLScanLine(const gl_shader_program * program, const GGLPixelFormat colorFormat,
    187                  void * frameBuffer, int * depthBuffer, unsigned char * stencilBuffer,
    188                  unsigned bufferWidth, unsigned bufferHeight, GGLActiveStencil * activeStencil,
    189                  const VertexOutput_t * start, const VertexOutput_t * end, const float (*constants)[4])
    190 {
    191 #if !USE_LLVM_SCANLINE
    192    assert(!"only for USE_LLVM_SCANLINE");
    193 #endif
    194 
    195 //   LOGD("pf2: GGLScanLine program=%p format=0x%.2X frameBuffer=%p depthBuffer=%p stencilBuffer=%p ",
    196 //      program, colorFormat, frameBuffer, depthBuffer, stencilBuffer);
    197 
    198    const unsigned int varyingCount = program->VaryingSlots;
    199    const unsigned y = start->position.y, startX = start->position.x,
    200                       endX = end->position.x;
    201 
    202    assert(bufferWidth > startX && bufferWidth > endX);
    203    assert(bufferHeight > y);
    204 
    205    char * frame = (char *)frameBuffer;
    206    if (GGL_PIXEL_FORMAT_RGBA_8888 == colorFormat)
    207       frame += (y * bufferWidth + startX) * 4;
    208    else if (GGL_PIXEL_FORMAT_RGB_565 == colorFormat)
    209       frame += (y * bufferWidth + startX) * 2;
    210    else
    211       assert(0);
    212    const VectorComp_t div = VectorComp_t_CTR(1 / (float)(endX - startX));
    213 
    214    //memcpy(ctx->glCtx->CurrentProgram->ValuesVertexOutput, start, sizeof(*start));
    215    // shader symbols are mapped to gl_shader_program_Values*
    216    //VertexOutput & vertex(*(VertexOutput*)ctx->glCtx->CurrentProgram->ValuesVertexOutput);
    217    VertexOutput vertex(*start);
    218    VertexOutput vertexDx(*end);
    219 
    220    vertexDx.position -= start->position;
    221    vertexDx.position *= div;
    222    //printf("vertexDx.position.z=%.8g \n", vertexDx.position.z);
    223    for (unsigned i = 0; i < varyingCount; i++) {
    224       vertexDx.varyings[i] -= start->varyings[i];
    225       vertexDx.varyings[i] *= div;
    226    }
    227    vertexDx.frontFacingPointCoord -= start->frontFacingPointCoord;
    228    vertexDx.frontFacingPointCoord *= div; // gl_PointCoord, only zw
    229    vertexDx.frontFacingPointCoord.y = 0; // gl_FrontFacing not interpolated
    230 
    231    int * depth = depthBuffer + y * bufferWidth + startX;
    232    unsigned char * stencil = stencilBuffer + y * bufferWidth + startX;
    233 
    234    // TODO DXL consider inverting gl_FragCoord.y
    235    ScanLineFunction_t scanLineFunction = (ScanLineFunction_t)
    236                                          program->_LinkedShaders[MESA_SHADER_FRAGMENT]->function;
    237 //   LOGD("pf2 GGLScanLine scanline=%p start=%p constants=%p", scanLineFunction, &vertex, constants);
    238    if (endX >= startX)
    239       scanLineFunction(&vertex, &vertexDx, constants, frame, depth, stencil, activeStencil, endX - startX + 1);
    240 
    241 //   LOGD("pf2: GGLScanLine end");
    242 
    243 }
    244 
    245 template <bool StencilTest, bool DepthTest, bool DepthWrite, bool BlendEnable>
    246 void ScanLine(const GGLInterface * iface, const VertexOutput * start, const VertexOutput * end)
    247 {
    248    GGL_GET_CONST_CONTEXT(ctx, iface);
    249    GGLScanLine(ctx->CurrentProgram, ctx->frameSurface.format, ctx->frameSurface.data,
    250                (int *)ctx->depthSurface.data, (unsigned char *)ctx->stencilSurface.data,
    251                ctx->frameSurface.width, ctx->frameSurface.height, &ctx->activeStencil,
    252                start, end, ctx->CurrentProgram->ValuesUniform);
    253 //   GGL_GET_CONST_CONTEXT(ctx, iface);
    254 //   //    assert((unsigned)start->position.y == (unsigned)end->position.y);
    255 //   //
    256 //   //    assert(GGL_PIXEL_FORMAT_RGBA_8888 == ctx->frameSurface.format);
    257 //   //    assert(GGL_PIXEL_FORMAT_Z_32 == ctx->depthSurface.format);
    258 //   //    assert(ctx->frameSurface.width == ctx->depthSurface.width);
    259 //   //    assert(ctx->frameSurface.height == ctx->depthSurface.height);
    260 //
    261 //   const unsigned int varyingCount = ctx->glCtx->CurrentProgram->VaryingSlots;
    262 //   const unsigned y = start->position.y, startX = start->position.x,
    263 //                      endX = end->position.x;
    264 //
    265 //   //assert(ctx->frameSurface.width > startX && ctx->frameSurface.width > endX);
    266 //   //assert(ctx->frameSurface.height > y);
    267 //
    268 //   unsigned * frame = (unsigned *)ctx->frameSurface.data
    269 //                      + y * ctx->frameSurface.width + startX;
    270 //   const VectorComp_t div = VectorComp_t_CTR(1 / (float)(endX - startX));
    271 //
    272 //   //memcpy(ctx->glCtx->CurrentProgram->ValuesVertexOutput, start, sizeof(*start));
    273 //   // shader symbols are mapped to gl_shader_program_Values*
    274 //   //VertexOutput & vertex(*(VertexOutput*)ctx->glCtx->CurrentProgram->ValuesVertexOutput);
    275 //   VertexOutput vertex(*start);
    276 //   VertexOutput vertexDx(*end);
    277 //
    278 //   vertexDx.position -= start->position;
    279 //   vertexDx.position *= div;
    280 //   //printf("vertexDx.position.z=%.8g \n", vertexDx.position.z);
    281 //   for (unsigned i = 0; i < varyingCount; i++) {
    282 //      vertexDx.varyings[i] -= start->varyings[i];
    283 //      vertexDx.varyings[i] *= div;
    284 //   }
    285 //   vertexDx.frontFacingPointCoord -= start->frontFacingPointCoord;
    286 //   vertexDx.frontFacingPointCoord *= div; // gl_PointCoord, only zw
    287 //   vertexDx.frontFacingPointCoord.y = 0; // gl_FrontFacing not interpolated
    288 //
    289 //#if USE_FORCED_FIXEDPOINT
    290 //   for (unsigned j = 0; j < 4; j++) {
    291 //      for (unsigned i = 0; i < varyingCount; i++) {
    292 //         vertex.varyings[i].i[j] = vertex.varyings[i].f[j] * 65536;
    293 //         vertexDx.varyings[i].i[j] = vertexDx.varyings[i].f[j] * 65536;
    294 //      }
    295 //      vertex.position.i[j] = vertex.position.f[j] * 65536;
    296 //      vertexDx.position.i[j] = vertexDx.position.f[j] * 65536;
    297 //      vertex.frontFacingPointCoord.i[j] = vertex.frontFacingPointCoord.f[j] * 65536;
    298 //   }
    299 //#endif
    300 //
    301 //   int * depth = (int *)ctx->depthSurface.data + y * ctx->frameSurface.width + startX;
    302 //   unsigned char * stencil = (unsigned char *)ctx->stencilSurface.data + y * ctx->frameSurface.width + startX;
    303 //
    304 //#if !USE_LLVM_TEXTURE_SAMPLER
    305 //   extern const GGLContext * textureGGLContext;
    306 //   textureGGLContext = ctx;
    307 //#endif
    308 //
    309 //   // TODO DXL consider inverting gl_FragCoord.y
    310 //
    311 //#if USE_LLVM_SCANLINE
    312 //   ScanLineFunction_t scanLineFunction = (ScanLineFunction_t)
    313 //                                         ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function;
    314 //   if (endX >= startX) {
    315 //      scanLineFunction(&vertex, &vertexDx, ctx->glCtx->CurrentProgram->ValuesUniform, frame, depth, stencil, &ctx->activeStencil, endX - startX + 1);
    316 //   }
    317 //#else
    318 //
    319 //   int z;
    320 //   bool sCmp = true; // default passed, unless failed by stencil test
    321 //   unsigned char s; // masked stored stencil value
    322 //   const unsigned char sMask = ctx->activeStencil.mask;
    323 //   const unsigned char sRef = ctx->activeStencil.ref;
    324 //   const unsigned sFunc = ctx->activeStencil.face ? 0x200 | ctx->backStencil.func :
    325 //                          0x200 | ctx->frontStencil.func;
    326 //   const unsigned ssFail = ctx->activeStencil.face ? ctx->backStencil.sFail :
    327 //                           ctx->frontStencil.sFail;
    328 //   const unsigned sdFail = ctx->activeStencil.face ? ctx->backStencil.dFail :
    329 //                           ctx->frontStencil.dFail;
    330 //   const unsigned sdPass = ctx->activeStencil.face ? ctx->backStencil.dPass :
    331 //                           ctx->frontStencil.dPass;
    332 //
    333 //   for (unsigned x = startX; x <= endX; x++) {
    334 //      //assert(abs((int)(vertex.position.x) - (int)x) < 2);
    335 //      //assert((unsigned)vertex.position.y == y);
    336 //      if (StencilTest) {
    337 //         s = *stencil & sMask;
    338 //         switch (sFunc) {
    339 //         case GL_NEVER:
    340 //            sCmp = false;
    341 //            break;
    342 //         case GL_LESS:
    343 //            sCmp = sRef < s;
    344 //            break;
    345 //         case GL_EQUAL:
    346 //            sCmp = sRef == s;
    347 //            break;
    348 //         case GL_LEQUAL:
    349 //            sCmp = sRef <= s;
    350 //            break;
    351 //         case GL_GREATER:
    352 //            sCmp = sRef > s;
    353 //            break;
    354 //         case GL_NOTEQUAL:
    355 //            sCmp = sRef != s;
    356 //            break;
    357 //         case GL_GEQUAL:
    358 //            sCmp = sRef >= s;
    359 //            break;
    360 //         case GL_ALWAYS:
    361 //            sCmp = true;
    362 //            break;
    363 //         default:
    364 //            assert(0);
    365 //            break;
    366 //         }
    367 //      }
    368 //
    369 //      if (!StencilTest || sCmp) {
    370 //         z = vertex.position.i[2];
    371 //         if (z & 0x80000000)  // negative float has leading 1
    372 //            z ^= 0x7fffffff;  // bigger negative is smaller
    373 //         bool zCmp = true;
    374 //         if (DepthTest) {
    375 //            switch (0x200 | ctx->state.bufferState.depthFunc) {
    376 //            case GL_NEVER:
    377 //               zCmp = false;
    378 //               break;
    379 //            case GL_LESS:
    380 //               zCmp = z < *depth;
    381 //               break;
    382 //            case GL_EQUAL:
    383 //               zCmp = z == *depth;
    384 //               break;
    385 //            case GL_LEQUAL:
    386 //               zCmp = z <= *depth;
    387 //               break;
    388 //            case GL_GREATER:
    389 //               zCmp = z > *depth;
    390 //               break;
    391 //            case GL_NOTEQUAL:
    392 //               zCmp = z != *depth;
    393 //               break;
    394 //            case GL_GEQUAL:
    395 //               zCmp = z >= *depth;
    396 //               break;
    397 //            case GL_ALWAYS:
    398 //               zCmp = true;
    399 //               break;
    400 //            default:
    401 //               assert(0);
    402 //               break;
    403 //            }
    404 //         }
    405 //         if (!DepthTest || zCmp) {
    406 //            float * varying = (float *)ctx->glCtx->CurrentProgram->ValuesVertexOutput;
    407 //            ShaderFunction_t function = (ShaderFunction_t)ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function;
    408 //            function(&vertex, &vertex, ctx->glCtx->CurrentProgram->ValuesUniform);
    409 //            //ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->function();
    410 //            if (BlendEnable) {
    411 //               BlendComp_t sOne = 255, sZero = 0;
    412 //               Vec4<BlendComp_t> one = sOne, zero = sZero;
    413 //
    414 //               Vec4<BlendComp_t> src;
    415 ////                    if (outputRegDesc.IsInt32Color())
    416 ////                        RGBAIntToRGBAIntx4(vertex.fragColor[0].u[0], &src);
    417 ////                    else if (outputRegDesc.IsVectorType(Float))
    418 //               RGBAFloatx4ToRGBAIntx4(&vertex.fragColor[0], &src);
    419 ////                    else if (outputRegDesc.IsVectorType(Fixed8))
    420 ////                    {
    421 ////                        src.u[0] = vertex.fragColor[0].u[0];
    422 ////                        src.u[1] = vertex.fragColor[0].u[1];
    423 ////                        src.u[2] = vertex.fragColor[0].u[2];
    424 ////                        src.u[3] = vertex.fragColor[0].u[3];
    425 ////                    }
    426 ////                    else
    427 ////                        assert(0);
    428 //
    429 //               Vec4<BlendComp_t> dst;
    430 //               unsigned dc = *frame;
    431 //               dst.r = dc & 255;
    432 //               dst.g = (dc >>= 8) & 255;
    433 //               dst.b = (dc >>= 8) & 255;
    434 //               dst.a = (dc >>= 8) & 255;
    435 //
    436 //               Vec4<BlendComp_t> sf, df;
    437 //               Vec4<BlendComp_t> blendStateColor(ctx->state.blendState.color[0], ctx->state.blendState.color[1],
    438 //                                                 ctx->state.blendState.color[2], ctx->state.blendState.color[3]);
    439 //
    440 //               BlendFactor(ctx->state.blendState.scf, sf, src, dst,
    441 //                           blendStateColor, one, zero, src.a, dst.a,
    442 //                           blendStateColor.a, sOne);
    443 //               if (ctx->state.blendState.scf != ctx->state.blendState.saf)
    444 //                  BlendFactor(ctx->state.blendState.saf, sf.a, src.a, dst.a,
    445 //                              blendStateColor.a, sOne, sZero, src.a, dst.a,
    446 //                              blendStateColor.a, sOne);
    447 //               BlendFactor(ctx->state.blendState.dcf, df, src, dst,
    448 //                           blendStateColor, one, zero, src.a, dst.a,
    449 //                           blendStateColor.a, sOne);
    450 //               if (ctx->state.blendState.dcf != ctx->state.blendState.daf)
    451 //                  BlendFactor(ctx->state.blendState.daf, df.a, src.a, dst.a,
    452 //                              blendStateColor.a, sOne, sZero, src.a, dst.a,
    453 //                              blendStateColor.a, sOne);
    454 //
    455 //               Vec4<BlendComp_t> sfs(sf), dfs(df);
    456 //               sfs.LShr(7);
    457 //               sf += sfs;
    458 //               dfs.LShr(7);
    459 //               df += dfs;
    460 //
    461 //               src *= sf;
    462 //               dst *= df;
    463 //               Vec4<BlendComp_t> res(src);
    464 //               switch (ctx->state.blendState.ce + GL_FUNC_ADD) {
    465 //               case GL_FUNC_ADD:
    466 //                  res += dst;
    467 //                  break;
    468 //               case GL_FUNC_SUBTRACT:
    469 //                  res -= dst;
    470 //                  break;
    471 //               case GL_FUNC_REVERSE_SUBTRACT:
    472 //                  res = dst;
    473 //                  res -= src;
    474 //                  break;
    475 //               default:
    476 //                  assert(0);
    477 //                  break;
    478 //               }
    479 //               if (ctx->state.blendState.ce != ctx->state.blendState.ae)
    480 //                  switch (ctx->state.blendState.ce + GL_FUNC_ADD) {
    481 //                  case GL_FUNC_ADD:
    482 //                     res.a = src.a + dst.a;
    483 //                     break;
    484 //                  case GL_FUNC_SUBTRACT:
    485 //                     res.a = src.a - dst.a;
    486 //                     break;
    487 //                  case GL_FUNC_REVERSE_SUBTRACT:
    488 //                     res.a = dst.a - src.a;
    489 //                     break;
    490 //                  default:
    491 //                     assert(0);
    492 //                     break;
    493 //                  }
    494 //
    495 //               res.AShr(8);
    496 //               Saturate(&res);
    497 //               *frame = RGBAIntx4ToRGBAInt(&res);
    498 //            } else {
    499 ////                    if (outputRegDesc.IsInt32Color())
    500 ////                        *frame = vertex.fragColor[0].u[0];
    501 ////                    else if (outputRegDesc.IsVectorType(Float))
    502 //               {
    503 //                  Vec4<BlendComp_t> src;
    504 //                  RGBAFloatx4ToRGBAIntx4(&vertex.fragColor[0], &src);
    505 //                  Saturate(&src);
    506 //                  *frame = RGBAIntx4ToRGBAInt(&src);
    507 //               }
    508 ////                    else if (outputRegDesc.IsVectorType(Fixed16))
    509 ////                    {
    510 ////                        Vec4<BlendComp_t> & src = (Vec4<BlendComp_t> &)vertex.fragColor[0];
    511 ////                        src.r = (src.r * 255 >> 16);
    512 ////                        src.g = (src.g * 255 >> 16);
    513 ////                        src.b = (src.b * 255 >> 16);
    514 ////                        src.a = (src.a * 255 >> 16);
    515 ////                        Saturate(&src);
    516 ////                        *frame = RGBAIntx4ToRGBAInt(&src);
    517 ////                    }
    518 ////                    else if (outputRegDesc.IsVectorType(Fixed8))
    519 ////                    {
    520 ////                        Vec4<BlendComp_t> & src = (Vec4<BlendComp_t> &)vertex.fragColor[0];
    521 ////                        Saturate(&src);
    522 ////                        *frame = RGBAIntx4ToRGBAInt(&src);
    523 ////                    }
    524 ////                    else
    525 ////                        assert(0);
    526 //            }
    527 //
    528 //            if (DepthWrite)
    529 //               *depth = z;
    530 //            if (StencilTest)
    531 //               *stencil = StencilOp(sdPass, s, sRef);
    532 //         } else if (StencilTest)
    533 //            *stencil = StencilOp(sdFail, s, sRef);
    534 //      } else if (StencilTest)
    535 //         *stencil = StencilOp(ssFail, s, sRef);
    536 //
    537 //      frame++;
    538 //      depth++;
    539 //      stencil++;
    540 //
    541 //#if USE_FORCED_FIXEDPOINT
    542 //      for (unsigned j = 0; j < 4; j++) {
    543 //         if (ctx->glCtx->Shader.CurrentProgram->FragmentProgram->UsesFragCoord)
    544 //            vertex.position.i[j] += vertexDx.position.i[j];
    545 //         for (unsigned i = 0; i < varyingCount; i++)
    546 //            vertex.varyings[i].i[j] += vertexDx.varyings[i].i[j];
    547 //      }
    548 //      vertex.position.i[2] += vertexDx.position.i[2];
    549 //      if (ctx->glCtx->Shader.CurrentProgram->FragmentProgram->UsesPointCoord) {
    550 //         vertex.frontFacingPointCoord.i[2] = vertexDx.frontFacingPointCoord.i[2];
    551 //         vertex.frontFacingPointCoord.i[3] = vertexDx.frontFacingPointCoord.i[3];
    552 //      }
    553 //#else
    554 //   if (ctx->glCtx->CurrentProgram->UsesFragCoord)
    555 //      vertex.position += vertexDx.position;
    556 //   else if (ctx->state.bufferState.depthTest)
    557 //      vertex.position.z += vertexDx.position.z;
    558 //
    559 //   for (unsigned i = 0; i < varyingCount; i++)
    560 //      vertex.varyings[i] += vertexDx.varyings[i];
    561 //   if (ctx->glCtx->CurrentProgram->UsesPointCoord) {
    562 //      vertex.frontFacingPointCoord.z += vertexDx.frontFacingPointCoord.z;
    563 //      vertex.frontFacingPointCoord.w += vertexDx.frontFacingPointCoord.w;
    564 //   }
    565 //#endif // #if USE_FORCED_FIXEDPOINT
    566 //   }
    567 //
    568 //#endif // #if USE_LLVM_SCANLINE
    569 //
    570 //#if !USE_LLVM_TEXTURE_SAMPLER
    571 //   textureGGLContext = NULL;
    572 //#endif
    573 }
    574 
    575 static void PickScanLine(GGLInterface * iface)
    576 {
    577    GGL_GET_CONTEXT(ctx, iface);
    578 
    579    ctx->interface.ScanLine = NULL;
    580    if (ctx->state.bufferState.stencilTest) {
    581       if (ctx->state.bufferState.depthTest) {
    582          if (ctx->state.blendState.enable)
    583             ctx->interface.ScanLine = ScanLine<true, true, true, true>;
    584          else
    585             ctx->interface.ScanLine = ScanLine<true, true, true, false>;
    586       } else {
    587          if (ctx->state.blendState.enable)
    588             ctx->interface.ScanLine = ScanLine<true, false, false, true>;
    589          else
    590             ctx->interface.ScanLine = ScanLine<true, false, false, false>;
    591       }
    592    } else {
    593       if (ctx->state.bufferState.depthTest) {
    594          if (ctx->state.blendState.enable)
    595             ctx->interface.ScanLine = ScanLine<false, true, true, true>;
    596          else
    597             ctx->interface.ScanLine = ScanLine<false, true, true, false>;
    598       } else {
    599          if (ctx->state.blendState.enable)
    600             ctx->interface.ScanLine = ScanLine<false, false, false, true>;
    601          else
    602             ctx->interface.ScanLine = ScanLine<false, false, false, false>;
    603       }
    604    }
    605 
    606    assert(ctx->interface.ScanLine);
    607 }
    608 
    609 void InitializeScanLineFunctions(GGLInterface * iface)
    610 {
    611    GGL_GET_CONTEXT(ctx, iface);
    612    ctx->PickScanLine = PickScanLine;
    613 }
    614