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// 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 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