📄 scanline.cpp
字号:
for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { texture_t& tmu = c->state.texture[i]; if (!tmu.enable) continue; texture_iterators_t& ti = tmu.iterators; for (int j=0 ; j<2 ; j++) { int32_t v = tc[i].st[j].v; if (span) v += (tmu.shade.st[j].dx)*span; else v += (tmu.shade.st[j].dx)<<SPAN_BITS; const int32_t v0 = tc[i].st[j].q; const int32_t v1 = gglMulx(v, q1, iwscale); int32_t dvdx = v1 - v0; if (span) dvdx /= span; else dvdx >>= SPAN_BITS; tc[i].st[j].v = v; tc[i].st[j].q = v1; const int scale = ti.st[j].scale + (iwscale - 30); if (scale >= 0) { ti.st[j].ydvdy = v0 << scale; ti.st[j].dvdx = dvdx << scale; } else { ti.st[j].ydvdy = v0 >> -scale; ti.st[j].dvdx = dvdx >> -scale; } } generated_tex_vars_t& gen = c->generated_vars.texture[i]; gen.dsdx = ti.st[0].dvdx; gen.dtdx = ti.st[1].dvdx; } c->iterators.xl = xl; c->iterators.xr = xl = xl + (span ? span : (1<<SPAN_BITS)); w0 = w1; q0 = q1; c->span(c); } while(numSpans--);}void scanline_perspective_single(context_t* c){ // 32 pixels spans works okay. 16 is a lot better, // but hey, it's a software renderer... const uint32_t SPAN_BITS = 5; const uint32_t ys = c->iterators.y; const uint32_t xs = c->iterators.xl; const uint32_t x1 = c->iterators.xr; const uint32_t xc = x1 - xs; const iterators_t& ci = c->iterators; int32_t w = (xs * c->shade.dwdx) + ci.ydwdy; int32_t iw = gglRecipQ(w, 30); const int iwscale = 32 - gglClz(iw); const int i = 31 - gglClz(c->state.enabled_tmu); generated_tex_vars_t& gen = c->generated_vars.texture[i]; texture_t& tmu = c->state.texture[i]; texture_iterators_t& ti = tmu.iterators; const int sscale = ti.sscale + (iwscale - 30); const int tscale = ti.tscale + (iwscale - 30); int32_t s = tmu.shade.is0 + (tmu.shade.idsdy * ys) + (tmu.shade.idsdx * xs) + ((tmu.shade.idsdx + tmu.shade.idsdy)>>1); int32_t t = tmu.shade.it0 + (tmu.shade.idtdy * ys) + (tmu.shade.idtdx * xs) + ((tmu.shade.idtdx + tmu.shade.idtdy)>>1); int32_t s0 = gglMulx(s, iw, iwscale); int32_t t0 = gglMulx(t, iw, iwscale); int32_t xl = c->iterators.xl; int32_t sq, tq, dsdx, dtdx; int32_t premainder = xc & ((1<<SPAN_BITS)-1); uint32_t numSpans = xc >> SPAN_BITS; if (c->shade.dwdx == 0) { // XXX: we could choose to do this if the error is small enough numSpans = 0; premainder = xc; goto no_perspective; } if (premainder) { w += c->shade.dwdx * premainder; iw = gglRecipQ(w, 30);no_perspective: s += tmu.shade.idsdx * premainder; t += tmu.shade.idtdx * premainder; sq = gglMulx(s, iw, iwscale); tq = gglMulx(t, iw, iwscale); dsdx = (sq - s0) / premainder; dtdx = (tq - t0) / premainder; c->iterators.xl = xl; c->iterators.xr = xl = xl + premainder; goto finish; } while (numSpans--) { w += c->shade.dwdx << SPAN_BITS; s += tmu.shade.idsdx << SPAN_BITS; t += tmu.shade.idtdx << SPAN_BITS; iw = gglRecipQ(w, 30); sq = gglMulx(s, iw, iwscale); tq = gglMulx(t, iw, iwscale); dsdx = (sq - s0) >> SPAN_BITS; dtdx = (tq - t0) >> SPAN_BITS; c->iterators.xl = xl; c->iterators.xr = xl = xl + (1<<SPAN_BITS);finish: if (sscale >= 0) { ti.ydsdy = s0 << sscale; ti.dsdx = dsdx << sscale; } else { ti.ydsdy = s0 >>-sscale; ti.dsdx = dsdx >>-sscale; } if (tscale >= 0) { ti.ydtdy = t0 << tscale; ti.dtdx = dtdx << tscale; } else { ti.ydtdy = t0 >>-tscale; ti.dtdx = dtdx >>-tscale; } s0 = sq; t0 = tq; gen.dsdx = ti.dsdx; gen.dtdx = ti.dtdx; c->span(c); }}// ----------------------------------------------------------------------------void scanline_t32cb16(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); union { uint16_t* dst; uint32_t* dst32; }; dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); surface_t* tex = &(c->state.texture[0].surface); const int32_t u = (c->state.texture[0].shade.is0>>16) + x; const int32_t v = (c->state.texture[0].shade.it0>>16) + y; uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v)); int sR, sG, sB; uint32_t s, d; if (ct==1 || uint32_t(dst)&2) {last_one: s = GGL_RGBA_TO_HOST( *src++ ); sR = (s >> ( 3))&0x1F; sG = (s >> ( 8+2))&0x3F; sB = (s >> (16+3))&0x1F; *dst++ = uint16_t((sR<<11)|(sG<<5)|sB); ct--; } while (ct > 0) { s = GGL_RGBA_TO_HOST( *src++ ); sR = (s >> ( 3))&0x1F; sG = (s >> ( 8+2))&0x3F; sB = (s >> (16+3))&0x1F; d = (sR<<11)|(sG<<5)|sB; s = GGL_RGBA_TO_HOST( *src++ ); sR = (s >> ( 3))&0x1F; sG = (s >> ( 8+2))&0x3F; sB = (s >> (16+3))&0x1F; d |= ((sR<<11)|(sG<<5)|sB)<<16;#if BYTE_ORDER == BIG_ENDIAN d = (d>>16) | (d<<16);#endif *dst32++ = d; ct -= 2; } if (ct > 0) { goto last_one; }}void scanline_t32cb16blend(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); uint16_t* dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); surface_t* tex = &(c->state.texture[0].surface); const int32_t u = (c->state.texture[0].shade.is0>>16) + x; const int32_t v = (c->state.texture[0].shade.it0>>16) + y; uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v));#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && defined(__arm__)) scanline_t32cb16blend_arm(dst, src, ct);#else while (ct--) { uint32_t s = *src++; if (!s) { dst++; continue; } uint16_t d = *dst; s = GGL_RGBA_TO_HOST(s); int sR = (s >> ( 3))&0x1F; int sG = (s >> ( 8+2))&0x3F; int sB = (s >> (16+3))&0x1F; int sA = (s>>24); int f = 0x100 - (sA + (sA>>7)); int dR = (d>>11)&0x1f; int dG = (d>>5)&0x3f; int dB = (d)&0x1f; sR += (f*dR)>>8; sG += (f*dG)>>8; sB += (f*dB)>>8; *dst++ = uint16_t((sR<<11)|(sG<<5)|sB); }#endif}void scanline_memcpy(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); const GGLFormat* fp = &(c->formats[cb->format]); uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x + (cb->stride * y)) * fp->size; surface_t* tex = &(c->state.texture[0].surface); const int32_t u = (c->state.texture[0].shade.is0>>16) + x; const int32_t v = (c->state.texture[0].shade.it0>>16) + y; uint8_t *src = reinterpret_cast<uint8_t*>(tex->data) + (u + (tex->stride * v)) * fp->size; const size_t size = ct * fp->size; memcpy(dst, src, size);}void scanline_memset8(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x+(cb->stride*y)); uint32_t packed = c->packed; memset(dst, packed, ct);}void scanline_memset16(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); uint16_t* dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); uint32_t packed = c->packed; android_memset16(dst, packed, ct*2);}void scanline_memset32(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); uint32_t* dst = reinterpret_cast<uint32_t*>(cb->data) + (x+(cb->stride*y)); uint32_t packed = GGL_HOST_TO_RGBA(c->packed); android_memset32(dst, packed, ct*4);}void scanline_clear(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); const GGLFormat* fp = &(c->formats[cb->format]); uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x + (cb->stride * y)) * fp->size; const size_t size = ct * fp->size; memset(dst, 0, size);}void scanline_set(context_t* c){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); const GGLFormat* fp = &(c->formats[cb->format]); uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x + (cb->stride * y)) * fp->size; const size_t size = ct * fp->size; memset(dst, 0xFF, size);}void scanline_noop(context_t* c){}void rect_generic(context_t* c, size_t yc){ do { c->scanline(c); c->step_y(c); } while (--yc);}void rect_memcpy(context_t* c, size_t yc){ int32_t x = c->iterators.xl; size_t ct = c->iterators.xr - x; int32_t y = c->iterators.y; surface_t* cb = &(c->state.buffers.color); const GGLFormat* fp = &(c->formats[cb->format]); uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x + (cb->stride * y)) * fp->size; surface_t* tex = &(c->state.texture[0].surface); const int32_t u = (c->state.texture[0].shade.is0>>16) + x; const int32_t v = (c->state.texture[0].shade.it0>>16) + y; uint8_t *src = reinterpret_cast<uint8_t*>(tex->data) + (u + (tex->stride * v)) * fp->size; if (cb->stride == tex->stride && ct == size_t(cb->stride)) { memcpy(dst, src, ct * fp->size * yc); } else { const size_t size = ct * fp->size; const size_t dbpr = cb->stride * fp->size; const size_t sbpr = tex->stride * fp->size; do { memcpy(dst, src, size); dst += dbpr; src += sbpr; } while (--yc); }}// ----------------------------------------------------------------------------}; // namespace androidusing namespace android;extern "C" void ggl_test_codegen(uint32_t n, uint32_t p, uint32_t t0, uint32_t t1){#if ANDROID_ARM_CODEGEN GGLContext* c; gglInit(&c); needs_t needs; needs.n = n; needs.p = p; needs.t[0] = t0; needs.t[1] = t1; sp<ScanlineAssembly> a(new ScanlineAssembly(needs, 1024)); GGLAssembler assembler( new ARMAssembler(a) ); int err = assembler.scanline(needs, (context_t*)c); if (err != 0) { printf("error %08x (%s)\n", err, strerror(-err)); } gglUninit(c);#else printf("This test runs only on ARM\n");#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -