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 <stdlib.h> 19 #include <math.h> 20 #include <string.h> 21 #include <stdio.h> 22 23 #include "pixelflinger2.h" 24 #include "src/mesa/main/mtypes.h" 25 #include "src/mesa/program/prog_parameter.h" 26 #include "src/mesa/program/prog_uniform.h" 27 #include "src/glsl/glsl_types.h" 28 29 //#undef LOGD 30 //#define LOGD(...) 31 32 static inline void LerpVector4(const Vector4 * a, const Vector4 * b, 33 const VectorComp_t x, Vector4 * d) __attribute__((always_inline)); 34 static inline void LerpVector4(const Vector4 * a, const Vector4 * b, 35 const VectorComp_t x, Vector4 * d) 36 { 37 assert(a != d && b != d); 38 //d = (b - a) * x + a; 39 (*d) = (*b); 40 (*d) -= (*a); 41 (*d) *= x; 42 (*d) += (*a); 43 } 44 45 static inline void InterpolateVertex(const VertexOutput * a, const VertexOutput * b, const VectorComp_t x, 46 VertexOutput * v, const unsigned varyingCount) 47 { 48 LerpVector4(&a->position, &b->position, x, &v->position); 49 for (unsigned i = 0; i < varyingCount; i++) 50 LerpVector4(a->varyings + i, b->varyings + i, x, v->varyings + i); 51 LerpVector4(&a->frontFacingPointCoord, &b->frontFacingPointCoord, 52 x, &v->frontFacingPointCoord); // gl_PointCoord 53 v->frontFacingPointCoord.y = a->frontFacingPointCoord.y; // gl_FrontFacing not interpolated 54 55 } 56 57 void GGLProcessVertex(const gl_shader_program * program, const VertexInput * input, 58 VertexOutput * output, const float (*constants)[4]) 59 { 60 ShaderFunction_t function = (ShaderFunction_t)program->_LinkedShaders[MESA_SHADER_VERTEX]->function; 61 function(input, output, constants); 62 } 63 64 static void ProcessVertex(const GGLInterface * iface, const VertexInput * input, 65 VertexOutput * output) 66 { 67 GGL_GET_CONST_CONTEXT(ctx, iface); 68 69 //#if !USE_LLVM_TEXTURE_SAMPLER 70 // extern const GGLContext * textureGGLContext; 71 // textureGGLContext = ctx; 72 //#endif 73 // 74 75 // memcpy(ctx->glCtx->CurrentProgram->ValuesVertexInput, input, sizeof(*input)); 76 // ctx->glCtx->CurrentProgram->_LinkedShaders[MESA_SHADER_VERTEX]->function(); 77 // memcpy(output, ctx->glCtx->CurrentProgram->ValuesVertexOutput, sizeof(*output)); 78 79 GGLProcessVertex(ctx->CurrentProgram, input, output, ctx->CurrentProgram->ValuesUniform); 80 // const Vector4 * constants = (Vector4 *) 81 // ctx->glCtx->Shader.CurrentProgram->VertexProgram->Parameters->ParameterValues; 82 // ctx->glCtx->Shader.CurrentProgram->GLVMVP->function(input, output, constants); 83 // 84 //#if !USE_LLVM_TEXTURE_SAMPLER 85 // textureGGLContext = NULL; 86 //#endif 87 } 88 89 #if USE_DUAL_THREAD 90 static void * RasterTrapezoidWorker(void * threadArgs) 91 { 92 GGLContext::Worker * args = (GGLContext::Worker *)threadArgs; 93 VertexOutput clip0, clip1, * left, * right; 94 95 pthread_mutex_lock(&args->finishLock); 96 pthread_mutex_lock(&args->assignLock); 97 pthread_cond_signal(&args->finishCond); 98 pthread_mutex_unlock(&args->finishLock); 99 100 while (true) { 101 pthread_cond_wait(&args->assignCond, &args->assignLock); 102 if (args->quit) 103 { 104 pthread_mutex_unlock(&args->assignLock); 105 break; 106 } 107 else 108 assert(args->assignedWork); 109 110 for (unsigned y = args->startY; y <= args->endY; y += 2) { 111 do { 112 if (args->bV.position.x < 0) { 113 if (args->cV.position.x < 0) 114 break; 115 InterpolateVertex(&args->bV, &args->cV, -args->bV.position.x / 116 (args->cV.position.x - args->bV.position.x), 117 &clip0, args->varyingCount); 118 left = &clip0; 119 } else 120 left = &args->bV; 121 if ((int)args->cV.position.x >= (int)args->width) { 122 if (args->bV.position.x >= (int)args->width) 123 break; 124 InterpolateVertex(&args->bV, &args->cV, (args->width - 1 - args->bV.position.x) / 125 (args->cV.position.x - args->bV.position.x), 126 &clip1, args->varyingCount); 127 right = &clip1; 128 } else 129 right = &args->cV; 130 args->iface->ScanLine(args->iface, left, right); 131 } while (false); 132 for (unsigned i = 0; i < args->varyingCount; i++) { 133 args->bV.varyings[i] += args->bDx.varyings[i]; 134 args->cV.varyings[i] += args->cDx.varyings[i]; 135 } 136 args->bV.position += args->bDx.position; 137 args->cV.position += args->cDx.position; 138 args->bV.frontFacingPointCoord += args->bDx.frontFacingPointCoord; 139 args->cV.frontFacingPointCoord += args->cDx.frontFacingPointCoord; 140 } 141 142 pthread_mutex_lock(&args->finishLock); 143 pthread_cond_signal(&args->finishCond); 144 pthread_mutex_unlock(&args->finishLock); 145 } 146 pthread_exit(NULL); 147 return NULL; 148 } 149 #endif 150 151 static void RasterTrapezoid(const GGLInterface * iface, const VertexOutput * tl, 152 const VertexOutput * tr, const VertexOutput * bl, 153 const VertexOutput * br) 154 { 155 GGL_GET_CONST_CONTEXT(ctx, iface); 156 157 assert(tl->position.x <= tr->position.x && bl->position.x <= br->position.x); 158 assert(tl->position.y <= bl->position.y && tr->position.y <= br->position.y); 159 assert(fabs(tl->position.y - tr->position.y) < 1 && fabs(bl->position.y - br->position.y) < 1); 160 161 const unsigned width = ctx->frameSurface.width, height = ctx->frameSurface.height; 162 const unsigned varyingCount = ctx->CurrentProgram->VaryingSlots; 163 164 165 // tlv-trv and blv-brv are parallel and horizontal 166 VertexOutput tlv(*tl), trv(*tr), blv(*bl), brv(*br); 167 VertexOutput tmp; 168 169 // vertically clip 170 171 if ((int)tlv.position.y < 0) { 172 InterpolateVertex(&tlv, &blv, (0 - tlv.position.y) / (blv.position.y - tlv.position.y), 173 &tmp, varyingCount); 174 tlv = tmp; 175 } 176 if ((int)trv.position.y < 0) { 177 InterpolateVertex(&trv, &brv, (0 - trv.position.y) / (brv.position.y - trv.position.y), 178 &tmp, varyingCount); 179 trv = tmp; 180 } 181 if ((int)blv.position.y >= (int)height) { 182 InterpolateVertex(&tlv, &blv, (height - 1 - tlv.position.y) / (blv.position.y - tlv.position.y), 183 &tmp, varyingCount); 184 blv = tmp; 185 } 186 if ((int)brv.position.y >= (int)height) { 187 InterpolateVertex(&trv, &brv, (height - 1 - trv.position.y) / (brv.position.y - trv.position.y), 188 &tmp, varyingCount); 189 brv = tmp; 190 } 191 192 // // horizontally clip 193 // if ((int)tlv.position.x < 0) { 194 // InterpolateVertex(&tlv, &trv, (0 - tlv.position.x) / (trv.position.x - tlv.position.x), 195 // &tmp, varyingCount); 196 // tlv = tmp; 197 // } 198 // if ((int)blv.position.x < 0) { 199 // InterpolateVertex(&blv, &brv, (0 - blv.position.x) / (brv.position.x - blv.position.x), 200 // &tmp, varyingCount); 201 // blv = tmp; 202 // } 203 // if ((int)trv.position.x >= (int)width) { 204 // InterpolateVertex(&tlv, &trv, (width - 1 - tlv.position.x) / (trv.position.x - tlv.position.x), 205 // &tmp, varyingCount); 206 // trv = tmp; 207 // } 208 // if ((int)brv.position.x >= (int)width) { 209 // InterpolateVertex(&blv, &brv, (width - 1 - blv.position.x) / (brv.position.x - blv.position.x), 210 // &tmp, varyingCount); 211 // brv = tmp; 212 // } 213 214 const unsigned int startY = tlv.position.y; 215 const unsigned int endY = blv.position.y; 216 217 if (endY < startY) 218 return; 219 220 const VectorComp_t yDistInv = VectorComp_t_CTR(1.0f / (endY - startY)); 221 222 // bV and cV are left and right vertices on a horizontal line in quad 223 // bDx and cDx are iterators from tlv to blv, trv to brv for bV and cV 224 225 VertexOutput bV(tlv), cV(trv); 226 VertexOutput bDx(blv), cDx(brv); 227 228 for (unsigned i = 0; i < varyingCount; i++) { 229 bDx.varyings[i] -= tlv.varyings[i]; 230 bDx.varyings[i] *= yDistInv; 231 232 cDx.varyings[i] -= trv.varyings[i]; 233 cDx.varyings[i] *= yDistInv; 234 } 235 236 bDx.position -= tlv.position; 237 bDx.position *= yDistInv; 238 239 cDx.position -= trv.position; 240 cDx.position *= yDistInv; 241 242 bDx.frontFacingPointCoord -= tlv.frontFacingPointCoord; // gl_PointCoord 243 bDx.frontFacingPointCoord *= yDistInv; 244 bDx.frontFacingPointCoord.y = VectorComp_t_Zero; // gl_FrontFacing not interpolated 245 cDx.frontFacingPointCoord -= trv.frontFacingPointCoord; // gl_PointCoord 246 cDx.frontFacingPointCoord *= yDistInv; 247 cDx.frontFacingPointCoord.y = VectorComp_t_Zero; // gl_FrontFacing not interpolated 248 249 #if USE_DUAL_THREAD 250 GGLContext::Worker & args = ctx->worker; 251 if (!ctx->worker.thread) { 252 pthread_attr_t attr; 253 pthread_attr_init(&attr); 254 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 255 int rc = pthread_create(&ctx->worker.thread, &attr, RasterTrapezoidWorker, &args); 256 assert(!rc); 257 // wait for worker to start 258 pthread_cond_wait(&args.finishCond, &args.finishLock); 259 } 260 args.startY = startY + 1; 261 args.endY = endY; 262 if (args.startY <= args.endY) { 263 pthread_mutex_lock(&args.assignLock); 264 265 args.bV = bV; 266 args.cV = cV; 267 for (unsigned i = 0; i < varyingCount; i++) { 268 args.bV.varyings[i] += bDx.varyings[i]; 269 bDx.varyings[i] += bDx.varyings[i]; 270 args.cV.varyings[i] += cDx.varyings[i]; 271 cDx.varyings[i] += cDx.varyings[i]; 272 } 273 args.bV.position += bDx.position; 274 bDx.position += bDx.position; 275 args.cV.position += cDx.position; 276 cDx.position += cDx.position; 277 args.bV.frontFacingPointCoord += bDx.frontFacingPointCoord; 278 bDx.frontFacingPointCoord += bDx.frontFacingPointCoord; 279 args.cV.frontFacingPointCoord += cDx.frontFacingPointCoord; 280 cDx.frontFacingPointCoord += cDx.frontFacingPointCoord; 281 args.iface = iface; 282 args.bDx = bDx; 283 args.cDx = cDx; 284 args.varyingCount = varyingCount; 285 args.width = width; 286 args.height = height; 287 args.assignedWork = true; 288 289 pthread_cond_signal(&args.assignCond); 290 pthread_mutex_unlock(&args.assignLock); 291 } 292 #endif 293 294 VertexOutput * left, * right; 295 VertexOutput clip0, clip1; 296 297 for (unsigned y = startY; y <= endY; y += 1 + USE_DUAL_THREAD) { 298 do { 299 if (bV.position.x < 0) { 300 if (cV.position.x < 0) 301 break; 302 InterpolateVertex(&bV, &cV, -bV.position.x / (cV.position.x - bV.position.x), 303 &clip0, varyingCount); 304 left = &clip0; 305 } else 306 left = &bV; 307 if ((int)cV.position.x >= (int)width) { 308 if (bV.position.x >= (int)width) 309 break; 310 InterpolateVertex(&bV, &cV, (width - 1 - bV.position.x) / (cV.position.x - bV.position.x), 311 &clip1, varyingCount); 312 right = &clip1; 313 } else 314 right = &cV; 315 iface->ScanLine(iface, left, right); 316 } while (false); 317 for (unsigned i = 0; i < varyingCount; i++) { 318 bV.varyings[i] += bDx.varyings[i]; 319 cV.varyings[i] += cDx.varyings[i]; 320 } 321 bV.position += bDx.position; 322 cV.position += cDx.position; 323 bV.frontFacingPointCoord += bDx.frontFacingPointCoord; 324 cV.frontFacingPointCoord += cDx.frontFacingPointCoord; 325 } 326 327 #if USE_DUAL_THREAD 328 if (args.assignedWork) 329 { 330 pthread_cond_wait(&args.finishCond, &args.finishLock); 331 args.assignedWork = false; 332 } 333 #endif 334 } 335 336 static void RasterTriangle(const GGLInterface * iface, const VertexOutput * v1, 337 const VertexOutput * v2, const VertexOutput * v3) 338 { 339 GGL_GET_CONST_CONTEXT(ctx, iface); 340 const unsigned varyingCount = ctx->CurrentProgram->VaryingSlots; 341 const unsigned height = ctx->frameSurface.height; 342 const VertexOutput * a = v1, * b = v2, * d = v3; 343 //abc is a triangle, bcd is another triangle, they share bc as horizontal edge 344 //c is between a and d, xy is screen coord 345 346 //first sort 3 vertices by MIN y first 347 if (v2->position.y < v1->position.y) { 348 a = v2; 349 b = v1; 350 } 351 if (v3->position.y < a->position.y) { 352 d = b; 353 b = a; 354 a = v3; 355 } else if (v3->position.y < b->position.y) { 356 d = b; 357 b = v3; 358 } 359 360 assert(a->position.y <= b->position.y && b->position.y <= d->position.y); 361 362 VertexOutput cVertex; 363 const VertexOutput* c = &cVertex; 364 365 const VectorComp_t cLerp = (b->position.y - a->position.y) / 366 MAX2(VectorComp_t_One, (d->position.y - a->position.y)); 367 // create 4th vertex, same y as b to form two triangles/trapezoids sharing horizontal edge 368 InterpolateVertex(a, d, cLerp, &cVertex, varyingCount); 369 370 if (c->position.x < b->position.x) { 371 const VertexOutput * tmp = c; 372 c = b; 373 b = tmp; 374 } 375 376 if ((int)a->position.y < (int)height && (int)b->position.y >= 0) 377 RasterTrapezoid(iface, a, a, b, c); 378 //b->position.y += VectorComp_t_One; 379 //c->position.y += VectorComp_t_One; 380 if ((int)b->position.y < (int)height && (int)d->position.y >= 0) 381 RasterTrapezoid(iface, b, c, d, d); 382 } 383 384 static void DrawTriangle(const GGLInterface * iface, const VertexInput * vin1, 385 const VertexInput * vin2, const VertexInput * vin3) 386 { 387 GGL_GET_CONST_CONTEXT(ctx, iface); 388 389 VertexOutput vouts[3]; 390 memset(vouts, 0, sizeof(vouts)); 391 VertexOutput * v1 = vouts + 0, * v2 = vouts + 1, * v3 = vouts + 2; 392 393 // LOGD("pf2: DrawTriangle"); 394 395 // if (!strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, 396 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;")) 397 // return; 398 399 // for (unsigned i = 0; i < program->NumShaders; i++) 400 // if (program->Shaders[i]->Source) 401 // LOGD("%s", program->Shaders[i]->Source); 402 403 // if (!strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, ").a;")) 404 // return; 405 406 // LOGD("%s", program->Shaders[MESA_SHADER_VERTEX]->Source); 407 // LOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source); 408 409 // for (unsigned i = 0; i < program->Attributes->NumParameters; i++) { 410 // const gl_program_parameter & attribute = program->Attributes->Parameters[i]; 411 // LOGD("attribute '%s': location=%d slots=%d \n", attribute.Name, attribute.Location, attribute.Slots); 412 // } 413 // for (unsigned i = 0; i < program->Varying->NumParameters; i++) { 414 // const gl_program_parameter & varying = program->Varying->Parameters[i]; 415 // LOGD("varying '%s': vs_location=%d fs_location=%d \n", varying.Name, varying.BindLocation, varying.Location); 416 // } 417 // for (unsigned i = 0; i < program->Uniforms->NumUniforms; i++) { 418 // const gl_uniform & uniform = program->Uniforms->Uniforms[i]; 419 // LOGD("uniform '%s': location=%d type=%s \n", uniform.Name, uniform.Pos, uniform.Type->name); 420 // } 421 422 // __attribute__ ((aligned (16))) 423 // static const float matrix[16] = { 424 // 1,0,0,0, 425 // 0,1,0,0, 426 // 0,0,1,0, 427 // 0,0,0,1 428 // }; 429 // 430 // iface->ShaderUniformMatrix((gl_shader_program *)program, 4, 4, 0, 1, GL_FALSE, matrix); 431 432 iface->ProcessVertex(iface, vin1, v1); 433 iface->ProcessVertex(iface, vin2, v2); 434 iface->ProcessVertex(iface, vin3, v3); 435 436 // __attribute__ ((aligned (16))) 437 // static const float matrix[16] = { 438 // 2,0,0,0, 439 // 0,-2,0,0, 440 // 0,0,-1,0, 441 // -1,1,0,1 442 // }; 443 444 445 // float * matrix = program->ValuesUniform[0]; 446 // for (unsigned i = 0; i < 4; i++) 447 // LOGD("pf2: DrawTriangle %.2f \t %.2f \t %.2f \t %.2f \n", matrix[i * 4 + 0], 448 // matrix[i * 4 + 1], matrix[i * 4 + 2], matrix[i * 4 + 3]); 449 //// LOGD("color %.02f %.02f %.02f %.02f", program->ValuesUniform[4][0], program->ValuesUniform[4][1], 450 //// program->ValuesUniform[4][2], program->ValuesUniform[4][3]); 451 // LOGD("vin1 position %.02f %.02f %.02f %.02f", vin1->attributes[1].x, vin1->attributes[1].y, 452 // vin1->attributes[1].z, vin1->attributes[1].w); 453 // LOGD("vin2 position %.02f %.02f %.02f %.02f", vin2->attributes[1].x, vin2->attributes[1].y, 454 // vin2->attributes[1].z, vin2->attributes[1].w); 455 // LOGD("vin3 position %.02f %.02f %.02f %.02f", vin3->attributes[1].x, vin3->attributes[1].y, 456 // vin3->attributes[1].z, vin3->attributes[1].w); 457 458 // GGLProcessVertex(program, vin1, v1, (const float (*)[4])matrix); 459 // GGLProcessVertex(program, vin2, v2, (const float (*)[4])matrix); 460 // GGLProcessVertex(program, vin3, v3, (const float (*)[4])matrix); 461 462 // LOGD("pf2: DrawTriangle processed %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f", 463 // v1->position.x, v1->position.y, v1->position.z, v1->position.w, 464 // v2->position.x, v2->position.y, v2->position.z, v2->position.w, 465 // v3->position.x, v3->position.y, v3->position.z, v3->position.w); 466 467 v1->position /= v1->position.w; 468 v2->position /= v2->position.w; 469 v3->position /= v3->position.w; 470 471 // LOGD("pf2: DrawTriangle divided %.02f,%.02f \t %.02f,%.02f \t %.02f,%.02f", v1->position.x, v1->position.y, 472 // v2->position.x, v2->position.y, v3->position.x, v3->position.y); 473 474 iface->ViewportTransform(iface, &v1->position); 475 iface->ViewportTransform(iface, &v2->position); 476 iface->ViewportTransform(iface, &v3->position); 477 478 // if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, 479 // "gl_FragColor = color * texture2D(sampler, outTexCoords).a;")) { 480 //// LOGD("%s", program->Shaders[MESA_SHADER_FRAGMENT]->Source); 481 // v1->position = vin1->attributes[0]; 482 // v2->position = vin2->attributes[0]; 483 // v3->position = vin3->attributes[0]; 484 // 485 // v1->varyings[0] = vin1->attributes[1]; 486 // v2->varyings[0] = vin2->attributes[1]; 487 // v3->varyings[0] = vin3->attributes[1]; 488 // } 489 490 // LOGD("pf2: DrawTriangle transformed %.0f,%.0f \t %.0f,%.0f \t %.0f,%.0f", v1->position.x, v1->position.y, 491 // v2->position.x, v2->position.y, v3->position.x, v3->position.y); 492 493 // LOGD("pf2: DrawTriangle varying %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f \t %.02f %.02f %.2f %.2f", 494 // v1->varyings[0].x, v1->varyings[0].y, v1->varyings[0].z, v1->varyings[0].w, 495 // v2->varyings[0].x, v2->varyings[0].y, v2->varyings[0].z, v2->varyings[0].w, 496 // v3->varyings[0].x, v3->varyings[0].y, v3->varyings[0].z, v3->varyings[0].w); 497 498 VectorComp_t area; 499 area = v1->position.x * v2->position.y - v2->position.x * v1->position.y; 500 area += v2->position.x * v3->position.y - v3->position.x * v2->position.y; 501 area += v3->position.x * v1->position.y - v1->position.x * v3->position.y; 502 area *= 0.5f; 503 504 if (GL_CCW == ctx->cullState.frontFace + GL_CW) 505 (unsigned &)area ^= 0x80000000; 506 507 if (false && ctx->cullState.enable) { // TODO: turn off for now 508 switch (ctx->cullState.cullFace + GL_FRONT) { 509 case GL_FRONT: 510 if (!((unsigned &)area & 0x80000000)) // +ve, front facing 511 return; 512 break; 513 case GL_BACK: 514 if ((unsigned &)area & 0x80000000) // -ve, back facing 515 return; 516 break; 517 case GL_FRONT_AND_BACK: 518 return; 519 default: 520 assert(0); 521 } 522 } 523 524 v1->frontFacingPointCoord.y = v2->frontFacingPointCoord.y = 525 v3->frontFacingPointCoord.y = !((unsigned &)area & 0x80000000) ? 526 VectorComp_t_One : VectorComp_t_Zero; 527 528 iface->StencilSelect(iface, ((unsigned &)area & 0x80000000) ? GL_BACK : GL_FRONT); 529 530 // if (0) 531 // { 532 // GGLContext * ctx =(GGLContext *)iface; 533 // for (unsigned sampler = 0; sampler < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; sampler++) 534 // { 535 // if (!((1 << sampler) & ctx->glCtx->Shader.CurrentProgram->FragmentProgram->SamplersUsed)) 536 // continue; 537 // const GGLTexture * texture = ctx->textureState.textures + sampler; 538 // int level = texture->width * texture->height / (area * 2) - 4; 539 // assert(texture->levels); 540 // ctx->textureState.textureData[sampler] = texture->levels[0]; 541 // ctx->textureState.textureDimensions[sampler * 2] = texture->width; 542 // ctx->textureState.textureDimensions[sampler * 2 + 1] = texture->height; 543 // for (unsigned i = 1; i < texture->levelCount && i <= level; i++) 544 // { 545 // ctx->textureState.textureData[sampler] = texture->levels[i]; 546 // ctx->textureState.textureDimensions[sampler * 2] += 1; 547 // ctx->textureState.textureDimensions[sampler * 2] /= 2; 548 // ctx->textureState.textureDimensions[sampler * 2 + 1] += 1; 549 // ctx->textureState.textureDimensions[sampler * 2 + 1] /= 2; 550 // } 551 // } 552 // } 553 554 // TODO DXL view frustum clipping 555 iface->RasterTriangle(iface, v1, v2, v3); 556 557 // LOGD("pf2: DrawTriangle end"); 558 559 } 560 561 static void PickRaster(GGLInterface * iface) 562 { 563 iface->ProcessVertex = ProcessVertex; 564 iface->DrawTriangle = DrawTriangle; 565 iface->RasterTriangle = RasterTriangle; 566 iface->RasterTrapezoid = RasterTrapezoid; 567 } 568 569 static void ViewportTransform(const GGLInterface * iface, Vector4 * v) 570 { 571 GGL_GET_CONST_CONTEXT(ctx, iface); 572 v->x = v->x * ctx->viewport.w + ctx->viewport.x; 573 v->y *= -1; 574 v->y = v->y * ctx->viewport.h + ctx->viewport.y; 575 v->z = v->z * ctx->viewport.f + ctx->viewport.n; 576 } 577 578 579 void InitializeRasterFunctions(GGLInterface * iface) 580 { 581 GGL_GET_CONTEXT(ctx, iface); 582 ctx->PickRaster = PickRaster; 583 iface->ViewportTransform = ViewportTransform; 584 } 585