scanline.cpp revision a5ca04aebd1a0df7c52e170252cf3c2f3ee3e8a2
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
28static 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
36static inline void RGBAIntToRGBAIntx4(unsigned rgba, Vec4<BlendComp_t> * color) __attribute__((always_inline));
37static 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
45static 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
53static inline unsigned RGBAIntx4ToRGBAInt(const Vec4<BlendComp_t> * color);
54static 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
82template<typename T>
83static 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));
87template<typename T>
88static 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
148unsigned 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
180typedef 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
186void 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//   ALOGD("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//   ALOGD("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//   ALOGD("pf2: GGLScanLine end");
242
243}
244
245template <bool StencilTest, bool DepthTest, bool DepthWrite, bool BlendEnable>
246void 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
575static 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
609void InitializeScanLineFunctions(GGLInterface * iface)
610{
611   GGL_GET_CONTEXT(ctx, iface);
612   ctx->PickScanLine = PickScanLine;
613}
614