• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Saturate(Vec4<BlendComp_t> * color)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));
RGBAIntToRGBAIntx4(unsigned rgba,Vec4<BlendComp_t> * color)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 
RGBAFloatx4ToRGBAIntx4(Vector4 * v,Vec4<BlendComp_t> * color)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);
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>
BlendFactor(const unsigned mode,T & factor,const T & src,const T & dst,const T & constant,const T & one,const T & zero,const BlendComp_t & srcA,const BlendComp_t & dstA,const BlendComp_t & constantA,const BlendComp_t & sOne)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 
StencilOp(const unsigned op,unsigned char s,const unsigned char ref)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 
GGLScanLine(const gl_shader_program * program,const GGLPixelFormat colorFormat,void * frameBuffer,int * depthBuffer,unsigned char * stencilBuffer,unsigned bufferWidth,unsigned bufferHeight,GGLActiveStencil * activeStencil,const VertexOutput_t * start,const VertexOutput_t * end,const float (* constants)[4])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 //   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 
245 template <bool StencilTest, bool DepthTest, bool DepthWrite, bool BlendEnable>
ScanLine(const GGLInterface * iface,const VertexOutput * start,const VertexOutput * end)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 
PickScanLine(GGLInterface * iface)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 
InitializeScanLineFunctions(GGLInterface * iface)609 void InitializeScanLineFunctions(GGLInterface * iface)
610 {
611    GGL_GET_CONTEXT(ctx, iface);
612    ctx->PickScanLine = PickScanLine;
613 }
614