167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
#ifndef _TEXSW_H_
|
|
|
|
#include "common.h"
|
|
|
|
#define TEX_LOD_MAX 11
|
|
|
|
#define MIN(x, y) ((x < y) ? (x) : (y))
|
|
|
|
#define MAX(x, y) ((x > y) ? (x) : (y))
|
|
|
|
inline int address(int wrap, int value) {
|
|
switch (wrap) {
|
|
case 1: return value & 0xfffff;
|
|
default:
|
|
case 0: return MIN(MAX(value, 0), 0xfffff);
|
|
}
|
|
}
|
|
|
|
inline void unpack(int format, int value, int* l, int* h) {
|
|
switch (format) {
|
|
case 1:
|
|
case 2:
|
|
*l = value;
|
|
*h = 0;
|
|
break;
|
|
case 3:
|
|
*l = (value | (value << 8)) & 0x00ff00ff;
|
|
*h = 0;
|
|
break;
|
|
case 4:
|
|
*l = (value | (value << 16)) & 0x07e0f81f;
|
|
*h = 0;
|
|
break;
|
|
case 5:
|
|
*l = (value | (value << 12)) & 0x0f0f0f0f;
|
|
*h = 0;
|
|
break;
|
|
default:
|
|
case 0:
|
|
*l = value & 0x00ff00ff;
|
|
*h = (value >> 8) & 0x00ff00ff;
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline void lerp(int al, int ah, int bl, int bh, int frac, int* l, int* h) {
|
|
*l = (al + (((bl - al) * frac) >> 8)) & 0x00ff00ff;
|
|
*h = (ah + (((bh - ah) * frac) >> 8)) & 0x00ff00ff;
|
|
}
|
|
|
|
inline int pack(int format, int l, int h) {
|
|
switch (format) {
|
|
case 1:
|
|
case 2:
|
|
return l;
|
|
case 3:
|
|
return (l | (l >> 8)) & 0xffff;
|
|
case 4:
|
|
return (l | (l >> 16)) & 0xffff;
|
|
case 5:
|
|
return (l | (l >> 12)) & 0xffff;
|
|
default:
|
|
case 0:
|
|
return (h << 8) | l;
|
|
}
|
|
}
|
|
|
|
inline int tex_sw(struct kernel_arg_t* state, int stage, int u, int v, int lod) {
|
|
int base_addr = state->src_ptr;
|
|
int mip_offset = 0;
|
|
int log_width = state->src_logWidth;
|
|
int log_height = state->src_logHeight;
|
|
int format = state->format;
|
|
int wrap = state->wrap;
|
|
int filter = state->filter;
|
|
|
|
int32_t* pBits = ((uint32_t*)base_addr) + mip_offset;
|
|
|
|
if (filter) {
|
|
int u0 = address(wrap, u - (0x80000 >> log_width));
|
|
int v0 = address(wrap, v - (0x80000 >> log_height));
|
|
int u1 = address(wrap, u + (0x80000 >> log_width));
|
|
int v1 = address(wrap, v + (0x80000 >> log_height));
|
|
|
|
int x0 = u0 >> (20 - log_width);
|
|
int y0 = v0 >> (20 - log_height);
|
|
int x1 = u1 >> (20 - log_width);
|
|
int y1 = v1 >> (20 - log_height);
|
|
|
|
// memory lookup
|
|
|
|
int c0 = pBits[x0 + (y0 << log_width)];
|
|
int c1 = pBits[x1 + (y0 << log_width)];
|
|
int c2 = pBits[x0 + (y1 << log_width)];
|
|
int c3 = pBits[x1 + (y1 << log_width)];
|
|
|
|
// filtering
|
|
|
|
int alpha = x0 & 0xff;
|
|
int beta = y0 & 0xff;
|
|
|
|
int c0a, c0b;
|
|
int c1a, c1b;
|
|
int c01a, c01b;
|
|
|
|
unpack(format, c0, &c0a, &c0b);
|
|
unpack(format, c1, &c1a, &c1b);
|
|
lerp(c0a, c0b, c1a, c1b, alpha, &c01a, &c01b);
|
|
|
|
int c2a, c2b;
|
|
int c3a, c3b;
|
|
int c23a, c23b;
|
|
|
|
unpack(format, c2, &c2a, &c2b);
|
|
unpack(format, c3, &c3a, &c3b);
|
|
lerp(c2a, c2b, c3a, c3b, alpha, &c23a, &c23b);
|
|
|
|
int c4a, c4b;
|
|
lerp(c01a, c01b, c23a, c23b, beta, &c4a, &c4b);
|
|
return pack(format, c4a, c4b);
|
|
} else {
|
|
int u0 = address(wrap, u);
|
|
int v0 = address(wrap, v);
|
|
|
|
int x0 = u0 >> (20 - log_width);
|
|
int y0 = v0 >> (20 - log_height);
|
|
|
|
int c0 = pBits[x0 + (y0 <<log_width)];
|
|
|
|
int c0a, c0b;
|
|
unpack(format, c0, &c0a, &c0b);
|
|
return pack(format, c0a, c0b);
|
|
}
|
|
}
|
|
|
|
inline int vx_tex3(int stage, int u, int v, int lod) {
|
|
int lodn = MIN(lod + 0x100000, TEX_LOD_MAX);
|
|
int a = vx_tex(0, u, v, lod);
|
|
int b = vx_tex(0, u, v, lodn);
|
|
int al = a & 0x00ff00ff;
|
|
int ah = (a >> 8) & 0x00ff00ff;
|
|
int bl = b & 0x00ff00ff;
|
|
int bh = (b >> 8) & 0x00ff00ff;
|
|
int frac = (lod >> 12) & 0xff;
|
|
int cl = (al + (((bl - al) * frac) >> 8)) & 0x00ff00ff;
|
|
int ch = (ah + (((bh - ah) * frac) >> 8)) & 0x00ff00ff;
|
|
int c = al | (ah << 8);
|
|
return c;
|
|
}
|
|
|
|
inline int tex3_sw(struct kernel_arg_t* state, int stage, int u, int v, int lod) {
|
|
int lodn = MIN(lod + 0x10000, TEX_LOD_MAX);
|
|
int a = tex_sw(state, 0, u, v, lod);
|
|
int b = tex_sw(state, 0, u, v, lodn);
|
|
int al = a & 0x00ff00ff;
|
|
int ah = (a >> 8) & 0x00ff00ff;
|
|
|
|
int bl = b & 0x00ff00ff;
|
|
int bh = (b >> 8) & 0x00ff00ff;
|
|
int frac = (lod >> 12) & 0xff;
|
|
int cl = (al + (((bl - al) * frac) >> 8)) & 0x00ff00ff;
|
|
int ch = (ah + (((bh - ah) * frac) >> 8)) & 0x00ff00ff;
|
|
int c = al | (ah << 8);
|
|
return c;
|
|
}
|
|
|
|
#endif |