forked from suyu/suyu
texture_cache: loose TryReconstructSurface when accurate GPU is not on.
Also corrects some asserts.
This commit is contained in:
parent
6162cb922e
commit
d267948a73
3 changed files with 20 additions and 4 deletions
|
@ -111,7 +111,7 @@ void MaxwellDMA::HandleCopy() {
|
||||||
|
|
||||||
memory_manager.WriteBlock(dest, write_buffer.data(), dst_size);
|
memory_manager.WriteBlock(dest, write_buffer.data(), dst_size);
|
||||||
} else {
|
} else {
|
||||||
ASSERT(regs.dst_params.BlockDepth() == 1);
|
ASSERT(regs.dst_params.BlockDepth() == 0);
|
||||||
|
|
||||||
const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count;
|
const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count;
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (params.is_tiled) {
|
if (params.is_tiled) {
|
||||||
ASSERT_MSG(params.block_width == 1, "Block width is defined as {}", params.block_width);
|
ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width);
|
||||||
for (u32 level = 0; level < params.num_levels; ++level) {
|
for (u32 level = 0; level < params.num_levels; ++level) {
|
||||||
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
|
const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)};
|
||||||
SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
|
SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
|
||||||
|
|
|
@ -425,6 +425,7 @@ private:
|
||||||
}
|
}
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
TSurface new_surface = GetUncachedSurface(gpu_addr, params);
|
TSurface new_surface = GetUncachedSurface(gpu_addr, params);
|
||||||
|
u32 passed_tests = 0;
|
||||||
for (auto surface : overlaps) {
|
for (auto surface : overlaps) {
|
||||||
const SurfaceParams& src_params = surface->GetSurfaceParams();
|
const SurfaceParams& src_params = surface->GetSurfaceParams();
|
||||||
if (src_params.is_layered || src_params.num_levels > 1) {
|
if (src_params.is_layered || src_params.num_levels > 1) {
|
||||||
|
@ -434,12 +435,12 @@ private:
|
||||||
const std::size_t candidate_size = surface->GetSizeInBytes();
|
const std::size_t candidate_size = surface->GetSizeInBytes();
|
||||||
auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())};
|
auto mipmap_layer{new_surface->GetLayerMipmap(surface->GetGpuAddr())};
|
||||||
if (!mipmap_layer) {
|
if (!mipmap_layer) {
|
||||||
return {};
|
continue;
|
||||||
}
|
}
|
||||||
const u32 layer{mipmap_layer->first};
|
const u32 layer{mipmap_layer->first};
|
||||||
const u32 mipmap{mipmap_layer->second};
|
const u32 mipmap{mipmap_layer->second};
|
||||||
if (new_surface->GetMipmapSize(mipmap) != candidate_size) {
|
if (new_surface->GetMipmapSize(mipmap) != candidate_size) {
|
||||||
return {};
|
continue;
|
||||||
}
|
}
|
||||||
modified |= surface->IsModified();
|
modified |= surface->IsModified();
|
||||||
// Now we got all the data set up
|
// Now we got all the data set up
|
||||||
|
@ -448,8 +449,15 @@ private:
|
||||||
const CopyParams copy_params(0, 0, 0, 0, 0, layer, 0, mipmap,
|
const CopyParams copy_params(0, 0, 0, 0, 0, layer, 0, mipmap,
|
||||||
std::min(src_params.width, dst_width),
|
std::min(src_params.width, dst_width),
|
||||||
std::min(src_params.height, dst_height), 1);
|
std::min(src_params.height, dst_height), 1);
|
||||||
|
passed_tests++;
|
||||||
ImageCopy(surface, new_surface, copy_params);
|
ImageCopy(surface, new_surface, copy_params);
|
||||||
}
|
}
|
||||||
|
if (passed_tests == 0) {
|
||||||
|
return {};
|
||||||
|
// In Accurate GPU all test should pass, else we recycle
|
||||||
|
} else if (Settings::values.use_accurate_gpu_emulation && passed_tests != overlaps.size()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
for (auto surface : overlaps) {
|
for (auto surface : overlaps) {
|
||||||
Unregister(surface);
|
Unregister(surface);
|
||||||
}
|
}
|
||||||
|
@ -548,6 +556,14 @@ private:
|
||||||
}
|
}
|
||||||
return {current_surface, *view};
|
return {current_surface, *view};
|
||||||
}
|
}
|
||||||
|
// The next case is unsafe, so if we r in accurate GPU, just skip it
|
||||||
|
if (Settings::values.use_accurate_gpu_emulation) {
|
||||||
|
return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, false);
|
||||||
|
}
|
||||||
|
// This is the case the texture is a part of the parent.
|
||||||
|
if (current_surface->MatchesSubTexture(params, gpu_addr)) {
|
||||||
|
return RebuildSurface(current_surface, params);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If there are many overlaps, odds are they are subtextures of the candidate
|
// If there are many overlaps, odds are they are subtextures of the candidate
|
||||||
// surface. We try to construct a new surface based on the candidate parameters,
|
// surface. We try to construct a new surface based on the candidate parameters,
|
||||||
|
|
Loading…
Reference in a new issue