mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 23:40:39 +00:00
[spline/bezier]Improve template parameter dispatch method.
# Conflicts: # GPU/Common/SplineCommon.h
This commit is contained in:
parent
f7ac70858d
commit
da1176f2b3
@ -410,53 +410,31 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp
|
||||
BuildIndex(indices, count, patch_div_s, patch_div_t, spatch.primType);
|
||||
}
|
||||
|
||||
template <bool origNrm, bool origCol, bool origTc>
|
||||
static inline void SplinePatchFullQualityDispatch4(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int quality, int maxVertices) {
|
||||
if (cpu_info.bSSE4_1)
|
||||
SplinePatchFullQuality<origNrm, origCol, origTc, true>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
else
|
||||
SplinePatchFullQuality<origNrm, origCol, origTc, false>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
}
|
||||
|
||||
template <bool origNrm, bool origCol>
|
||||
static inline void SplinePatchFullQualityDispatch3(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int quality, int maxVertices) {
|
||||
bool origTc = (origVertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
if (origTc)
|
||||
SplinePatchFullQualityDispatch4<origNrm, origCol, true>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
else
|
||||
SplinePatchFullQualityDispatch4<origNrm, origCol, false>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
}
|
||||
|
||||
template <bool origNrm>
|
||||
static inline void SplinePatchFullQualityDispatch2(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int quality, int maxVertices) {
|
||||
bool origCol = (origVertType & GE_VTYPE_COL_MASK) != 0;
|
||||
|
||||
if (origCol)
|
||||
SplinePatchFullQualityDispatch3<origNrm, true>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
else
|
||||
SplinePatchFullQualityDispatch3<origNrm, false>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
}
|
||||
|
||||
static void SplinePatchFullQualityDispatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int quality, int maxVertices) {
|
||||
bool origNrm = (origVertType & GE_VTYPE_NRM_MASK) != 0;
|
||||
|
||||
if (origNrm)
|
||||
SplinePatchFullQualityDispatch2<true>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
else
|
||||
SplinePatchFullQualityDispatch2<false>(dest, indices, count, spatch, origVertType, quality, maxVertices);
|
||||
}
|
||||
// Define class TemplateParameterDispatcherTess
|
||||
TEMPLATE_PARAMETER_DISPATCHER(Tess, SplinePatchFullQuality);
|
||||
|
||||
void TessellateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertexCount) {
|
||||
using TessFunc = void(*)(u8 *&, u16 *, int &, const SplinePatchLocal &, u32, int, int);
|
||||
constexpr int NumParams = 4;
|
||||
static TemplateParameterDispatcherTess<TessFunc, NumParams> dispatcher; // Initialize only once
|
||||
|
||||
const bool params[NumParams] = {
|
||||
(origVertType & GE_VTYPE_NRM_MASK) != 0,
|
||||
(origVertType & GE_VTYPE_COL_MASK) != 0,
|
||||
(origVertType & GE_VTYPE_TC_MASK) != 0,
|
||||
cpu_info.bSSE4_1,
|
||||
};
|
||||
TessFunc func = dispatcher.GetFunc(params);
|
||||
|
||||
switch (g_Config.iSplineBezierQuality) {
|
||||
case LOW_QUALITY:
|
||||
SplinePatchFullQualityDispatch(dest, indices, count, spatch, origVertType, 0, maxVertexCount);
|
||||
(*func)(dest, indices, count, spatch, origVertType, 0, maxVertexCount);
|
||||
break;
|
||||
case MEDIUM_QUALITY:
|
||||
SplinePatchFullQualityDispatch(dest, indices, count, spatch, origVertType, 2, maxVertexCount);
|
||||
(*func)(dest, indices, count, spatch, origVertType, 2, maxVertexCount);
|
||||
break;
|
||||
case HIGH_QUALITY:
|
||||
SplinePatchFullQualityDispatch(dest, indices, count, spatch, origVertType, 1, maxVertexCount);
|
||||
(*func)(dest, indices, count, spatch, origVertType, 1, maxVertexCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -69,3 +69,40 @@ enum SplineQuality {
|
||||
|
||||
bool CanUseHardwareTessellation(GEPatchPrimType prim);
|
||||
void TessellateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertices);
|
||||
void TessellateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices);
|
||||
|
||||
#define TEMPLATE_PARAMETER_DISPATCHER(NAME, FUNCNAME) \
|
||||
template<typename Func, int NumParams> \
|
||||
class TemplateParameterDispatcher##NAME { \
|
||||
/* Store all combinations of template functions into an array */ \
|
||||
template<int LoopCount, int Index = 0, bool ...Params> \
|
||||
struct Initializer { \
|
||||
Initializer(Func funcs[]) { \
|
||||
Initializer<LoopCount - 1, (Index << 1) + 1, true, Params...> _true(funcs); \
|
||||
Initializer<LoopCount - 1, (Index << 1) + 0, false, Params...> _false(funcs); \
|
||||
} \
|
||||
}; \
|
||||
/* Specialized for terminates the recursive loop */ \
|
||||
template<int Index, bool ...Params> \
|
||||
struct Initializer<0, Index, Params...> { \
|
||||
Initializer(Func funcs[]) { \
|
||||
funcs[Index] = &FUNCNAME<Params...>; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
private: \
|
||||
Func funcs[1 << NumParams]; /* Function pointers array */ \
|
||||
public: \
|
||||
TemplateParameterDispatcher##NAME() { \
|
||||
Initializer<NumParams>::Initializer(funcs); \
|
||||
} \
|
||||
\
|
||||
Func GetFunc(const bool params[]) const { \
|
||||
/* Convert bool parameters to index of the array */ \
|
||||
int param = 0; \
|
||||
for (int i = 0; i < NumParams; ++i) \
|
||||
param |= params[i] << i; \
|
||||
\
|
||||
return funcs[param]; \
|
||||
} \
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user