mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #9176 from hrydgard/always-prescale-uv
Always prescale uv ("texcoord speedhack")
This commit is contained in:
commit
e9bea75a07
32 changed files with 117 additions and 580 deletions
|
@ -730,7 +730,6 @@ static ConfigSetting debuggerSettings[] = {
|
|||
};
|
||||
|
||||
static ConfigSetting speedHackSettings[] = {
|
||||
ReportedConfigSetting("PrescaleUVCoords", &g_Config.bPrescaleUV, true, true, true),
|
||||
ReportedConfigSetting("DisableAlphaTest", &g_Config.bDisableAlphaTest, false, true, true),
|
||||
|
||||
ConfigSetting(false),
|
||||
|
|
|
@ -360,14 +360,7 @@ public:
|
|||
float fAnalogLimiterDeadzone;
|
||||
// GLES backend-specific hacks. Not saved to the ini file, do not add checkboxes. Will be made into
|
||||
// proper options when good enough.
|
||||
// PrescaleUV:
|
||||
// * Applies UV scale/offset when decoding verts. Get rid of some work in the vertex shader,
|
||||
// saves a uniform upload and is a prerequisite for future optimized hybrid
|
||||
// (SW skinning, HW transform) skinning.
|
||||
// * Still has major problems so off by default - need to store tex scale/offset per DeferredDrawCall,
|
||||
// which currently isn't done so if texscale/offset isn't static (like in Tekken 6) things go wrong.
|
||||
bool bPrescaleUV;
|
||||
bool bDisableAlphaTest; // Helps PowerVR immensely, breaks some graphics
|
||||
bool bDisableAlphaTest; // Helps PowerVR performance immensely, breaks some graphics
|
||||
// End GLES hacks.
|
||||
|
||||
// Use the hardware scaler to scale up the image to save fillrate. Similar to Windows' window size, really.
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#define QUAD_INDICES_MAX 65536
|
||||
|
||||
DrawEngineCommon::DrawEngineCommon() : dec_(nullptr) {
|
||||
DrawEngineCommon::DrawEngineCommon() : dec_(nullptr), decOptions_{} {
|
||||
quadIndices_ = new u16[6 * QUAD_INDICES_MAX];
|
||||
decJitCache_ = new VertexDecoderJitCache();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ std::string VertexShaderDesc(const ShaderID &id) {
|
|||
}
|
||||
if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc << "MatUp:" << id.Bits(VS_BIT_MATERIAL_UPDATE, 3) << " ";
|
||||
if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " ";
|
||||
if (id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2)) desc << "TCScale " << id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2) << " ";
|
||||
if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat ";
|
||||
|
||||
// TODO: More...
|
||||
|
@ -119,11 +118,6 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform)
|
|||
|
||||
id.SetBit(VS_BIT_NORM_REVERSE, gstate.areNormalsReversed());
|
||||
id.SetBit(VS_BIT_HAS_TEXCOORD, hasTexcoord);
|
||||
if (doTextureProjection && gstate.getUVProjMode() == GE_PROJMAP_UV) {
|
||||
id.SetBits(VS_BIT_TEXCOORD_FMTSCALE, 2, (vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT); // two bits
|
||||
} else {
|
||||
id.SetBits(VS_BIT_TEXCOORD_FMTSCALE, 2, 3); // float - no scaling
|
||||
}
|
||||
}
|
||||
|
||||
id.SetBit(VS_BIT_FLATSHADE, doFlatShading);
|
||||
|
|
|
@ -37,7 +37,6 @@ enum {
|
|||
VS_BIT_LIGHT3_ENABLE = 55,
|
||||
VS_BIT_LIGHTING_ENABLE = 56,
|
||||
VS_BIT_WEIGHT_FMTSCALE = 57, // only two bits, 1 free after
|
||||
VS_BIT_TEXCOORD_FMTSCALE = 60,
|
||||
VS_BIT_FLATSHADE = 62, // 1 free after
|
||||
};
|
||||
|
||||
|
|
|
@ -146,12 +146,9 @@ void SoftwareTransform(
|
|||
|
||||
float uscale = 1.0f;
|
||||
float vscale = 1.0f;
|
||||
bool scaleUV = false;
|
||||
if (throughmode) {
|
||||
uscale /= gstate_c.curTextureWidth;
|
||||
vscale /= gstate_c.curTextureHeight;
|
||||
} else {
|
||||
scaleUV = !g_Config.bPrescaleUV;
|
||||
}
|
||||
|
||||
bool skinningEnabled = vertTypeIsSkinningEnabled(vertType);
|
||||
|
@ -317,14 +314,9 @@ void SoftwareTransform(
|
|||
switch (gstate.getUVGenMode()) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS: // UV mapping
|
||||
case GE_TEXMAP_UNKNOWN: // Seen in Riviera. Unsure of meaning, but this works.
|
||||
// Texture scale/offset is only performed in this mode.
|
||||
if (scaleUV) {
|
||||
uv[0] = ruv[0]*gstate_c.uv.uScale + gstate_c.uv.uOff;
|
||||
uv[1] = ruv[1]*gstate_c.uv.vScale + gstate_c.uv.vOff;
|
||||
} else {
|
||||
uv[0] = ruv[0];
|
||||
uv[1] = ruv[1];
|
||||
}
|
||||
// We always prescale in the vertex decoder now.
|
||||
uv[0] = ruv[0];
|
||||
uv[1] = ruv[1];
|
||||
uv[2] = 1.0f;
|
||||
break;
|
||||
|
||||
|
|
|
@ -864,13 +864,13 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
|||
u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT;
|
||||
|
||||
UVScale prevUVScale;
|
||||
if (g_Config.bPrescaleUV && (origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
if ((origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
// We scaled during Normalize already so let's turn it off when drawing.
|
||||
prevUVScale = gstate_c.uv;
|
||||
gstate_c.uv.uScale = 1.0f;
|
||||
gstate_c.uv.vScale = 1.0f;
|
||||
gstate_c.uv.uOff = 0;
|
||||
gstate_c.uv.vOff = 0;
|
||||
gstate_c.uv.uOff = 0.0f;
|
||||
gstate_c.uv.vOff = 0.0f;
|
||||
}
|
||||
|
||||
int generatedBytesRead;
|
||||
|
@ -878,7 +878,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
|||
|
||||
DispatchFlush();
|
||||
|
||||
if (g_Config.bPrescaleUV && (origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
if ((origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
gstate_c.uv = prevUVScale;
|
||||
}
|
||||
}
|
||||
|
@ -979,7 +979,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
|||
u32 vertTypeWithIndex16 = (vertType & ~GE_VTYPE_IDX_MASK) | GE_VTYPE_IDX_16BIT;
|
||||
|
||||
UVScale prevUVScale;
|
||||
if (g_Config.bPrescaleUV && (origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
if (origVertType & GE_VTYPE_TC_MASK) {
|
||||
// We scaled during Normalize already so let's turn it off when drawing.
|
||||
prevUVScale = gstate_c.uv;
|
||||
gstate_c.uv.uScale = 1.0f;
|
||||
|
@ -993,7 +993,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
|||
|
||||
DispatchFlush();
|
||||
|
||||
if (g_Config.bPrescaleUV && (origVertType & GE_VTYPE_TC_MASK) != 0) {
|
||||
if (origVertType & GE_VTYPE_TC_MASK) {
|
||||
gstate_c.uv = prevUVScale;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,8 +119,6 @@ static const JitLookup jitLookup[] = {
|
|||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
|
||||
{&VertexDecoder::Step_TcU8, &VertexDecoderJitCache::Jit_TcU8},
|
||||
{&VertexDecoder::Step_TcU16, &VertexDecoderJitCache::Jit_TcU16},
|
||||
{&VertexDecoder::Step_TcFloat, &VertexDecoderJitCache::Jit_TcFloat},
|
||||
{&VertexDecoder::Step_TcU16Double, &VertexDecoderJitCache::Jit_TcU16Double},
|
||||
|
||||
|
@ -563,21 +561,6 @@ void VertexDecoderJitCache::Jit_WeightsFloatSkin() {
|
|||
Jit_ApplyWeights();
|
||||
}
|
||||
|
||||
// Fill last two bytes with zeroes to align to 4 bytes. LDRH does it for us, handy.
|
||||
void VertexDecoderJitCache::Jit_TcU8() {
|
||||
LDRB(tempReg1, srcReg, dec_->tcoff);
|
||||
LDRB(tempReg2, srcReg, dec_->tcoff + 1);
|
||||
ORR(tempReg1, tempReg1, Operand2(tempReg2, ST_LSL, 8));
|
||||
STR(tempReg1, dstReg, dec_->decFmt.uvoff);
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU16() {
|
||||
LDRH(tempReg1, srcReg, dec_->tcoff);
|
||||
LDRH(tempReg2, srcReg, dec_->tcoff + 2);
|
||||
ORR(tempReg1, tempReg1, Operand2(tempReg2, ST_LSL, 16));
|
||||
STR(tempReg1, dstReg, dec_->decFmt.uvoff);
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcFloat() {
|
||||
LDR(tempReg1, srcReg, dec_->tcoff);
|
||||
LDR(tempReg2, srcReg, dec_->tcoff + 4);
|
||||
|
|
|
@ -92,8 +92,6 @@ static const JitLookup jitLookup[] = {
|
|||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
|
||||
{&VertexDecoder::Step_TcU8, &VertexDecoderJitCache::Jit_TcU8},
|
||||
{&VertexDecoder::Step_TcU16, &VertexDecoderJitCache::Jit_TcU16},
|
||||
{&VertexDecoder::Step_TcFloat, &VertexDecoderJitCache::Jit_TcFloat},
|
||||
{&VertexDecoder::Step_TcU16Double, &VertexDecoderJitCache::Jit_TcU16Double},
|
||||
{&VertexDecoder::Step_TcU8Prescale, &VertexDecoderJitCache::Jit_TcU8Prescale},
|
||||
|
@ -578,16 +576,6 @@ void VertexDecoderJitCache::Jit_Color5551() {
|
|||
CSEL(fullAlphaReg, fullAlphaReg, WZR, CC_EQ);
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU8() {
|
||||
LDURH(tempReg1, srcReg, dec_->tcoff);
|
||||
STR(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.uvoff);
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU16() {
|
||||
LDUR(tempReg1, srcReg, dec_->tcoff);
|
||||
STR(INDEX_UNSIGNED, tempReg1, dstReg, dec_->decFmt.uvoff);
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU16Through() {
|
||||
LDRH(INDEX_UNSIGNED, tempReg1, srcReg, dec_->tcoff);
|
||||
LDRH(INDEX_UNSIGNED, tempReg2, srcReg, dec_->tcoff + 2);
|
||||
|
|
|
@ -264,14 +264,6 @@ void VertexDecoder::Step_WeightsFloatSkin() const
|
|||
}
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_TcU8() const
|
||||
{
|
||||
// u32 to write two bytes of zeroes for free.
|
||||
u32 *uv = (u32*)(decoded_ + decFmt.uvoff);
|
||||
const u16 *uvdata = (const u16*)(ptr_ + tcoff);
|
||||
*uv = *uvdata;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_TcU8ToFloat() const
|
||||
{
|
||||
// u32 to write two bytes of zeroes for free.
|
||||
|
@ -281,14 +273,6 @@ void VertexDecoder::Step_TcU8ToFloat() const
|
|||
uv[1] = uvdata[1] * (1.0f / 128.0f);
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_TcU16() const
|
||||
{
|
||||
u32 *uv = (u32 *)(decoded_ + decFmt.uvoff);
|
||||
// TODO: Fix big-endian without losing the optimization
|
||||
const u32 *uvdata = (const u32*)(ptr_ + tcoff);
|
||||
*uv = *uvdata;
|
||||
}
|
||||
|
||||
void VertexDecoder::Step_TcU16ToFloat() const
|
||||
{
|
||||
float *uv = (float *)(decoded_ + decFmt.uvoff);
|
||||
|
@ -903,13 +887,6 @@ static const StepFunction wtstep_skin[4] = {
|
|||
&VertexDecoder::Step_WeightsFloatSkin,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8,
|
||||
&VertexDecoder::Step_TcU16,
|
||||
&VertexDecoder::Step_TcFloat,
|
||||
};
|
||||
|
||||
static const StepFunction tcstepToFloat[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8ToFloat,
|
||||
|
@ -973,13 +950,6 @@ static const StepFunction tcstep_morph_remasterToFloat[4] = {
|
|||
&VertexDecoder::Step_TcFloatMorph,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep_through[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8,
|
||||
&VertexDecoder::Step_TcU16Through,
|
||||
&VertexDecoder::Step_TcFloatThrough,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep_throughToFloat[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8ToFloat,
|
||||
|
@ -987,14 +957,6 @@ static const StepFunction tcstep_throughToFloat[4] = {
|
|||
&VertexDecoder::Step_TcFloatThrough,
|
||||
};
|
||||
|
||||
// Some HD Remaster games double the u16 texture coordinates.
|
||||
static const StepFunction tcstep_remaster[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8,
|
||||
&VertexDecoder::Step_TcU16Double,
|
||||
&VertexDecoder::Step_TcFloat,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep_remasterToFloat[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8ToFloat,
|
||||
|
@ -1002,13 +964,6 @@ static const StepFunction tcstep_remasterToFloat[4] = {
|
|||
&VertexDecoder::Step_TcFloat,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep_through_remaster[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8,
|
||||
&VertexDecoder::Step_TcU16ThroughDouble,
|
||||
&VertexDecoder::Step_TcFloatThrough,
|
||||
};
|
||||
|
||||
static const StepFunction tcstep_through_remasterToFloat[4] = {
|
||||
0,
|
||||
&VertexDecoder::Step_TcU8ToFloat,
|
||||
|
@ -1173,41 +1128,21 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
|
|||
biggest = tcalign[tc];
|
||||
|
||||
// NOTE: That we check getUVGenMode here means that we must include it in the decoder ID!
|
||||
if (g_Config.bPrescaleUV && !throughmode && (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN)) {
|
||||
if (!throughmode && (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN)) {
|
||||
if (g_DoubleTextureCoordinates)
|
||||
steps_[numSteps_++] = morphcount == 1 ? tcstep_prescale_remaster[tc] : tcstep_prescale_morph_remaster[tc];
|
||||
else
|
||||
steps_[numSteps_++] = morphcount == 1 ? tcstep_prescale[tc] : tcstep_prescale_morph[tc];
|
||||
decFmt.uvfmt = DEC_FLOAT_2;
|
||||
} else {
|
||||
if (options.expandAllUVtoFloat) {
|
||||
if (morphcount != 1 && !throughmode)
|
||||
steps_[numSteps_++] = g_DoubleTextureCoordinates ? tcstep_morph_remasterToFloat[tc] : tcstep_morphToFloat[tc];
|
||||
else if (g_DoubleTextureCoordinates)
|
||||
steps_[numSteps_++] = throughmode ? tcstep_through_remasterToFloat[tc] : tcstep_remasterToFloat[tc];
|
||||
else
|
||||
steps_[numSteps_++] = throughmode ? tcstep_throughToFloat[tc] : tcstepToFloat[tc];
|
||||
decFmt.uvfmt = DEC_FLOAT_2;
|
||||
} else {
|
||||
if (morphcount != 1 && !throughmode)
|
||||
steps_[numSteps_++] = g_DoubleTextureCoordinates ? tcstep_morph_remaster[tc] : tcstep_morph[tc];
|
||||
else if (g_DoubleTextureCoordinates)
|
||||
steps_[numSteps_++] = throughmode ? tcstep_through_remaster[tc] : tcstep_remaster[tc];
|
||||
else
|
||||
steps_[numSteps_++] = throughmode ? tcstep_through[tc] : tcstep[tc];
|
||||
|
||||
switch (tc) {
|
||||
case GE_VTYPE_TC_8BIT >> GE_VTYPE_TC_SHIFT:
|
||||
decFmt.uvfmt = throughmode ? DEC_U8A_2 : DEC_U8_2;
|
||||
break;
|
||||
case GE_VTYPE_TC_16BIT >> GE_VTYPE_TC_SHIFT:
|
||||
decFmt.uvfmt = throughmode ? DEC_U16A_2 : DEC_U16_2;
|
||||
break;
|
||||
case GE_VTYPE_TC_FLOAT >> GE_VTYPE_TC_SHIFT:
|
||||
decFmt.uvfmt = DEC_FLOAT_2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We now always expand UV to float.
|
||||
if (morphcount != 1 && !throughmode)
|
||||
steps_[numSteps_++] = g_DoubleTextureCoordinates ? tcstep_morph_remasterToFloat[tc] : tcstep_morphToFloat[tc];
|
||||
else if (g_DoubleTextureCoordinates)
|
||||
steps_[numSteps_++] = throughmode ? tcstep_through_remasterToFloat[tc] : tcstep_remasterToFloat[tc];
|
||||
else
|
||||
steps_[numSteps_++] = throughmode ? tcstep_throughToFloat[tc] : tcstepToFloat[tc];
|
||||
decFmt.uvfmt = DEC_FLOAT_2;
|
||||
}
|
||||
|
||||
decFmt.uvoff = decOff;
|
||||
|
|
|
@ -443,7 +443,6 @@ int TranslateNumBones(int bones);
|
|||
typedef void(*JittedVertexDecoder)(const u8 *src, u8 *dst, int count);
|
||||
|
||||
struct VertexDecoderOptions {
|
||||
bool expandAllUVtoFloat;
|
||||
bool expandAllWeightsToFloat;
|
||||
bool expand8BitNormalsToFloat;
|
||||
};
|
||||
|
@ -477,8 +476,6 @@ public:
|
|||
void Step_WeightsU16Skin() const;
|
||||
void Step_WeightsFloatSkin() const;
|
||||
|
||||
void Step_TcU8() const;
|
||||
void Step_TcU16() const;
|
||||
void Step_TcU8ToFloat() const;
|
||||
void Step_TcU16ToFloat() const;
|
||||
void Step_TcFloat() const;
|
||||
|
@ -633,9 +630,7 @@ public:
|
|||
void Jit_WeightsU16Skin();
|
||||
void Jit_WeightsFloatSkin();
|
||||
|
||||
void Jit_TcU8();
|
||||
void Jit_TcU8ToFloat();
|
||||
void Jit_TcU16();
|
||||
void Jit_TcU16ToFloat();
|
||||
void Jit_TcFloat();
|
||||
|
||||
|
|
|
@ -97,8 +97,6 @@ static const JitLookup jitLookup[] = {
|
|||
{&VertexDecoder::Step_WeightsU16Skin, &VertexDecoderJitCache::Jit_WeightsU16Skin},
|
||||
{&VertexDecoder::Step_WeightsFloatSkin, &VertexDecoderJitCache::Jit_WeightsFloatSkin},
|
||||
|
||||
{&VertexDecoder::Step_TcU8, &VertexDecoderJitCache::Jit_TcU8},
|
||||
{&VertexDecoder::Step_TcU16, &VertexDecoderJitCache::Jit_TcU16},
|
||||
{&VertexDecoder::Step_TcU8ToFloat, &VertexDecoderJitCache::Jit_TcU8ToFloat},
|
||||
{&VertexDecoder::Step_TcU16ToFloat, &VertexDecoderJitCache::Jit_TcU16ToFloat},
|
||||
{&VertexDecoder::Step_TcFloat, &VertexDecoderJitCache::Jit_TcFloat},
|
||||
|
@ -687,17 +685,6 @@ void VertexDecoderJitCache::Jit_WeightsFloatSkin() {
|
|||
}
|
||||
}
|
||||
|
||||
// Fill last two bytes with zeroes to align to 4 bytes. MOVZX does it for us, handy.
|
||||
void VertexDecoderJitCache::Jit_TcU8() {
|
||||
MOVZX(32, 16, tempReg1, MDisp(srcReg, dec_->tcoff));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.uvoff), R(tempReg1));
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU16() {
|
||||
MOV(32, R(tempReg1), MDisp(srcReg, dec_->tcoff));
|
||||
MOV(32, MDisp(dstReg, dec_->decFmt.uvoff), R(tempReg1));
|
||||
}
|
||||
|
||||
void VertexDecoderJitCache::Jit_TcU8ToFloat() {
|
||||
Jit_AnyU8ToFloat(dec_->tcoff, 16);
|
||||
MOVQ_xmm(MDisp(dstReg, dec_->decFmt.uvoff), XMM3);
|
||||
|
|
|
@ -89,12 +89,8 @@ DrawEngineDX9::DrawEngineDX9()
|
|||
vertexCountInDrawCalls(0),
|
||||
decodeCounter_(0),
|
||||
dcid_(0),
|
||||
uvScale(0),
|
||||
fboTexNeedBind_(false),
|
||||
fboTexBound_(false) {
|
||||
|
||||
memset(&decOptions_, 0, sizeof(decOptions_));
|
||||
decOptions_.expandAllUVtoFloat = true;
|
||||
decOptions_.expandAllWeightsToFloat = true;
|
||||
decOptions_.expand8BitNormalsToFloat = true;
|
||||
|
||||
|
@ -108,9 +104,6 @@ DrawEngineDX9::DrawEngineDX9()
|
|||
transformed = (TransformedVertex *)AllocateMemoryPages(TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
|
||||
transformedExpanded = (TransformedVertex *)AllocateMemoryPages(3 * TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
}
|
||||
indexGen.Setup(decIndex);
|
||||
|
||||
InitDeviceObjects();
|
||||
|
@ -128,8 +121,6 @@ DrawEngineDX9::~DrawEngineDX9() {
|
|||
decl->second->Release();
|
||||
}
|
||||
}
|
||||
|
||||
delete [] uvScale;
|
||||
}
|
||||
|
||||
void DrawEngineDX9::InitDeviceObjects() {
|
||||
|
@ -305,9 +296,7 @@ void DrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, in
|
|||
dc.indexUpperBound = vertexCount - 1;
|
||||
}
|
||||
|
||||
if (uvScale) {
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
}
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
|
||||
numDrawCalls++;
|
||||
vertexCountInDrawCalls += vertexCount;
|
||||
|
@ -327,18 +316,13 @@ void DrawEngineDX9::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, in
|
|||
}
|
||||
|
||||
void DrawEngineDX9::DecodeVerts() {
|
||||
if (uvScale) {
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
gstate_c.uv = uvScale[decodeCounter_];
|
||||
DecodeVertsStep();
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
} else {
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
DecodeVertsStep();
|
||||
}
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
gstate_c.uv = uvScale[decodeCounter_];
|
||||
DecodeVertsStep();
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
|
||||
// Sanity check
|
||||
if (indexGen.Prim() < 0) {
|
||||
ERROR_LOG_REPORT(G3D, "DecodeVerts: Failed to deduce prim: %i", indexGen.Prim());
|
||||
|
@ -373,26 +357,15 @@ void DrawEngineDX9::DecodeVertsStep() {
|
|||
// Expand the lower and upper bounds as we go.
|
||||
int lastMatch = i;
|
||||
const int total = numDrawCalls;
|
||||
if (uvScale) {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
} else {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
|
||||
// 2. Loop through the drawcalls, translating indices as we go.
|
||||
|
@ -918,13 +891,6 @@ void DrawEngineDX9::Resized() {
|
|||
delete iter->second;
|
||||
}
|
||||
decoderMap_.clear();
|
||||
|
||||
if (g_Config.bPrescaleUV && !uvScale) {
|
||||
uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
} else if (!g_Config.bPrescaleUV && uvScale) {
|
||||
delete uvScale;
|
||||
uvScale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawEngineDX9::IsCodePtrVertexDecoder(const u8 *ptr) const {
|
||||
|
|
|
@ -242,7 +242,7 @@ private:
|
|||
int decodeCounter_;
|
||||
u32 dcid_;
|
||||
|
||||
UVScale *uvScale;
|
||||
UVScale uvScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
|
||||
bool fboTexNeedBind_;
|
||||
bool fboTexBound_;
|
||||
|
|
|
@ -85,10 +85,11 @@ static const CommandTableEntry commandTable[] = {
|
|||
|
||||
// Changes that dirty texture scaling.
|
||||
{ GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexMapMode },
|
||||
{ GE_CMD_TEXSCALEU, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexScaleU },
|
||||
{ GE_CMD_TEXSCALEV, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexScaleV },
|
||||
{ GE_CMD_TEXOFFSETU, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexOffsetU },
|
||||
{ GE_CMD_TEXOFFSETV, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexOffsetV },
|
||||
|
||||
{ GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexScaleU },
|
||||
{ GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexScaleV },
|
||||
{ GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexOffsetU },
|
||||
{ GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, &GPU_DX9::Execute_TexOffsetV },
|
||||
|
||||
// Changes that dirty the current texture. Really should be possible to avoid executing these if we compile
|
||||
// by adding some more flags.
|
||||
|
@ -450,18 +451,6 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx)
|
|||
}
|
||||
|
||||
void GPU_DX9::UpdateCmdInfo() {
|
||||
if (g_Config.bPrescaleUV) {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
} else {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
}
|
||||
|
||||
if (g_Config.bSoftwareSkinning) {
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPU_DX9::Execute_VertexTypeSkinning;
|
||||
|
|
|
@ -431,52 +431,11 @@ void ShaderManagerDX9::VSUpdateUniforms(int dirtyUniforms) {
|
|||
const int h = gstate.getTextureHeight(0);
|
||||
const float widthFactor = (float)w * invW;
|
||||
const float heightFactor = (float)h * invH;
|
||||
|
||||
float uvscaleoff[4];
|
||||
|
||||
switch (gstate.getUVGenMode()) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS:
|
||||
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
|
||||
case GE_TEXMAP_UNKNOWN:
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// We are here but are prescaling UV in the decoder? Let's do the same as in the other case
|
||||
// except consider *Scale and *Off to be 1 and 0.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
} else {
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
|
||||
uvscaleoff[1] = gstate_c.uv.vScale * heightFactor;
|
||||
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
|
||||
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
|
||||
}
|
||||
break;
|
||||
|
||||
// These two work the same whether or not we prescale UV.
|
||||
|
||||
case GE_TEXMAP_TEXTURE_MATRIX:
|
||||
// We cannot bake the UV coord scale factor in here, as we apply a matrix multiplication
|
||||
// before this is applied, and the matrix multiplication may contain translation. In this case
|
||||
// the translation will be scaled which breaks faces in Hexyz Force for example.
|
||||
// So I've gone back to applying the scale factor in the shader.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
case GE_TEXMAP_ENVIRONMENT_MAP:
|
||||
// In this mode we only use uvscaleoff to scale to the texture size.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG_REPORT(G3D, "Unexpected UV gen mode: %d", gstate.getUVGenMode());
|
||||
}
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
VSSetFloatArray(CONST_VS_UVSCALEOFFSET, uvscaleoff, 4);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
|
|||
bool enableLighting = id.Bit(VS_BIT_LIGHTING_ENABLE);
|
||||
int matUpdate = id.Bits(VS_BIT_MATERIAL_UPDATE, 3);
|
||||
|
||||
bool prescale = g_Config.bPrescaleUV && !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
bool scaleUV = !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
|
||||
DoLightComputation doLight[4] = { LIGHT_OFF, LIGHT_OFF, LIGHT_OFF, LIGHT_OFF };
|
||||
if (useHWTransform) {
|
||||
|
@ -503,7 +503,7 @@ void GenerateVertexShaderDX9(const ShaderID &id, char *buffer) {
|
|||
switch (uvGenMode) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS: // Scale-offset. Easy.
|
||||
case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works.
|
||||
if (prescale) {
|
||||
if (scaleUV) {
|
||||
if (hasTexcoord) {
|
||||
WRITE(p, " Out.v_texcoord = In.texcoord * u_uvscaleoffset.xy;\n");
|
||||
} else {
|
||||
|
|
|
@ -126,13 +126,10 @@ DrawEngineGLES::DrawEngineGLES()
|
|||
vertexCountInDrawCalls(0),
|
||||
decodeCounter_(0),
|
||||
dcid_(0),
|
||||
uvScale(nullptr),
|
||||
fboTexNeedBind_(false),
|
||||
fboTexBound_(false) {
|
||||
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
|
||||
bufferDecimationCounter_ = VERTEXCACHE_NAME_DECIMATION_INTERVAL;
|
||||
memset(&decOptions_, 0, sizeof(decOptions_));
|
||||
decOptions_.expandAllUVtoFloat = false;
|
||||
// Allocate nicely aligned memory. Maybe graphics drivers will
|
||||
// appreciate it.
|
||||
// All this is a LOT of memory, need to see if we can cut down somehow.
|
||||
|
@ -142,9 +139,6 @@ DrawEngineGLES::DrawEngineGLES()
|
|||
transformed = (TransformedVertex *)AllocateMemoryPages(TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
|
||||
transformedExpanded = (TransformedVertex *)AllocateMemoryPages(3 * TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
}
|
||||
indexGen.Setup(decIndex);
|
||||
|
||||
InitDeviceObjects();
|
||||
|
@ -160,7 +154,6 @@ DrawEngineGLES::~DrawEngineGLES() {
|
|||
FreeMemoryPages(transformedExpanded, 3 * TRANSFORMED_VERTEX_BUFFER_SIZE);
|
||||
|
||||
unregister_gl_resource_holder(this);
|
||||
delete [] uvScale;
|
||||
}
|
||||
|
||||
void DrawEngineGLES::RestoreVAO() {
|
||||
|
@ -327,9 +320,7 @@ void DrawEngineGLES::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, i
|
|||
dc.indexUpperBound = vertexCount - 1;
|
||||
}
|
||||
|
||||
if (uvScale) {
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
}
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
|
||||
numDrawCalls++;
|
||||
vertexCountInDrawCalls += vertexCount;
|
||||
|
@ -349,18 +340,12 @@ void DrawEngineGLES::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, i
|
|||
}
|
||||
|
||||
void DrawEngineGLES::DecodeVerts() {
|
||||
if (uvScale) {
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
gstate_c.uv = uvScale[decodeCounter_];
|
||||
DecodeVertsStep();
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
} else {
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
DecodeVertsStep();
|
||||
}
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (; decodeCounter_ < numDrawCalls; decodeCounter_++) {
|
||||
gstate_c.uv = uvScale[decodeCounter_];
|
||||
DecodeVertsStep();
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
// Sanity check
|
||||
if (indexGen.Prim() < 0) {
|
||||
ERROR_LOG_REPORT(G3D, "DecodeVerts: Failed to deduce prim: %i", indexGen.Prim());
|
||||
|
@ -396,26 +381,15 @@ void DrawEngineGLES::DecodeVertsStep() {
|
|||
// Expand the lower and upper bounds as we go.
|
||||
int lastMatch = i;
|
||||
const int total = numDrawCalls;
|
||||
if (uvScale) {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
if (memcmp(&uvScale[j], &uvScale[i], sizeof(uvScale[0])) != 0)
|
||||
break;
|
||||
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
} else {
|
||||
for (int j = i + 1; j < total; ++j) {
|
||||
if (drawCalls[j].verts != dc.verts)
|
||||
break;
|
||||
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
indexLowerBound = std::min(indexLowerBound, (int)drawCalls[j].indexLowerBound);
|
||||
indexUpperBound = std::max(indexUpperBound, (int)drawCalls[j].indexUpperBound);
|
||||
lastMatch = j;
|
||||
}
|
||||
|
||||
// 2. Loop through the drawcalls, translating indices as we go.
|
||||
|
@ -543,9 +517,7 @@ ReliableHashType DrawEngineGLES::ComputeHash() {
|
|||
i = lastMatch;
|
||||
}
|
||||
}
|
||||
if (uvScale) {
|
||||
fullhash += DoReliableHash(&uvScale[0], sizeof(uvScale[0]) * numDrawCalls, 0x0123e658);
|
||||
}
|
||||
fullhash += DoReliableHash(&uvScale[0], sizeof(uvScale[0]) * numDrawCalls, 0x0123e658);
|
||||
|
||||
return fullhash;
|
||||
}
|
||||
|
@ -1031,13 +1003,6 @@ void DrawEngineGLES::Resized() {
|
|||
delete iter->second;
|
||||
}
|
||||
decoderMap_.clear();
|
||||
|
||||
if (g_Config.bPrescaleUV && !uvScale) {
|
||||
uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
} else if (!g_Config.bPrescaleUV && uvScale) {
|
||||
delete uvScale;
|
||||
uvScale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint DrawEngineGLES::BindBuffer(const void *p, size_t sz) {
|
||||
|
|
|
@ -268,7 +268,7 @@ private:
|
|||
int decodeCounter_;
|
||||
u32 dcid_;
|
||||
|
||||
UVScale *uvScale;
|
||||
UVScale uvScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
|
||||
bool fboTexNeedBind_;
|
||||
bool fboTexBound_;
|
||||
|
|
|
@ -722,18 +722,6 @@ inline void GPU_GLES::UpdateVsyncInterval(bool force) {
|
|||
}
|
||||
|
||||
void GPU_GLES::UpdateCmdInfo() {
|
||||
if (g_Config.bPrescaleUV) {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
} else {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
}
|
||||
|
||||
if (g_Config.bSoftwareSkinning) {
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPU_GLES::Execute_VertexTypeSkinning;
|
||||
|
|
|
@ -536,55 +536,11 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) {
|
|||
const int h = gstate.getTextureHeight(0);
|
||||
const float widthFactor = (float)w * invW;
|
||||
const float heightFactor = (float)h * invH;
|
||||
|
||||
static const float rescale[4] = {1.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
|
||||
const float factor = rescale[(vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
|
||||
|
||||
float uvscaleoff[4];
|
||||
|
||||
switch (gstate.getUVGenMode()) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS:
|
||||
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
|
||||
case GE_TEXMAP_UNKNOWN:
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// We are here but are prescaling UV in the decoder? Let's do the same as in the other case
|
||||
// except consider *Scale and *Off to be 1 and 0.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
} else {
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * factor * widthFactor;
|
||||
uvscaleoff[1] = gstate_c.uv.vScale * factor * heightFactor;
|
||||
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
|
||||
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
|
||||
}
|
||||
break;
|
||||
|
||||
// These two work the same whether or not we prescale UV.
|
||||
|
||||
case GE_TEXMAP_TEXTURE_MATRIX:
|
||||
// We cannot bake the UV coord scale factor in here, as we apply a matrix multiplication
|
||||
// before this is applied, and the matrix multiplication may contain translation. In this case
|
||||
// the translation will be scaled which breaks faces in Hexyz Force for example.
|
||||
// So I've gone back to applying the scale factor in the shader.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
case GE_TEXMAP_ENVIRONMENT_MAP:
|
||||
// In this mode we only use uvscaleoff to scale to the texture size.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG_REPORT(G3D, "Unexpected UV gen mode: %d", gstate.getUVGenMode());
|
||||
}
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
glUniform4fv(u_uvscaleoffset, 1, uvscaleoff);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,6 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3);
|
||||
WRITE(p, "%s", boneWeightDecl[numBoneWeights]);
|
||||
}
|
||||
int texFmtScale = id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2);
|
||||
|
||||
if (useHWTransform)
|
||||
WRITE(p, "%s vec3 position;\n", attribute);
|
||||
|
@ -221,7 +220,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
// Add all the uniforms we'll need to transform properly.
|
||||
}
|
||||
|
||||
bool prescale = g_Config.bPrescaleUV && !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
bool scaleUV = !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
|
||||
if (useHWTransform) {
|
||||
// When transforming by hardware, we need a great deal more uniforms...
|
||||
|
@ -584,7 +583,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
switch (uvGenMode) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS: // Scale-offset. Easy.
|
||||
case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works.
|
||||
if (prescale) {
|
||||
if (scaleUV) {
|
||||
if (hasTexcoord) {
|
||||
WRITE(p, " v_texcoord = texcoord * u_uvscaleoffset.xy;\n");
|
||||
} else {
|
||||
|
@ -610,9 +609,7 @@ void GenerateVertexShader(const ShaderID &id, char *buffer) {
|
|||
{
|
||||
// prescale is false here.
|
||||
if (hasTexcoord) {
|
||||
static const char *rescaleuv[4] = {"", " * 1.9921875", " * 1.999969482421875", ""}; // 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
|
||||
const char *factor = rescaleuv[texFmtScale];
|
||||
temp_tc = StringFromFormat("vec4(texcoord.xy %s, 0.0, 1.0)", factor);
|
||||
temp_tc = "vec4(texcoord.xy, 0.0, 1.0)";
|
||||
} else {
|
||||
temp_tc = "vec4(0.0, 0.0, 0.0, 1.0)";
|
||||
}
|
||||
|
|
|
@ -1189,18 +1189,6 @@ void DrawTriangleSlice(
|
|||
Vec2<int> d01((int)v0.screenpos.x - (int)v1.screenpos.x, (int)v0.screenpos.y - (int)v1.screenpos.y);
|
||||
Vec2<int> d02((int)v0.screenpos.x - (int)v2.screenpos.x, (int)v0.screenpos.y - (int)v2.screenpos.y);
|
||||
Vec2<int> d12((int)v1.screenpos.x - (int)v2.screenpos.x, (int)v1.screenpos.y - (int)v2.screenpos.y);
|
||||
float texScaleU = gstate_c.uv.uScale;
|
||||
float texScaleV = gstate_c.uv.vScale;
|
||||
float texOffsetU = gstate_c.uv.uOff;
|
||||
float texOffsetV = gstate_c.uv.vOff;
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// Already applied during vertex decode.
|
||||
texScaleU = 1.0f;
|
||||
texScaleV = 1.0f;
|
||||
texOffsetU = 0.0f;
|
||||
texOffsetV = 0.0f;
|
||||
}
|
||||
|
||||
int bias0 = IsRightSideOrFlatBottomLine(v0.screenpos.xy(), v1.screenpos.xy(), v2.screenpos.xy()) ? -1 : 0;
|
||||
int bias1 = IsRightSideOrFlatBottomLine(v1.screenpos.xy(), v2.screenpos.xy(), v0.screenpos.xy()) ? -1 : 0;
|
||||
|
@ -1294,8 +1282,6 @@ void DrawTriangleSlice(
|
|||
// Texture coordinate interpolation must definitely be perspective-correct.
|
||||
float s = 0, t = 0;
|
||||
GetTextureCoordinates(v0, v1, v2, w0, w1, w2, s, t);
|
||||
s = s * texScaleU + texOffsetU;
|
||||
t = t * texScaleV + texOffsetV;
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
}
|
||||
}
|
||||
|
@ -1421,27 +1407,7 @@ void DrawPoint(const VertexData &v0)
|
|||
}
|
||||
}
|
||||
|
||||
if (gstate.isModeThrough()) {
|
||||
// TODO: Is it really this simple?
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
} else {
|
||||
float texScaleU = gstate_c.uv.uScale;
|
||||
float texScaleV = gstate_c.uv.vScale;
|
||||
float texOffsetU = gstate_c.uv.uOff;
|
||||
float texOffsetV = gstate_c.uv.vOff;
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// Already applied during vertex decode.
|
||||
texScaleU = 1.0f;
|
||||
texScaleV = 1.0f;
|
||||
texOffsetU = 0.0f;
|
||||
texOffsetV = 0.0f;
|
||||
}
|
||||
|
||||
s = s * texScaleU + texOffsetU;
|
||||
t = t * texScaleV + texOffsetV;
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
}
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
}
|
||||
|
||||
if (!clearMode)
|
||||
|
@ -1516,19 +1482,6 @@ void DrawLine(const VertexData &v0, const VertexData &v1)
|
|||
}
|
||||
}
|
||||
|
||||
float texScaleU = gstate_c.uv.uScale;
|
||||
float texScaleV = gstate_c.uv.vScale;
|
||||
float texOffsetU = gstate_c.uv.uOff;
|
||||
float texOffsetV = gstate_c.uv.vOff;
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// Already applied during vertex decode.
|
||||
texScaleU = 1.0f;
|
||||
texScaleV = 1.0f;
|
||||
texOffsetU = 0.0f;
|
||||
texOffsetV = 0.0f;
|
||||
}
|
||||
|
||||
float x = a.x;
|
||||
float y = a.y;
|
||||
float z = a.z;
|
||||
|
@ -1553,14 +1506,7 @@ void DrawLine(const VertexData &v0, const VertexData &v1)
|
|||
float t = tc.t();
|
||||
|
||||
if (gstate.isTextureMapEnabled() && !clearMode) {
|
||||
if (gstate.isModeThrough()) {
|
||||
// TODO: Is it really this simple?
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
} else {
|
||||
s = s * texScaleU + texOffsetU;
|
||||
t = t * texScaleV + texOffsetV;
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
}
|
||||
ApplyTexturing(prim_color, s, t, maxTexLevel, magFilt, texptr, texbufwidthbits);
|
||||
}
|
||||
|
||||
if (!clearMode)
|
||||
|
|
|
@ -217,9 +217,7 @@ int TransformUnit::patchBufferSize_ = 0;
|
|||
|
||||
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type) {
|
||||
VertexDecoder vdecoder;
|
||||
VertexDecoderOptions options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.expandAllUVtoFloat = false;
|
||||
VertexDecoderOptions options{};
|
||||
vdecoder.SetVertexType(vertex_type, options);
|
||||
const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();
|
||||
|
||||
|
@ -310,9 +308,7 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
|
|||
{
|
||||
// TODO: Cache VertexDecoder objects
|
||||
VertexDecoder vdecoder;
|
||||
VertexDecoderOptions options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.expandAllUVtoFloat = false;
|
||||
VertexDecoderOptions options{};
|
||||
vdecoder.SetVertexType(vertex_type, options);
|
||||
const DecVtxFormat& vtxfmt = vdecoder.GetDecVtxFmt();
|
||||
|
||||
|
@ -569,9 +565,7 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVert
|
|||
simpleVertices.resize(indexUpperBound + 1);
|
||||
|
||||
VertexDecoder vdecoder;
|
||||
VertexDecoderOptions options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.expandAllUVtoFloat = false; // TODO: True should be fine here
|
||||
VertexDecoderOptions options{};
|
||||
vdecoder.SetVertexType(gstate.vertType, options);
|
||||
DrawEngineCommon::NormalizeVertices((u8 *)(&simpleVertices[0]), (u8 *)(&temp_buffer[0]), Memory::GetPointer(gstate_c.vertexAddr), &vdecoder, indexLowerBound, indexUpperBound, gstate.vertType);
|
||||
|
||||
|
|
|
@ -71,16 +71,12 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan)
|
|||
framebufferManager_(nullptr),
|
||||
numDrawCalls(0),
|
||||
vertexCountInDrawCalls(0),
|
||||
uvScale(nullptr),
|
||||
fboTexNeedBind_(false),
|
||||
fboTexBound_(false),
|
||||
curFrame_(0),
|
||||
nullTexture_(nullptr) {
|
||||
nullTexture_(nullptr),
|
||||
stats_{} {
|
||||
|
||||
memset(&stats_, 0, sizeof(stats_));
|
||||
|
||||
memset(&decOptions_, 0, sizeof(decOptions_));
|
||||
decOptions_.expandAllUVtoFloat = false; // this may be a good idea though.
|
||||
decOptions_.expandAllWeightsToFloat = false;
|
||||
decOptions_.expand8BitNormalsToFloat = false;
|
||||
|
||||
|
@ -95,10 +91,6 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan)
|
|||
|
||||
indexGen.Setup(decIndex);
|
||||
|
||||
if (g_Config.bPrescaleUV) {
|
||||
uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
}
|
||||
|
||||
InitDeviceObjects();
|
||||
}
|
||||
|
||||
|
@ -202,7 +194,6 @@ DrawEngineVulkan::~DrawEngineVulkan() {
|
|||
FreeMemoryPages(transformedExpanded, 3 * TRANSFORMED_VERTEX_BUFFER_SIZE);
|
||||
|
||||
DestroyDeviceObjects();
|
||||
delete[] uvScale;
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) {
|
||||
|
@ -358,9 +349,7 @@ void DrawEngineVulkan::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim,
|
|||
dc.indexUpperBound = vertexCount - 1;
|
||||
}
|
||||
|
||||
if (uvScale) {
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
}
|
||||
uvScale[numDrawCalls] = gstate_c.uv;
|
||||
|
||||
numDrawCalls++;
|
||||
vertexCountInDrawCalls += vertexCount;
|
||||
|
@ -480,18 +469,12 @@ void DrawEngineVulkan::DecodeVerts(VulkanPushBuffer *push, uint32_t *bindOffset,
|
|||
dest = (u8 *)push->Push(vertsToDecode * dec_->GetDecVtxFmt().stride, bindOffset, vkbuf);
|
||||
}
|
||||
|
||||
if (uvScale) {
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (int i = 0; i < numDrawCalls; i++) {
|
||||
gstate_c.uv = uvScale[i];
|
||||
DecodeVertsStep(dest, i, decodedVerts); // Note that this can modify i
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
} else {
|
||||
for (int i = 0; i < numDrawCalls; i++) {
|
||||
DecodeVertsStep(dest, i, decodedVerts); // Note that this can modify i
|
||||
}
|
||||
const UVScale origUV = gstate_c.uv;
|
||||
for (int i = 0; i < numDrawCalls; i++) {
|
||||
gstate_c.uv = uvScale[i];
|
||||
DecodeVertsStep(dest, i, decodedVerts); // Note that this can modify i
|
||||
}
|
||||
gstate_c.uv = origUV;
|
||||
|
||||
// Sanity check
|
||||
if (indexGen.Prim() < 0) {
|
||||
|
|
|
@ -265,7 +265,7 @@ private:
|
|||
DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS];
|
||||
int numDrawCalls;
|
||||
int vertexCountInDrawCalls;
|
||||
UVScale *uvScale;
|
||||
UVScale uvScale[MAX_DEFERRED_DRAW_CALLS];
|
||||
|
||||
bool fboTexNeedBind_;
|
||||
bool fboTexBound_;
|
||||
|
|
|
@ -1148,7 +1148,7 @@ bool FramebufferManagerVulkan::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb
|
|||
}
|
||||
|
||||
void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
|
||||
_assert_msg_(G3D, nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer");
|
||||
// _assert_msg_(G3D, nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer");
|
||||
|
||||
// Discard the previous contents of this buffer where possible.
|
||||
/*
|
||||
|
|
|
@ -86,10 +86,10 @@ static const CommandTableEntry commandTable[] = {
|
|||
|
||||
// Changes that dirty texture scaling.
|
||||
{ GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexMapMode },
|
||||
{ GE_CMD_TEXSCALEU, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexScaleU },
|
||||
{ GE_CMD_TEXSCALEV, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexScaleV },
|
||||
{ GE_CMD_TEXOFFSETU, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexOffsetU },
|
||||
{ GE_CMD_TEXOFFSETV, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexOffsetV },
|
||||
{ GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexScaleU },
|
||||
{ GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexScaleV },
|
||||
{ GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexOffsetU },
|
||||
{ GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, DIRTY_UVSCALEOFFSET, &GPU_Vulkan::Execute_TexOffsetV },
|
||||
|
||||
// Changes that dirty the current texture. Really should be possible to avoid executing these if we compile
|
||||
// by adding some more flags.
|
||||
|
@ -442,9 +442,6 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
// No need to flush before the tex scale/offset commands if we are baking
|
||||
// the tex scale/offset into the vertices anyway.
|
||||
|
||||
UpdateCmdInfo();
|
||||
|
||||
BuildReportingInfo();
|
||||
|
@ -644,20 +641,14 @@ void GPU_Vulkan::UpdateVsyncInterval(bool force) {
|
|||
}
|
||||
|
||||
void GPU_Vulkan::UpdateCmdInfo() {
|
||||
if (g_Config.bPrescaleUV) {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
} else {
|
||||
cmdInfo_[GE_CMD_TEXSCALEU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXSCALEV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETU].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_TEXOFFSETV].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
}
|
||||
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPU_Vulkan::Execute_VertexType;
|
||||
/*
|
||||
if (g_Config.bSoftwareSkinning) {
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].flags &= ~FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPU_Vulkan::Execute_VertexTypeSkinning;
|
||||
} else {*/
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].flags |= FLAG_FLUSHBEFOREONCHANGE;
|
||||
cmdInfo_[GE_CMD_VERTEXTYPE].func = &GPU_Vulkan::Execute_VertexType;
|
||||
// }
|
||||
}
|
||||
|
||||
void GPU_Vulkan::ReapplyGfxStateInternal() {
|
||||
|
|
|
@ -213,18 +213,12 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
|
|||
const float heightFactor = (float)h * invH;
|
||||
|
||||
// First wrap xy, then half texel xy (for clamp.)
|
||||
const float texclamp[4] = {
|
||||
widthFactor,
|
||||
heightFactor,
|
||||
invW * 0.5f,
|
||||
invH * 0.5f,
|
||||
};
|
||||
const float texclampoff[2] = {
|
||||
gstate_c.curTextureXOffset * invW,
|
||||
gstate_c.curTextureYOffset * invH,
|
||||
};
|
||||
CopyFloat4(ub_base.texClamp, texclamp);
|
||||
CopyFloat2(ub_base.texClampOffset, texclampoff);
|
||||
ub_base.texClamp[0] = widthFactor;
|
||||
ub_base.texClamp[1] = heightFactor;
|
||||
ub_base.texClamp[2] = invW * 0.5f;
|
||||
ub_base.texClamp[3] = invH * 0.5f;
|
||||
ub_base.texClampOffset[0] = gstate_c.curTextureXOffset * invW;
|
||||
ub_base.texClampOffset[1] = gstate_c.curTextureYOffset * invH;
|
||||
}
|
||||
|
||||
if (dirtyUniforms & DIRTY_PROJMATRIX) {
|
||||
|
@ -300,56 +294,10 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
|
|||
const int h = gstate.getTextureHeight(0);
|
||||
const float widthFactor = (float)w * invW;
|
||||
const float heightFactor = (float)h * invH;
|
||||
|
||||
static const float rescale[4] = { 1.0f, 2 * 127.5f / 128.f, 2 * 32767.5f / 32768.f, 1.0f };
|
||||
const float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
|
||||
|
||||
float uvscaleoff[4];
|
||||
|
||||
switch (gstate.getUVGenMode()) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS:
|
||||
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
|
||||
case GE_TEXMAP_UNKNOWN:
|
||||
if (g_Config.bPrescaleUV) {
|
||||
// We are here but are prescaling UV in the decoder? Let's do the same as in the other case
|
||||
// except consider *Scale and *Off to be 1 and 0.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
} else {
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * factor * widthFactor;
|
||||
uvscaleoff[1] = gstate_c.uv.vScale * factor * heightFactor;
|
||||
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
|
||||
uvscaleoff[3] = gstate_c.uv.vOff * heightFactor;
|
||||
}
|
||||
break;
|
||||
|
||||
// These two work the same whether or not we prescale UV.
|
||||
|
||||
case GE_TEXMAP_TEXTURE_MATRIX:
|
||||
// We cannot bake the UV coord scale factor in here, as we apply a matrix multiplication
|
||||
// before this is applied, and the matrix multiplication may contain translation. In this case
|
||||
// the translation will be scaled which breaks faces in Hexyz Force for example.
|
||||
// So I've gone back to applying the scale factor in the shader.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
case GE_TEXMAP_ENVIRONMENT_MAP:
|
||||
// In this mode we only use uvscaleoff to scale to the texture size.
|
||||
uvscaleoff[0] = widthFactor;
|
||||
uvscaleoff[1] = heightFactor;
|
||||
uvscaleoff[2] = 0.0f;
|
||||
uvscaleoff[3] = 0.0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG_REPORT(G3D, "Unexpected UV gen mode: %d", gstate.getUVGenMode());
|
||||
}
|
||||
CopyFloat4(ub_base.uvScaleOffset, uvscaleoff);
|
||||
ub_base.uvScaleOffset[0] = widthFactor;
|
||||
ub_base.uvScaleOffset[1] = heightFactor;
|
||||
ub_base.uvScaleOffset[2] = 0.0f;
|
||||
ub_base.uvScaleOffset[3] = 0.0f;
|
||||
}
|
||||
|
||||
if (dirtyUniforms & DIRTY_DEPTHRANGE) {
|
||||
|
@ -377,8 +325,10 @@ void ShaderManagerVulkan::BaseUpdateUniforms(int dirtyUniforms) {
|
|||
viewZInvScale = 0.0;
|
||||
}
|
||||
|
||||
float data[4] = { viewZScale, viewZCenter, viewZCenter, viewZInvScale };
|
||||
CopyFloat4(ub_base.depthRange, data);
|
||||
ub_base.depthRange[0] = viewZScale;
|
||||
ub_base.depthRange[1] = viewZCenter;
|
||||
ub_base.depthRange[2] = viewZCenter;
|
||||
ub_base.depthRange[3] = viewZInvScale;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,6 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
|||
numBoneWeights = 1 + id.Bits(VS_BIT_BONES, 3);
|
||||
WRITE(p, "%s", boneWeightDecl[numBoneWeights]);
|
||||
}
|
||||
int texFmtScale = id.Bits(VS_BIT_TEXCOORD_FMTSCALE, 2);
|
||||
|
||||
if (useHWTransform)
|
||||
WRITE(p, "layout (location = %d) in vec3 position;\n", PspAttributeLocation::POSITION);
|
||||
|
@ -186,8 +185,6 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
|||
WRITE(p, "layout (location = %d) in vec3 color1;\n", PspAttributeLocation::COLOR1);
|
||||
}
|
||||
|
||||
bool prescale = g_Config.bPrescaleUV && !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
|
||||
WRITE(p, "layout (location = 1) %sout vec4 v_color0;\n", shading);
|
||||
if (lmode) {
|
||||
WRITE(p, "layout (location = 2) %sout vec3 v_color1;\n", shading);
|
||||
|
@ -431,12 +428,14 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
|||
}
|
||||
}
|
||||
|
||||
bool scaleUV = !throughmode && (uvGenMode == GE_TEXMAP_TEXTURE_COORDS || uvGenMode == GE_TEXMAP_UNKNOWN);
|
||||
|
||||
// Step 3: UV generation
|
||||
if (doTexture) {
|
||||
switch (uvGenMode) {
|
||||
case GE_TEXMAP_TEXTURE_COORDS: // Scale-offset. Easy.
|
||||
case GE_TEXMAP_UNKNOWN: // Not sure what this is, but Riviera uses it. Treating as coords works.
|
||||
if (prescale) {
|
||||
if (scaleUV) {
|
||||
if (hasTexcoord) {
|
||||
WRITE(p, " v_texcoord = texcoord;\n");
|
||||
} else {
|
||||
|
@ -460,11 +459,9 @@ bool GenerateVulkanGLSLVertexShader(const ShaderID &id, char *buffer, bool *uses
|
|||
break;
|
||||
case GE_PROJMAP_UV: // Use unscaled UV as source
|
||||
{
|
||||
// prescale is false here.
|
||||
// scaleUV is false here.
|
||||
if (hasTexcoord) {
|
||||
static const char *rescaleuv[4] = { "", " * 1.9921875", " * 1.999969482421875", "" }; // 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
|
||||
const char *factor = rescaleuv[texFmtScale];
|
||||
temp_tc = StringFromFormat("vec4(texcoord.xy %s, 0.0, 1.0)", factor);
|
||||
temp_tc = "vec4(texcoord.xy, 0.0, 1.0)";
|
||||
} else {
|
||||
temp_tc = "vec4(0.0, 0.0, 0.0, 1.0)";
|
||||
}
|
||||
|
|
|
@ -361,13 +361,6 @@ void GameSettingsScreen::CreateViews() {
|
|||
CheckBox *depthWrite = graphicsSettings->Add(new CheckBox(&g_Config.bAlwaysDepthWrite, gr->T("Always Depth Write")));
|
||||
depthWrite->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
CheckBox *textureHack = graphicsSettings->Add(new CheckBox(&g_Config.bPrescaleUV, gr->T("Texture Coord Speedhack")));
|
||||
textureHack->OnClick.Add([=](EventParams &e) {
|
||||
settingInfo_->Show(gr->T("TextureCoordSpeedhack Tip", "Faster some games that benefit from software skinning further by reducing the number of draw calls"), e.v);
|
||||
return UI::EVENT_CONTINUE;
|
||||
});
|
||||
textureHack->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
|
||||
static const char *bloomHackOptions[] = { "Off", "Safe", "Balanced", "Aggressive" };
|
||||
PopupMultiChoice *bloomHack = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iBloomHack, gr->T("Lower resolution for effects (reduces artifacts)"), bloomHackOptions, 0, ARRAY_SIZE(bloomHackOptions), gr->GetName(), screenManager()));
|
||||
bloomHackEnable_ = !g_Config.bSoftwareRendering && (g_Config.iInternalResolution != 1);
|
||||
|
|
|
@ -288,9 +288,7 @@ int CtrlVertexList::GetRowCount() {
|
|||
if (!gpuDebug->GetCurrentSimpleVertices(rowCount_, vertices, indices)) {
|
||||
rowCount_ = 0;
|
||||
}
|
||||
VertexDecoderOptions options;
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.expandAllUVtoFloat = false;
|
||||
VertexDecoderOptions options{};
|
||||
decoder->SetVertexType(state.vertType, options);
|
||||
return rowCount_;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue