Compare commits

..

1 Commits

Author SHA1 Message Date
Andrea Pappacoda
02ca46d394 build: use system SoundTouch when available
Checking for both a CMake config file and a pkg-config file is needed
because some distros only ship the latter.

Related to #6833 and #7044
2022-03-27 13:17:37 +02:00
9 changed files with 135 additions and 6 deletions

View File

@@ -69,7 +69,12 @@ if (YUZU_USE_EXTERNAL_SDL2)
endif()
# SoundTouch
add_subdirectory(soundtouch)
find_package(SoundTouch MODULE)
if (NOT SoundTouch_FOUND)
message(STATUS "SoundTouch not found, falling back to externals")
add_subdirectory(soundtouch)
add_library(SoundTouch::SoundTouch ALIAS SoundTouch)
endif()
# Cubeb
if(ENABLE_CUBEB)

View File

@@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: 2022 Andrea Pappacoda <andrea@pappacoda.it>
#
# SPDX-License-Identifier: GPL-2.0-or-later
# This find module looks for SoundTouch with both a CMake Config file and a
# pkg-config. If the library is found, it checks if it enforces 32 bit
# floating point samples, and if not it defines SOUNDTOUCH_INTEGER_SAMPLES,
# just like in the bundled library.
find_package(SoundTouch CONFIG)
if (SoundTouch_FOUND)
set(_st_real_name "SoundTouch::SoundTouch")
else()
find_package(PkgConfig QUIET)
if (PKG_CONFIG_FOUND)
pkg_search_module(SoundTouch IMPORTED_TARGET soundtouch)
if (SoundTouch_FOUND)
set_target_properties(PkgConfig::SoundTouch PROPERTIES IMPORTED_GLOBAL True)
add_library(SoundTouch::SoundTouch ALIAS PkgConfig::SoundTouch)
# Need to set this variable because CMake doesn't allow to add
# compile definitions to ALIAS targets
set(_st_real_name "PkgConfig::SoundTouch")
endif()
endif()
endif()
if (SoundTouch_FOUND)
find_path(_st_include_dir "soundtouch/soundtouch_config.h")
file(READ "${_st_include_dir}/soundtouch/soundtouch_config.h" _st_config_file)
# Check if the config file defines SOUNDTOUCH_FLOAT_SAMPLES
string(REGEX MATCH "#define[ ]+SOUNDTOUCH_FLOAT_SAMPLES[ ]+1" SoundTouch_FLOAT_SAMPLES ${_st_config_file})
if (NOT SoundTouch_FLOAT_SAMPLES)
target_compile_definitions(${_st_real_name} INTERFACE "SOUNDTOUCH_INTEGER_SAMPLES=1")
set(SoundTouch_INTEGER_SAMPLES True)
else()
# Check if SoundTouch supports SOUNDTOUCH_NO_CONFIG
file(READ "${_st_include_dir}/soundtouch/STTypes.h" _st_types_file)
string(FIND "${_st_types_file}" "SOUNDTOUCH_NO_CONFIG" SoundTouch_NO_CONFIG)
# if found
if (NOT SoundTouch_NO_CONFIG EQUAL "-1")
target_compile_definitions(${_st_real_name} INTERFACE "SOUNDTOUCH_NO_CONFIG" "SOUNDTOUCH_INTEGER_SAMPLES=1")
set(SoundTouch_INTEGER_SAMPLES True)
endif()
unset(_st_types_file)
endif()
unset(_st_real_name)
unset(_st_include_dir)
unset(_st_config_file)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SoundTouch
REQUIRED_VARS
SoundTouch_FOUND
SoundTouch_INTEGER_SAMPLES
VERSION_VAR SoundTouch_VERSION
)

View File

@@ -63,7 +63,7 @@ if (NOT MSVC)
endif()
target_link_libraries(audio_core PUBLIC common core)
target_link_libraries(audio_core PRIVATE SoundTouch)
target_link_libraries(audio_core PRIVATE SoundTouch::SoundTouch)
if(ENABLE_CUBEB)
target_link_libraries(audio_core PRIVATE cubeb)

View File

@@ -322,7 +322,7 @@ struct Memory::Impl {
}
if (Settings::IsFastmemEnabled()) {
const bool is_read_enable = Settings::IsGPULevelHigh() || !cached;
const bool is_read_enable = !Settings::IsGPULevelExtreme() || !cached;
system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
}

View File

