mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Remove obsolete vertex decoder code and options
This commit is contained in:
1 parent
cd40e2d4f0
commit
c3eafeb005
10 files changed
+4
-499
No files matched your search
@@ -104,9 +104,6 @@ static const ARMReg srcNEON = Q2;
|
||||
static const ARMReg accNEON = Q3;
|
||||
|
||||
static const JitLookup jitLookup[] = {
|
||||
{&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8},
|
||||
{&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16},
|
||||
{&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat},
|
||||
{&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin},
|
||||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
@@ -296,55 +293,6 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
||||
return (JittedVertexDecoder)start;
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8() {
|
||||
// Basic implementation - a byte at a time. TODO: Optimize
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDRB(tempReg1, srcReg, dec_->weightoff + j);
|
||||
STRB(tempReg1, dstReg, dec_->decFmt.w0off + j);
|
||||
}
|
||||
if (j & 3) {
|
||||
// Create a zero register. Might want to make a fixed one.
|
||||
EOR(scratchReg, scratchReg, scratchReg);
|
||||
}
|
||||
while (j & 3) {
|
||||
STRB(scratchReg, dstReg, dec_->decFmt.w0off + j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16() {
|
||||
// Basic implementation - a short at a time. TODO: Optimize
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDRH(tempReg1, srcReg, dec_->weightoff + j * 2);
|
||||
STRH(tempReg1, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
}
|
||||
if (j & 3) {
|
||||
// Create a zero register. Might want to make a fixed one.
|
||||
EOR(scratchReg, scratchReg, scratchReg);
|
||||
}
|
||||
while (j & 3) {
|
||||
STRH(scratchReg, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsFloat() {
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDR(tempReg1, srcReg, dec_->weightoff + j * 4);
|
||||
STR(tempReg1, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
}
|
||||
if (j & 3) {
|
||||
EOR(tempReg1, tempReg1, tempReg1);
|
||||
}
|
||||
while (j & 3) { // Zero additional weights rounding up to 4.
|
||||
STR(tempReg1, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
static const ARMReg weightRegs[8] = { S8, S9, S10, S11, S12, S13, S14, S15 };
|
||||
static const ARMReg neonWeightRegsD[4] = { D4, D5, D6, D7 };
|
||||
static const ARMReg neonWeightRegsQ[2] = { Q2, Q3 };
|
||||
|
||||
@@ -81,9 +81,6 @@ static const ARM64Reg neonWeightRegsQ[2] = { Q3, Q2 }; // reverse order to prev
|
||||
// Q16+ are free-for-all for matrices. In 16 registers, we can fit 4 4x4 matrices.
|
||||
|
||||
static const JitLookup jitLookup[] = {
|
||||
{&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8},
|
||||
{&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16},
|
||||
{&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat},
|
||||
{&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin},
|
||||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
@@ -359,44 +356,6 @@ void VertexDecoderJitCache::Jit_ApplyWeights() {
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8() {
|
||||
// Basic implementation - a byte at a time. TODO: Optimize
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDRB(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j);
|
||||
STRB(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j);
|
||||
}
|
||||
while (j & 3) {
|
||||
STRB(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16() {
|
||||
// Basic implementation - a short at a time. TODO: Optimize
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDRH(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j * 2);
|
||||
STRH(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
}
|
||||
while (j & 3) {
|
||||
STRH(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsFloat() {
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LDR(INDEX_UNSIGNED, tempReg1, srcReg, dec_->weightoff + j * 4);
|
||||
STR(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
}
|
||||
while (j & 3) { // Zero additional weights rounding up to 4.
|
||||
STR(INDEX_UNSIGNED, WZR, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8Skin() {
|
||||
// Weight is first so srcReg is correct.
|
||||
switch (dec_->nweights) {
|
||||
|
||||
@@ -55,13 +55,6 @@ inline int align(int n, int align) {
|
||||
return (n + (align - 1)) & ~(align - 1);
|
||||
}
|
||||
|
||||
// Map 1-4 bones to 4 bones. works fine.
|
||||
int TranslateNumBones(int bones) {
|
||||
if (!bones) return 0;
|
||||
if (bones < 4) return 4;
|
||||
return bones;
|
||||
}
|
||||
|
||||
static int DecFmtSize(u8 fmt) {
|
||||
switch (fmt) {
|
||||
case DEC_NONE: return 0;
|
||||
@@ -230,66 +223,6 @@ void PrintDecodedVertex(const VertexReader &vtx) {
|
||||
printf("P: %f %f %f\n", pos[0], pos[1], pos[2]);
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_WeightsU8(const VertexDecoder *dec, const u8 *ptr, u8 *decoded) {
|
||||
u8 *wt = (u8 *)(decoded + dec->decFmt.w0off);
|
||||
const u8 *wdata = (const u8*)(ptr);
|
||||
int j;
|
||||
const int nweights = dec->nweights;
|
||||
for (j = 0; j < nweights; j++)
|
||||
wt[j] = wdata[j];
|
||||
while (j & 3) // Zero additional weights rounding up to 4.
|
||||
wt[j++] = 0;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_WeightsU16(const VertexDecoder *dec, const u8 *ptr, u8 *decoded) {
|
||||
u16 *wt = (u16 *)(decoded + dec->decFmt.w0off);
|
||||
const u16_le *wdata = (const u16_le *)(ptr);
|
||||
int j;
|
||||
const int nweights = dec->nweights;
|
||||
for (j = 0; j < nweights; j++)
|
||||
wt[j] = wdata[j];
|
||||
while (j & 3) // Zero additional weights rounding up to 4.
|
||||
wt[j++] = 0;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_WeightsU8ToFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded) {
|
||||
float *wt = (float *)(decoded + dec->decFmt.w0off);
|
||||
const u8 *wdata = (const u8*)(ptr);
|
||||
int j;
|
||||
const int nweights = dec->nweights;
|
||||
for (j = 0; j < nweights; j++) {
|
||||
wt[j] = (float)wdata[j] * (1.0f / 128.0f);
|
||||
}
|
||||
while (j & 3) // Zero additional weights rounding up to 4.
|
||||
wt[j++] = 0;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_WeightsU16ToFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded) {
|
||||
float *wt = (float *)(decoded + dec->decFmt.w0off);
|
||||
const u16_le *wdata = (const u16_le *)(ptr);
|
||||
int j;
|
||||
const int nweights = dec->nweights;
|
||||
for (j = 0; j < nweights; j++) {
|
||||
wt[j] = (float)wdata[j] * (1.0f / 32768.0f);
|
||||
}
|
||||
while (j & 3) // Zero additional weights rounding up to 4.
|
||||
wt[j++] = 0;
|
||||
}
|
||||
|
||||
// Float weights should be uncommon, we can live with having to multiply these by 2.0
|
||||
// to avoid special checks in the vertex shader generator.
|
||||
// (PSP uses 0.0-2.0 fixed point numbers for weights)
|
||||
void VertexDecoder::Step_WeightsFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded) {
|
||||
float *wt = (float *)(decoded + dec->decFmt.w0off);
|
||||
const float_le *wdata = (const float_le *)(ptr);
|
||||
int j;
|
||||
for (j = 0; j < dec->nweights; j++) {
|
||||
wt[j] = wdata[j];
|
||||
}
|
||||
while (j & 3) // Zero additional weights rounding up to 4.
|
||||
wt[j++] = 0.0f;
|
||||
}
|
||||
|
||||
void VertexDecoder::ComputeSkinMatrix(const float weights[8]) const {
|
||||
const int count = nweights;
|
||||
#if PPSSPP_ARCH(SSE2)
|
||||
@@ -1061,20 +994,6 @@ void VertexDecoder::Step_PosFloatMorphSkin(const VertexDecoder *dec, const u8 *p
|
||||
Vec3ByMatrix43(v, pos, skinMatrix);
|
||||
}
|
||||
|
||||
static const StepFunction wtstep[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_WeightsU8,
|
||||
&VertexDecoder::Step_WeightsU16,
|
||||
&VertexDecoder::Step_WeightsFloat,
|
||||
};
|
||||
|
||||
static const StepFunction wtstepToFloat[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_WeightsU8ToFloat,
|
||||
&VertexDecoder::Step_WeightsU16ToFloat,
|
||||
&VertexDecoder::Step_WeightsFloat,
|
||||
};
|
||||
|
||||
// TODO: Morph weights correctly! This is missing. Not sure if any game actually
|
||||
// use this functionality at all.
|
||||
|
||||
@@ -1273,50 +1192,18 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
|
||||
DEBUG_LOG(Log::G3D, "VTYPE: THRU=%i TC=%i COL=%i POS=%i NRM=%i WT=%i NW=%i IDX=%i MC=%i", (int)throughmode, tc, col, pos, nrm, weighttype, nweights, idx, morphcount);
|
||||
}
|
||||
|
||||
skinInDecode = weighttype != 0 && VertTypeIDSkinInDecode(fmt);
|
||||
|
||||
if (weighttype) { // && nweights?
|
||||
skinInDecode = true;
|
||||
weightoff = size;
|
||||
//size = align(size, wtalign[weighttype]); unnecessary
|
||||
size += wtsize[weighttype] * nweights;
|
||||
if (wtalign[weighttype] > biggest)
|
||||
biggest = wtalign[weighttype];
|
||||
|
||||
if (skinInDecode) {
|
||||
// No visible output, computes a matrix that is passed through the skinMatrix variable
|
||||
// to the "nrm" and "pos" steps.
|
||||
steps_[numSteps_++] = wtstep_skin[weighttype];
|
||||
} else {
|
||||
int fmtBase = DEC_FLOAT_1;
|
||||
if (options.expandAllWeightsToFloat) {
|
||||
steps_[numSteps_++] = wtstepToFloat[weighttype];
|
||||
fmtBase = DEC_FLOAT_1;
|
||||
} else {
|
||||
steps_[numSteps_++] = wtstep[weighttype];
|
||||
if (weighttype == GE_VTYPE_WEIGHT_8BIT >> GE_VTYPE_WEIGHT_SHIFT) {
|
||||
fmtBase = DEC_U8_1;
|
||||
} else if (weighttype == GE_VTYPE_WEIGHT_16BIT >> GE_VTYPE_WEIGHT_SHIFT) {
|
||||
fmtBase = DEC_U16_1;
|
||||
} else if (weighttype == GE_VTYPE_WEIGHT_FLOAT >> GE_VTYPE_WEIGHT_SHIFT) {
|
||||
fmtBase = DEC_FLOAT_1;
|
||||
}
|
||||
}
|
||||
|
||||
int numWeights = TranslateNumBones(nweights);
|
||||
|
||||
if (numWeights <= 4) {
|
||||
decFmt.w0off = decOff;
|
||||
decFmt.w0fmt = fmtBase + numWeights - 1;
|
||||
decOff += DecFmtSize(decFmt.w0fmt);
|
||||
} else {
|
||||
decFmt.w0off = decOff;
|
||||
decFmt.w0fmt = fmtBase + 3;
|
||||
decOff += DecFmtSize(decFmt.w0fmt);
|
||||
decFmt.w1off = decOff;
|
||||
decFmt.w1fmt = fmtBase + numWeights - 5;
|
||||
decOff += DecFmtSize(decFmt.w1fmt);
|
||||
}
|
||||
}
|
||||
// No visible output, computes a matrix that is passed through the skinMatrix variable
|
||||
// to the "nrm" and "pos" steps.
|
||||
steps_[numSteps_++] = wtstep_skin[weighttype];
|
||||
}
|
||||
|
||||
if (tc) {
|
||||
@@ -1747,12 +1634,6 @@ struct StepFunctionNameEntry {
|
||||
};
|
||||
|
||||
static const StepFunctionNameEntry stepFunctionNames[] = {
|
||||
{VertexDecoder::Step_WeightsU8, "WeightsU8"},
|
||||
{VertexDecoder::Step_WeightsU16, "WeightsU16"},
|
||||
{VertexDecoder::Step_WeightsU8ToFloat, "WeightsU8ToFloat"},
|
||||
{VertexDecoder::Step_WeightsU16ToFloat, "WeightsU16ToFloat"},
|
||||
{VertexDecoder::Step_WeightsFloat, "WeightsFloat"},
|
||||
|
||||
{VertexDecoder::Step_WeightsU8Skin, "WeightsU8Skin"},
|
||||
{VertexDecoder::Step_WeightsU16Skin, "WeightsU16Skin"},
|
||||
{VertexDecoder::Step_WeightsFloatSkin, "WeightsFloatSkin"},
|
||||
|
||||
@@ -133,13 +133,9 @@ struct JitLookup {
|
||||
JitStepFunction jitFunc;
|
||||
};
|
||||
|
||||
// Collapse to less skinning shaders to reduce shader switching, which is expensive.
|
||||
int TranslateNumBones(int bones);
|
||||
|
||||
typedef void (*JittedVertexDecoder)(const u8 *src, u8 *dst, int count, const UVScale *uvScaleOffset);
|
||||
|
||||
struct VertexDecoderOptions {
|
||||
bool expandAllWeightsToFloat;
|
||||
bool expand8BitNormalsToFloat;
|
||||
};
|
||||
|
||||
@@ -149,10 +145,6 @@ inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
|
||||
return (vertType & 0xFFFFFF) | (uvGenMode << 24);
|
||||
}
|
||||
|
||||
inline bool VertTypeIDSkinInDecode(uint32_t vertType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline GETexMapMode VertTypeIDUVGenMode(uint32_t vertType) {
|
||||
return (GETexMapMode)((vertType >> 24) & 3);
|
||||
}
|
||||
@@ -179,12 +171,6 @@ public:
|
||||
|
||||
void ComputeSkinMatrix(const float weights[8]) const;
|
||||
|
||||
static void Step_WeightsU8(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsU16(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsU8ToFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsU16ToFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsFloat(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
|
||||
static void Step_WeightsU8Skin(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsU16Skin(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
static void Step_WeightsFloatSkin(const VertexDecoder *dec, const u8 *ptr, u8 *decoded);
|
||||
@@ -351,12 +337,6 @@ public:
|
||||
JittedVertexDecoder Compile(const VertexDecoder &dec, int32_t *jittedSize);
|
||||
void Clear();
|
||||
|
||||
void Jit_WeightsU8();
|
||||
void Jit_WeightsU16();
|
||||
void Jit_WeightsU8ToFloat();
|
||||
void Jit_WeightsU16ToFloat();
|
||||
void Jit_WeightsFloat();
|
||||
|
||||
void Jit_WeightsU8Skin();
|
||||
void Jit_WeightsU16Skin();
|
||||
void Jit_WeightsFloatSkin();
|
||||
|
||||
@@ -93,9 +93,6 @@ static constexpr LoongArch64Reg regs_to_save_fp[]{ F24, F25, F26, F27, F28, F29,
|
||||
// V16+ are free-for-all for matrices. In 16 registers, we can fit 4 4x4 matrices.
|
||||
|
||||
static const JitLookup jitLookup[] = {
|
||||
{&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8},
|
||||
{&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16},
|
||||
{&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat},
|
||||
{&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin},
|
||||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
@@ -415,46 +412,6 @@ void VertexDecoderJitCache::Jit_ApplyWeights() {
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8() {
|
||||
// Basic implementation - a byte at a time.
|
||||
// TODO: Could optimize with unaligned load/store
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LD_B(tempReg1, srcReg, dec_->weightoff + j);
|
||||
ST_B(tempReg1, dstReg, dec_->decFmt.w0off + j);
|
||||
}
|
||||
while (j & 3) {
|
||||
ST_B(R_ZERO, dstReg, dec_->decFmt.w0off + j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16() {
|
||||
// Basic implementation - a short at a time.
|
||||
// TODO: Could optimize with unaligned load/store
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LD_H(tempReg1, srcReg, dec_->weightoff + j * 2);
|
||||
ST_H(tempReg1, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
}
|
||||
while (j & 3) {
|
||||
ST_H(R_ZERO, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsFloat() {
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LD_W(tempReg1, srcReg, dec_->weightoff + j * 4);
|
||||
ST_W(tempReg1, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
}
|
||||
while (j & 3) { // Zero additional weights rounding up to 4.
|
||||
ST_W(R_ZERO, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8Skin() {
|
||||
// Weight is first so srcReg is correct.
|
||||
switch (dec_->nweights) {
|
||||
|
||||
@@ -123,9 +123,6 @@ static uint32_t GetMorphValueUsage(uint32_t vtype) {
|
||||
// TODO: Use vector, where supported.
|
||||
|
||||
static const JitLookup jitLookup[] = {
|
||||
{&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8},
|
||||
{&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16},
|
||||
{&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat},
|
||||
{&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin},
|
||||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
@@ -374,45 +371,6 @@ bool VertexDecoderJitCache::CompileStep(const VertexDecoder &dec, int step) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8() {
|
||||
// Just copy a byte at a time. Would be nice if we knew if misaligned access was fast.
|
||||
// If it's not fast, it can crash or hit a software trap (100x slower.)
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LB(tempReg1, srcReg, dec_->weightoff + j);
|
||||
SB(tempReg1, dstReg, dec_->decFmt.w0off + j);
|
||||
}
|
||||
// We zero out any weights up to a multiple of 4.
|
||||
while (j & 3) {
|
||||
SB(R_ZERO, dstReg, dec_->decFmt.w0off + j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16() {
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LH(tempReg1, srcReg, dec_->weightoff + j * 2);
|
||||
SH(tempReg1, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
}
|
||||
while (j & 3) {
|
||||
SH(R_ZERO, dstReg, dec_->decFmt.w0off + j * 2);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsFloat() {
|
||||
int j;
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
LW(tempReg1, srcReg, dec_->weightoff + j * 4);
|
||||
SW(tempReg1, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
}
|
||||
while (j & 3) {
|
||||
SW(R_ZERO, dstReg, dec_->decFmt.w0off + j * 4);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8Skin() {
|
||||
Jit_ApplyWeights();
|
||||
}
|
||||
|
||||
@@ -101,16 +101,10 @@ static const X64Reg fpScratchReg4 = XMM4;
|
||||
// on the interpreter if the compiler fails.
|
||||
|
||||
static const JitLookup jitLookup[] = {
|
||||
{&VertexDecoder::Step_WeightsU8, &VertexDecoderJitCache::Jit_WeightsU8},
|
||||
{&VertexDecoder::Step_WeightsU16, &VertexDecoderJitCache::Jit_WeightsU16},
|
||||
{&VertexDecoder::Step_WeightsFloat, &VertexDecoderJitCache::Jit_WeightsFloat},
|
||||
{&VertexDecoder::Step_WeightsU8Skin, &VertexDecoderJitCache::Jit_WeightsU8Skin},
|
||||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
|
||||
{&VertexDecoder::Step_WeightsU8ToFloat, &VertexDecoderJitCache::Jit_WeightsU8ToFloat},
|
||||
{&VertexDecoder::Step_WeightsU16ToFloat, &VertexDecoderJitCache::Jit_WeightsU16ToFloat},
|
||||
|
||||
{&VertexDecoder::Step_TcFloat, &VertexDecoderJitCache::Jit_TcFloat},
|
||||
{&VertexDecoder::Step_TcU8ToFloat, &VertexDecoderJitCache::Jit_TcU8ToFloat},
|
||||
{&VertexDecoder::Step_TcU16ToFloat, &VertexDecoderJitCache::Jit_TcU16ToFloat},
|
||||
@@ -333,175 +327,6 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
||||
return (JittedVertexDecoder)start;
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8() {
|
||||
switch (dec_->nweights) {
|
||||
case 1:
|
||||
MOVZX(32, 8, tempReg1, MDisp(srcReg, dec_->weightoff));
|
||||
break;
|
||||
case 2:
|
||||
MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->weightoff));
|
||||
break;
|
||||
case 3:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
AND(32, R(tempReg1), Imm32(0x00FFFFFF));
|
||||
break;
|
||||
case 4:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
break;
|
||||
case 5:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOVZX(32, 8, tempReg2, MDisp(srcReg, dec_->weightoff + 4));
|
||||
break;
|
||||
case 6:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOVZX(32, 16, tempReg2, MDisp(srcReg, dec_->weightoff + 4));
|
||||
break;
|
||||
case 7:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4));
|
||||
AND(32, R(tempReg2), Imm32(0x00FFFFFF));
|
||||
break;
|
||||
case 8:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dec_->nweights <= 4) {
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
} else {
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w1off), R(tempReg2));
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16() {
|
||||
switch (dec_->nweights) {
|
||||
case 1:
|
||||
MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->weightoff));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), Imm32(0));
|
||||
return;
|
||||
|
||||
case 2:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), Imm32(0));
|
||||
return;
|
||||
|
||||
case 3:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOVZX(32, 16, tempReg2, MDisp(srcReg, dec_->weightoff + 4));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), R(tempReg2));
|
||||
return;
|
||||
|
||||
case 4:
|
||||
// Anything above 4 will do 4 here, and then the rest after.
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff));
|
||||
MOV(32, R(tempReg2), MDisp(srcReg, dec_->weightoff + 4));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off), R(tempReg1));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + 4), R(tempReg2));
|
||||
break;
|
||||
}
|
||||
|
||||
// Basic implementation - a short at a time. TODO: Optimize
|
||||
int j;
|
||||
for (j = 4; j < dec_->nweights; j++) {
|
||||
MOV(16, R(tempReg1), MDisp(srcReg, dec_->weightoff + j * 2));
|
||||
MOV(16, MDisp(dstReg, dec_->decFmt.w0off + j * 2), R(tempReg1));
|
||||
}
|
||||
while (j & 3) {
|
||||
MOV(16, MDisp(dstReg, dec_->decFmt.w0off + j * 2), Imm16(0));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8ToFloat() {
|
||||
if (dec_->nweights >= 4) {
|
||||
Jit_AnyU8ToFloat(dec_->weightoff, 32);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
if (dec_->nweights > 4) {
|
||||
Jit_AnyU8ToFloat(dec_->weightoff + 4, (dec_->nweights - 4) * 8);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w1off), XMM3);
|
||||
}
|
||||
} else {
|
||||
Jit_AnyU8ToFloat(dec_->weightoff, dec_->nweights * 8);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU16ToFloat() {
|
||||
if (dec_->nweights >= 4) {
|
||||
Jit_AnyU16ToFloat(dec_->weightoff, 64);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
if (dec_->nweights > 4) {
|
||||
Jit_AnyU16ToFloat(dec_->weightoff + 4 * 2, (dec_->nweights - 4) * 16);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w1off), XMM3);
|
||||
}
|
||||
} else {
|
||||
Jit_AnyU16ToFloat(dec_->weightoff, dec_->nweights * 16);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsFloat() {
|
||||
int j;
|
||||
switch (dec_->nweights) {
|
||||
case 1:
|
||||
// MOVSS: When the source operand is a memory location and destination operand is an XMM register, the three high-order doublewords of the destination operand are cleared to all 0s.
|
||||
MOVSS(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
MOVQ_xmm(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVSS(XMM4, MDisp(srcReg, dec_->weightoff + 16));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVQ_xmm(XMM4, MDisp(srcReg, dec_->weightoff + 16));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
MOVUPS(XMM3, MDisp(srcReg, dec_->weightoff));
|
||||
MOVUPS(XMM4, MDisp(srcReg, dec_->weightoff + 16));
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off), XMM3);
|
||||
MOVUPS(MDisp(dstReg, dec_->decFmt.w0off + 16), XMM4);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (j = 0; j < dec_->nweights; j++) {
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->weightoff + j * 4));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + j * 4), R(tempReg1));
|
||||
}
|
||||
while (j & 3) { // Zero additional weights rounding up to 4.
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.w0off + j * 4), Imm32(0));
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_WeightsU8Skin() {
|
||||
MOV(PTRBITS, R(tempReg2), ImmPtr(&bones));
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device,
|
||||
rasterCache_(4) {
|
||||
device1_ = (ID3D11Device1 *)draw->GetNativeObject(Draw::NativeObject::DEVICE_EX);
|
||||
context1_ = (ID3D11DeviceContext1 *)draw->GetNativeObject(Draw::NativeObject::CONTEXT_EX);
|
||||
decOptions_.expandAllWeightsToFloat = true;
|
||||
decOptions_.expand8BitNormalsToFloat = true;
|
||||
|
||||
InitDeviceObjects();
|
||||
|
||||
@@ -53,7 +53,6 @@ enum {
|
||||
DrawEngineGLES::DrawEngineGLES(Draw::DrawContext *draw) : inputLayoutMap_(16), draw_(draw) {
|
||||
render_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
|
||||
decOptions_.expandAllWeightsToFloat = false;
|
||||
decOptions_.expand8BitNormalsToFloat = false;
|
||||
|
||||
InitDeviceObjects();
|
||||
|
||||
@@ -50,7 +50,6 @@ enum {
|
||||
|
||||
DrawEngineVulkan::DrawEngineVulkan(Draw::DrawContext *draw)
|
||||
: draw_(draw) {
|
||||
decOptions_.expandAllWeightsToFloat = false;
|
||||
decOptions_.expand8BitNormalsToFloat = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user