More sophisticated checks, merging more draw calls

This commit is contained in:
Henrik Rydgård 2023-05-10 20:45:03 +02:00
parent 66f7a8730d
commit c36af2112d
4 changed files with 43 additions and 18 deletions

View File

@ -406,6 +406,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
Unbind();
gstate_c.SetTextureIs3D(false);
gstate_c.SetTextureIsArray(false);
gstate_c.SetTextureIsFramebuffer(false);
return nullptr;
}
@ -573,6 +574,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
gstate_c.SetTextureIs3D((entry->status & TexCacheEntry::STATUS_3D) != 0);
gstate_c.SetTextureIsArray(false);
gstate_c.SetTextureIsBGRA((entry->status & TexCacheEntry::STATUS_BGRA) != 0);
gstate_c.SetTextureIsFramebuffer(false);
if (rehash) {
// Update in case any of these changed.
@ -681,6 +683,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
gstate_c.curTextureHeight = h;
gstate_c.SetTextureIs3D((entry->status & TexCacheEntry::STATUS_3D) != 0);
gstate_c.SetTextureIsArray(false); // Ordinary 2D textures still aren't used by array view in VK. We probably might as well, though, at this point..
gstate_c.SetTextureIsFramebuffer(false);
failedTexture_ = false;
nextTexture_ = entry;
@ -1154,6 +1157,8 @@ void TextureCacheCommon::SetTextureFramebuffer(const AttachCandidate &candidate)
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
gstate_c.SetTextureIsBGRA(false);
gstate_c.SetTextureIsFramebuffer(true);
gstate_c.curTextureXOffset = fbInfo.xOffset;
gstate_c.curTextureYOffset = fbInfo.yOffset;
u32 texW = (u32)gstate.getTextureWidth(0);

View File

@ -1176,7 +1176,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
steps_[numSteps_++] = morphcount == 1 ? colstep[col] : colstep_morph[col];
// All color formats decode to DEC_U8_4 currently.
// All color formats decode to DEC_U8_4.
// They can become floats later during transform though.
decFmt.c0fmt = DEC_U8_4;
decFmt.c0off = decOff;

View File

@ -149,7 +149,7 @@ const CommonCommandTableEntry commonCommandTable[] = {
{ GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
{ GE_CMD_TEXLEVEL, FLAG_EXECUTEONCHANGE, DIRTY_TEXTURE_PARAMS, &GPUCommonHW::Execute_TexLevel },
{ GE_CMD_TEXLODSLOPE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET },
{ GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE },
{ GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
{ GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
{ GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS },
@ -822,7 +822,7 @@ void GPUCommonHW::FastRunLoop(DisplayList &list) {
void GPUCommonHW::Execute_VertexType(u32 op, u32 diff) {
if (diff)
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) {
if (diff & (GE_VTYPE_THROUGH_MASK)) {
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);
// Switching between through and non-through, we need to invalidate a bunch of stuff.
if (diff & GE_VTYPE_THROUGH_MASK)
@ -831,24 +831,36 @@ void GPUCommonHW::Execute_VertexType(u32 op, u32 diff) {
}
void GPUCommonHW::Execute_VertexTypeSkinning(u32 op, u32 diff) {
// Don't flush when weight count changes.
// Don't flush when only weight count changes.
if (diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) {
// Restore and flush
gstate.vertType ^= diff;
Flush();
gstate.vertType ^= diff;
if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK))
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);
// In this case, we may be doing weights and morphs.
// Update any bone matrix uniforms so it uses them correctly.
if ((op & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
gstate_c.Dirty(gstate_c.deferredVertTypeDirty);
gstate_c.deferredVertTypeDirty = 0;
// If the vertex format changed, but the component setup didn't (same components, different input format),
// we don't actually need to flush. Assuming the output vertex format stays the same. This is quite common in games with highly optimized mesh data.
if ((diff & ~(GE_VTYPE_TC_MASK | GE_VTYPE_COL_MASK | GE_VTYPE_POS_MASK)) == 0 &&
((gstate.vertType & GE_VTYPE_TC_MASK) != 0) == ((((gstate.vertType ^ diff) & GE_VTYPE_TC_MASK) != 0)) &&
((gstate.vertType & GE_VTYPE_COL_MASK) != 0) == ((((gstate.vertType ^ diff) & GE_VTYPE_COL_MASK) != 0))) {
// don't flush
if ((op & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
gstate_c.Dirty(gstate_c.deferredVertTypeDirty);
gstate_c.deferredVertTypeDirty = 0;
}
} else {
// Restore and flush
gstate.vertType ^= diff;
Flush();
gstate.vertType ^= diff;
// In this case, we may be doing weights and morphs.
// Update any bone matrix uniforms so it uses them correctly.
if ((op & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
gstate_c.Dirty(gstate_c.deferredVertTypeDirty);
gstate_c.deferredVertTypeDirty = 0;
}
// NOTE: Vertex shader only cares about presence of components.
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
}
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
}
if (diff & GE_VTYPE_THROUGH_MASK)
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_CULLRANGE);
gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_GEOMETRYSHADER_STATE | DIRTY_CULLRANGE | DIRTY_UVSCALEOFFSET);
}
void GPUCommonHW::Execute_Prim(u32 op, u32 diff) {
@ -1282,7 +1294,8 @@ void GPUCommonHW::Execute_TexSize0(u32 op, u32 diff) {
if (diff || gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS)) {
gstate_c.curTextureWidth = gstate.getTextureWidth(0);
gstate_c.curTextureHeight = gstate.getTextureHeight(0);
gstate_c.Dirty(DIRTY_UVSCALEOFFSET);
// NOTE: We used to reset DIRTY_UVSCALEOFFSET here BUT it's only necessary when
// switching to/from render textures.
// We will need to reset the texture now.
gstate_c.Dirty(DIRTY_TEXTURE_PARAMS);
}

View File

@ -574,6 +574,12 @@ struct GPUStateCache {
Dirty(DIRTY_FRAGMENTSHADER_STATE);
}
}
void SetTextureIsFramebuffer(bool framebuf) {
if (framebufTexture != framebuf) {
framebufTexture = framebuf;
Dirty(DIRTY_UVSCALEOFFSET);
}
}
void SetTextureIsBGRA(bool isBGRA) {
if (bgraTexture != isBGRA) {
bgraTexture = isBGRA;
@ -616,6 +622,7 @@ public:
bool needShaderTexClamp;
bool arrayTexture;
bool useFlagsChanged;
bool framebufTexture;
float morphWeights[8];
u32 deferredVertTypeDirty;