@@ -352,7 +352,7 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
shader_cache.OnCPUWrite(addr, size);
{
std::scoped_lock lock{texture_cache.mutex};
texture_cache.WriteMemory(addr, size);
texture_cache.CachedWriteMemory(addr, size);
}
{
std::scoped_lock lock{buffer_cache.mutex};
@@ -363,6 +363,10 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
void RasterizerOpenGL::SyncGuestHost() {
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
shader_cache.SyncGuestHost();
{
std::scoped_lock lock{texture_cache.mutex};
texture_cache.FlushCachedWrites();
}
{
std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.FlushCachedWrites();

View File

@@ -408,7 +408,7 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
pipeline_cache.OnCPUWrite(addr, size);
{
std::scoped_lock lock{texture_cache.mutex};
texture_cache.WriteMemory(addr, size);
texture_cache.CachedWriteMemory(addr, size);
}
{
std::scoped_lock lock{buffer_cache.mutex};
@@ -418,6 +418,10 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
void RasterizerVulkan::SyncGuestHost() {
pipeline_cache.SyncGuestHost();
{
std::scoped_lock lock{texture_cache.mutex};
texture_cache.FlushCachedWrites();
}
{
std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.FlushCachedWrites();

View File

@@ -39,6 +39,9 @@ enum class ImageFlagBits : u32 {
Rescaled = 1 << 13,
CheckingRescalable = 1 << 14,
IsRescalable = 1 << 15,
// Cached CPU
CachedCpuModified = 1 << 16, ///< Contents have been modified from the CPU
};
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)

View File

@@ -437,6 +437,23 @@ void TextureCache<P>::WriteMemory(VAddr cpu_addr, size_t size) {
});
}
template <class P>
void TextureCache<P>::CachedWriteMemory(VAddr cpu_addr, size_t size) {
const VAddr new_cpu_addr = Common::AlignDown(cpu_addr, CPU_PAGE_SIZE);
const size_t new_size = Common::AlignUp(size + cpu_addr - new_cpu_addr, CPU_PAGE_SIZE);
ForEachImageInRegion(new_cpu_addr, new_size, [this](ImageId image_id, Image& image) {
if (True(image.flags & ImageFlagBits::CachedCpuModified)) {
return;
}
image.flags |= ImageFlagBits::CachedCpuModified;
cached_cpu_invalidate.insert(image_id);
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, image_id);
}
});
}
template <class P>
void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {
std::vector<ImageId> images;
@@ -494,6 +511,18 @@ void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) {
}
}
template <class P>
void TextureCache<P>::FlushCachedWrites() {
for (ImageId image_id : cached_cpu_invalidate) {
Image& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::CachedCpuModified)) {
image.flags &= ~ImageFlagBits::CachedCpuModified;
image.flags |= ImageFlagBits::CpuModified;
}
}
cached_cpu_invalidate.clear();
}
template <class P>
void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Surface& src,
@@ -1560,6 +1589,9 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
template <class P>
void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
ASSERT(False(image.flags & ImageFlagBits::Tracked));
if (True(image.flags & ImageFlagBits::CachedCpuModified)) {
return;
}
image.flags |= ImageFlagBits::Tracked;
if (False(image.flags & ImageFlagBits::Sparse)) {
rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
@@ -1616,6 +1648,9 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
}
total_used_memory -= Common::AlignUp(tentative_size, 1024);
if (True(image.flags & ImageFlagBits::CachedCpuModified)) {
cached_cpu_invalidate.erase(image_id);
}
const GPUVAddr gpu_addr = image.gpu_addr;
const auto alloc_it = image_allocs_table.find(gpu_addr);
if (alloc_it == image_allocs_table.end()) {
@@ -1782,7 +1817,11 @@ template <class P>
void TextureCache<P>::PrepareImage(ImageId image_id, bool is_modification, bool invalidate) {
Image& image = slot_images[image_id];
if (invalidate) {
image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified);
if (True(image.flags & ImageFlagBits::CachedCpuModified)) {
cached_cpu_invalidate.erase(image_id);
}
image.flags &= ~(ImageFlagBits::CpuModified | ImageFlagBits::GpuModified |
ImageFlagBits::CachedCpuModified);
if (False(image.flags & ImageFlagBits::Tracked)) {
TrackImage(image, image_id);
}

View File

@@ -8,6 +8,7 @@
#include <span>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <queue>
@@ -50,6 +51,9 @@ class TextureCache {
/// Address shift for caching images into a hash table
static constexpr u64 PAGE_BITS = 20;
static constexpr u64 CPU_PAGE_BITS = 12;
static constexpr u64 CPU_PAGE_SIZE = 1ULL << CPU_PAGE_BITS;
/// Enables debugging features to the texture cache
static constexpr bool ENABLE_VALIDATION = P::ENABLE_VALIDATION;
/// Implement blits as copies between framebuffers
@@ -136,6 +140,9 @@ public:
/// Mark images in a range as modified from the CPU
void WriteMemory(VAddr cpu_addr, size_t size);
/// Mark images in a range as modified from the CPU
void CachedWriteMemory(VAddr cpu_addr, size_t size);
/// Download contents of host images to guest memory in a region
void DownloadMemory(VAddr cpu_addr, size_t size);
@@ -145,6 +152,8 @@ public:
/// Remove images in a region
void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size);
void FlushCachedWrites();
/// Blit an image with the given parameters
void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Surface& src,
@@ -366,6 +375,8 @@ private:
std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views;
std::unordered_set<ImageId> cached_cpu_invalidate;
VAddr virtual_invalid_space{};
bool has_deleted_images = false;