mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-24 08:39:51 +00:00
Try to optimize bezier color sampling.
This commit is contained in:
parent
49783edf6d
commit
5ee062c681
@ -36,12 +36,16 @@ inline float lerp(float a, float b, float x) {
|
||||
}
|
||||
|
||||
// SLOW!
|
||||
inline void lerpColor(u8 a[4], u8 b[4], float x, u8 out[4]) {
|
||||
inline void lerpColor(const Vec4f &a, const Vec4f &b, float x, Vec4f &out) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
out[i] = (u8)((float)a[i] + x * ((float)b[i] - (float)a[i]));
|
||||
out[i] = a[i] + x * (b[i] - a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void lerpColor(const u8 *a, const u8 *b, float x, Vec4f &out) {
|
||||
lerpColor(Vec4f::FromRGBA(a), Vec4f::FromRGBA(b), x, out);
|
||||
}
|
||||
|
||||
// We decode all vertices into a common format for easy interpolation and stuff.
|
||||
// Not fast but can be optimized later.
|
||||
struct BezierPatch {
|
||||
@ -52,53 +56,54 @@ struct BezierPatch {
|
||||
|
||||
int index;
|
||||
|
||||
struct SamplingParams {
|
||||
float fracU;
|
||||
float fracV;
|
||||
int tl;
|
||||
int tr;
|
||||
int bl;
|
||||
int br;
|
||||
|
||||
SamplingParams(float u, float v) {
|
||||
u *= 3.0f;
|
||||
v *= 3.0f;
|
||||
int iu = (int)floorf(u);
|
||||
int iv = (int)floorf(v);
|
||||
int iu2 = iu + 1;
|
||||
int iv2 = iv + 1;
|
||||
fracU = u - iu;
|
||||
fracV = v - iv;
|
||||
|
||||
if (iu2 > 3)
|
||||
iu2 = 3;
|
||||
if (iv2 > 3)
|
||||
iv2 = 3;
|
||||
|
||||
tl = iu + 4 * iv;
|
||||
tr = iu2 + 4 * iv;
|
||||
bl = iu + 4 * iv2;
|
||||
br = iu2 + 4 * iv2;
|
||||
}
|
||||
};
|
||||
|
||||
// Interpolate colors between control points (bilinear, should be good enough).
|
||||
void sampleColor(float u, float v, u8 color[4]) const {
|
||||
u *= 3.0f;
|
||||
v *= 3.0f;
|
||||
int iu = (int)floorf(u);
|
||||
int iv = (int)floorf(v);
|
||||
int iu2 = iu + 1;
|
||||
int iv2 = iv + 1;
|
||||
float fracU = u - iu;
|
||||
float fracV = v - iv;
|
||||
if (iu2 > 3) iu2 = 3;
|
||||
if (iv2 > 3) iv2 = 3;
|
||||
|
||||
int tl = iu + 4 * iv;
|
||||
int tr = iu2 + 4 * iv;
|
||||
int bl = iu + 4 * iv2;
|
||||
int br = iu2 + 4 * iv2;
|
||||
|
||||
u8 upperColor[4], lowerColor[4];
|
||||
lerpColor(points[tl]->color, points[tr]->color, fracU, upperColor);
|
||||
lerpColor(points[bl]->color, points[br]->color, fracU, lowerColor);
|
||||
lerpColor(upperColor, lowerColor, fracV, color);
|
||||
const SamplingParams params(u, v);
|
||||
Vec4f upperColor, lowerColor, resultColor;
|
||||
lerpColor(points[params.tl]->color, points[params.tr]->color, params.fracU, upperColor);
|
||||
lerpColor(points[params.bl]->color, points[params.br]->color, params.fracU, lowerColor);
|
||||
lerpColor(upperColor, lowerColor, params.fracV, resultColor);
|
||||
resultColor.ToRGBA(color);
|
||||
}
|
||||
|
||||
void sampleTexUV(float u, float v, float &tu, float &tv) const {
|
||||
u *= 3.0f;
|
||||
v *= 3.0f;
|
||||
int iu = (int)floorf(u);
|
||||
int iv = (int)floorf(v);
|
||||
int iu2 = iu + 1;
|
||||
int iv2 = iv + 1;
|
||||
float fracU = u - iu;
|
||||
float fracV = v - iv;
|
||||
if (iu2 > 3) iu2 = 3;
|
||||
if (iv2 > 3) iv2 = 3;
|
||||
|
||||
int tl = iu + 4 * iv;
|
||||
int tr = iu2 + 4 * iv;
|
||||
int bl = iu + 4 * iv2;
|
||||
int br = iu2 + 4 * iv2;
|
||||
|
||||
float upperTU = lerp(points[tl]->uv[0], points[tr]->uv[0], fracU);
|
||||
float upperTV = lerp(points[tl]->uv[1], points[tr]->uv[1], fracU);
|
||||
float lowerTU = lerp(points[bl]->uv[0], points[br]->uv[0], fracU);
|
||||
float lowerTV = lerp(points[bl]->uv[1], points[br]->uv[1], fracU);
|
||||
tu = lerp(upperTU, lowerTU, fracV);
|
||||
tv = lerp(upperTV, lowerTV, fracV);
|
||||
const SamplingParams params(u, v);
|
||||
float upperTU = lerp(points[params.tl]->uv[0], points[params.tr]->uv[0], params.fracU);
|
||||
float upperTV = lerp(points[params.tl]->uv[1], points[params.tr]->uv[1], params.fracU);
|
||||
float lowerTU = lerp(points[params.bl]->uv[0], points[params.br]->uv[0], params.fracU);
|
||||
float lowerTV = lerp(points[params.bl]->uv[1], points[params.br]->uv[1], params.fracU);
|
||||
tu = lerp(upperTU, lowerTU, params.fracV);
|
||||
tv = lerp(upperTV, lowerTV, params.fracV);
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,56 +113,6 @@ struct SplinePatchLocal {
|
||||
int count_v;
|
||||
int type_u;
|
||||
int type_v;
|
||||
|
||||
/*
|
||||
// Interpolate colors between control points (bilinear, should be good enough).
|
||||
void sampleColor(float u, float v, u8 color[4]) const {
|
||||
u *= 3.0f;
|
||||
v *= 3.0f;
|
||||
int iu = (int)floorf(u);
|
||||
int iv = (int)floorf(v);
|
||||
int iu2 = iu + 1;
|
||||
int iv2 = iv + 1;
|
||||
float fracU = u - iu;
|
||||
float fracV = v - iv;
|
||||
if (iu2 >= count_u) iu2 = count_u - 1;
|
||||
if (iv2 >= count_v) iv2 = count_v - 1;
|
||||
|
||||
int tl = iu + count_u * iv;
|
||||
int tr = iu2 + count_u * iv;
|
||||
int bl = iu + count_u * iv2;
|
||||
int br = iu2 + count_u * iv2;
|
||||
|
||||
u8 upperColor[4], lowerColor[4];
|
||||
lerpColor(points[tl]->color, points[tr]->color, fracU, upperColor);
|
||||
lerpColor(points[bl]->color, points[br]->color, fracU, lowerColor);
|
||||
lerpColor(upperColor, lowerColor, fracV, color);
|
||||
}
|
||||
|
||||
void sampleTexUV(float u, float v, float &tu, float &tv) const {
|
||||
u *= 3.0f;
|
||||
v *= 3.0f;
|
||||
int iu = (int)floorf(u);
|
||||
int iv = (int)floorf(v);
|
||||
int iu2 = iu + 1;
|
||||
int iv2 = iv + 1;
|
||||
float fracU = u - iu;
|
||||
float fracV = v - iv;
|
||||
if (iu2 >= count_u) iu2 = count_u - 1;
|
||||
if (iv2 >= count_v) iv2 = count_v - 1;
|
||||
|
||||
int tl = iu + count_u * iv;
|
||||
int tr = iu2 + count_u * iv;
|
||||
int bl = iu + count_u * iv2;
|
||||
int br = iu2 + count_u * iv2;
|
||||
|
||||
float upperTU = lerp(points[tl]->uv[0], points[tr]->uv[0], fracU);
|
||||
float upperTV = lerp(points[tl]->uv[1], points[tr]->uv[1], fracU);
|
||||
float lowerTU = lerp(points[bl]->uv[0], points[br]->uv[0], fracU);
|
||||
float lowerTV = lerp(points[bl]->uv[1], points[br]->uv[1], fracU);
|
||||
tu = lerp(upperTU, lowerTU, fracV);
|
||||
tv = lerp(upperTV, lowerTV, fracV);
|
||||
}*/
|
||||
};
|
||||
|
||||
enum quality {
|
||||
|
14
GPU/Math3D.h
14
GPU/Math3D.h
@ -561,7 +561,9 @@ public:
|
||||
|
||||
// Only implemented for T=int and T=float
|
||||
static Vec4 FromRGBA(unsigned int rgba);
|
||||
static Vec4 FromRGBA(const u8 *rgba);
|
||||
unsigned int ToRGBA() const;
|
||||
void ToRGBA(u8 *rgba) const;
|
||||
|
||||
static Vec4 AssignToAll(const T& f)
|
||||
{
|
||||
@ -1012,6 +1014,12 @@ inline Vec4<float> Vec4<float>::FromRGBA(unsigned int rgba)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline Vec4<T> Vec4<T>::FromRGBA(const u8 *rgba)
|
||||
{
|
||||
return Vec4<T>::FromRGBA(*(unsigned int *)rgba);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Vec4<int> Vec4<int>::FromRGBA(unsigned int rgba)
|
||||
{
|
||||
@ -1051,6 +1059,12 @@ __forceinline unsigned int Vec4<int>::ToRGBA() const
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__forceinline void Vec4<T>::ToRGBA(u8 *rgba) const
|
||||
{
|
||||
*(u32 *)rgba = ToRGBA();
|
||||
}
|
||||
|
||||
}; // namespace Math3D
|
||||
|
||||
// linear interpolation via float: 0.0=begin, 1.0=end
|
||||
|
Loading…
Reference in New Issue
Block a user