summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexLoaderManager.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2015-05-29 18:25:19 +1200
committerScott Mansell <phiren@gmail.com>2015-05-29 18:51:17 +1200
commit6d916762fb52a85aa086ef0cb6516cc63fbe775b (patch)
tree468488194c2fd28c59b7188c982cec87e5a1d3da /Source/Core/VideoCommon/VertexLoaderManager.cpp
parent68d6f07b5c7251dce346f3eaf15eb637b869ab4b (diff)
Fix invalid pointer errors in Burnout 2.
Yet another story of games loading weird shit into registers. For some reason, Burnout 2 would (in rare situations) load invalid addresses into cp_state.array_bases. What would the real hardware do in this situation? Who knows, Burnout 2 doesn't actually enable the vertex array with the invalid address so nothing kinky happens. But dolphin tries to optimise things and starts using the address as soon as it is loaded into memory. This causes GetPointer (which is now much more vocal) to throw an error. The Fix: We don't call GetPointer until we are sure the vertex array has been enabled.
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderManager.cpp')
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index 4168f7c777..8d2acecc66 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -42,7 +42,6 @@ void Init()
map_entry = nullptr;
for (auto& map_entry : g_preprocess_cp_state.vertex_loaders)
map_entry = nullptr;
- RecomputeCachedArraybases();
SETSTAT(stats.numVertexLoaders, 0);
}
@@ -136,6 +135,11 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal
} else {
loader = state->vertex_loaders[vtx_attr_group];
}
+
+ // Lookup pointers for any vertex arrays.
+ if (!preprocess)
+ ComputeCachedArrayBases();
+
return loader;
}
@@ -232,8 +236,6 @@ void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess)
// Pointers to vertex arrays in GC RAM
case 0xA0:
state->array_bases[sub_cmd & 0xF] = value;
- if (update_global_state)
- cached_arraybases[sub_cmd & 0xF] = Memory::GetPointer(value);
break;
case 0xB0:
@@ -263,10 +265,15 @@ void FillCPMemoryArray(u32 *memory)
}
}
-void RecomputeCachedArraybases()
+void ComputeCachedArrayBases()
{
- for (int i = 0; i < 16; i++)
+ // Some games such as Burnout 2 can put invalid addresses into
+ // the array base registers. (see issue 8591)
+ // But the vertex arrays with invalid addresses aren't actually enabled.
+ for (int i = 0; i < 12; i++)
{
- cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
+ // Only update the array base if the vertex description states we are going to use it.
+ if (g_main_cp_state.vtx_desc.GetVertexArrayStatus(i) >= 0x2)
+ cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
}
}