Compare commits

..

11 Commits

Author SHA1 Message Date
Charles Lombardo 0f31039831 android: Clean up file extension checks 2023-06-26 13:25:56 -04:00
bunnei a67bdeb2c2 Merge pull request #10853 from lat9nq/update_tzdb_to_nx
externals: Update tzdb_to_nx
2023-06-20 10:42:54 -07:00
liamwhite f1e12e3b08 Merge pull request #10818 from vonchenplus/render_target_samples
video_core: add samples check when find render target
2023-06-20 09:55:23 -04:00
liamwhite 93061d1ea1 Merge pull request #10835 from lat9nq/intel-restrict-compute-disable
vulkan_device: Restrict compute disable only to affected Intel drivers
2023-06-20 09:55:14 -04:00
liamwhite 6d12e7320b Merge pull request #10840 from Kelebek1/unbug_blinks_brain
Use current GPU address when unmapping GPU pages, not the base
2023-06-20 09:55:01 -04:00
toast2903 78ff2862f6 vulkan_device: Remove brace initializer
Co-authored-by: Tobias <thm.frey@gmail.com>
2023-06-19 17:35:12 -04:00
lat9nq 197e13d93d video_core: Check broken compute earlier
Checks it as the system is determining what settings to enable. Reduces
the need to check settings while the system is running.
2023-06-19 17:33:30 -04:00
Kelebek1 711190bb67 Use current GPU address when unmapping GPU pages, not the base 2023-06-19 00:19:50 +01:00
lat9nq b9a86b040b vk_device_info: Check only affected Intel drivers
Renames is_intel_proprietary to has_broken_compute for accuracy.

vk_device_info: Use vulkan::device to check compute
2023-06-18 16:15:51 -04:00
lat9nq 346c253cd2 video_core: Formalize HasBrokenCompute
Also limits it to only affected Intel proprietrary driver versions.

vulkan_device: Move broken compute determination

vk_device: Remove errant back quote
2023-06-18 16:15:47 -04:00
FengChen 76a676883a video_core: add samples check when find render target 2023-06-17 23:48:51 +08:00
14 changed files with 73 additions and 82 deletions
@@ -29,7 +29,6 @@ import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.FileUtil
class SearchFragment : Fragment() {
private var _binding: FragmentSearchBinding? = null
@@ -128,10 +127,7 @@ class SearchFragment : Fragment() {
R.id.chip_homebrew -> baseList.filter { it.isHomebrew }
R.id.chip_retail -> baseList.filter {
FileUtil.hasExtension(it.path, "xci") ||
FileUtil.hasExtension(it.path, "nsp")
}
R.id.chip_retail -> baseList.filter { !it.isHomebrew }
else -> baseList
}
@@ -43,7 +43,7 @@ class Game(
companion object {
val extensions: Set<String> = HashSet(
listOf(".xci", ".nsp", ".nca", ".nro")
listOf("xci", "nsp", "nca", "nro")
)
}
}
@@ -294,7 +294,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
return@registerForActivityResult
}
if (!FileUtil.hasExtension(result, "keys")) {
if (FileUtil.getExtension(result) != "keys") {
MessageDialogFragment.newInstance(
R.string.reading_keys_failure,
R.string.install_prod_keys_failure_extension_description
@@ -391,7 +391,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
return@registerForActivityResult
}
if (!FileUtil.hasExtension(result, "bin")) {
if (FileUtil.getExtension(result) != "bin") {
MessageDialogFragment.newInstance(
R.string.reading_keys_failure,
R.string.install_amiibo_keys_failure_extension_description
@@ -7,7 +7,6 @@ import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.DocumentsContract
import android.provider.OpenableColumns
import androidx.documentfile.provider.DocumentFile
import java.io.BufferedInputStream
import java.io.File
@@ -185,19 +184,18 @@ object FileUtil {
/**
* Get file display name from given path
* @param path content uri path
* @param uri content uri
* @return String display name
*/
fun getFilename(context: Context, path: String): String {
val resolver = context.contentResolver
fun getFilename(uri: Uri): String {
val resolver = YuzuApplication.appContext.contentResolver
val columns = arrayOf(
DocumentsContract.Document.COLUMN_DISPLAY_NAME
)
var filename = ""
var c: Cursor? = null
try {
val mUri = Uri.parse(path)
c = resolver.query(mUri, columns, null, null, null)
c = resolver.query(uri, columns, null, null, null)
c!!.moveToNext()
filename = c.getString(0)
} catch (e: Exception) {
@@ -326,25 +324,9 @@ object FileUtil {
}
}
fun hasExtension(path: String, extension: String): Boolean =
path.substring(path.lastIndexOf(".") + 1).contains(extension)
fun hasExtension(uri: Uri, extension: String): Boolean {
val fileName: String?
val cursor = YuzuApplication.appContext.contentResolver.query(uri, null, null, null, null)
val nameIndex = cursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME)
cursor?.moveToFirst()
if (nameIndex == null) {
return false
}
fileName = cursor.getString(nameIndex)
cursor.close()
if (fileName == null) {
return false
}
return fileName.substring(fileName.lastIndexOf(".") + 1).contains(extension)
fun getExtension(uri: Uri): String {
val fileName = getFilename(uri)
return fileName.substring(fileName.lastIndexOf(".") + 1)
.lowercase()
}
}
@@ -6,7 +6,6 @@ package org.yuzu.yuzu_emu.utils
import android.content.SharedPreferences
import android.net.Uri
import androidx.preference.PreferenceManager
import java.util.*
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.yuzu.yuzu_emu.NativeLibrary
@@ -33,15 +32,9 @@ object GameHelper {
val children = FileUtil.listFiles(context, gamesUri)
for (file in children) {
if (!file.isDirectory) {
val filename = file.uri.toString()
val extensionStart = filename.lastIndexOf('.')
if (extensionStart > 0) {
val fileExtension = filename.substring(extensionStart)
// Check that the file has an extension we care about before trying to read out of it.
if (Game.extensions.contains(fileExtension.lowercase(Locale.getDefault()))) {
games.add(getGame(filename))
}
// Check that the file has an extension we care about before trying to read out of it.
if (Game.extensions.contains(FileUtil.getExtension(file.uri))) {
games.add(getGame(file.uri))
}
}
}
@@ -59,21 +52,19 @@ object GameHelper {
return games.toList()
}
private fun getGame(filePath: String): Game {
private fun getGame(uri: Uri): Game {
val filePath = uri.toString()
var name = NativeLibrary.getTitle(filePath)
// If the game's title field is empty, use the filename.
if (name.isEmpty()) {
name = filePath.substring(filePath.lastIndexOf("/") + 1)
name = FileUtil.getFilename(uri)
}
var gameId = NativeLibrary.getGameId(filePath)
// If the game's ID field is empty, use the filename without extension.
if (gameId.isEmpty()) {
gameId = filePath.substring(
filePath.lastIndexOf("/") + 1,
filePath.lastIndexOf(".")
)
gameId = name.substring(0, name.lastIndexOf("."))
}
val newGame = Game(
+2 -2
View File
@@ -111,7 +111,7 @@ GPUVAddr MemoryManager::PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cp
[[maybe_unused]] const auto current_entry_type = GetEntry<false>(current_gpu_addr);
SetEntry<false>(current_gpu_addr, entry_type);
if (current_entry_type != entry_type) {
rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, page_size);
rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, page_size);
}
if constexpr (entry_type == EntryType::Mapped) {
const VAddr current_cpu_addr = cpu_addr + offset;
@@ -134,7 +134,7 @@ GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr
[[maybe_unused]] const auto current_entry_type = GetEntry<true>(current_gpu_addr);
SetEntry<true>(current_gpu_addr, entry_type);
if (current_entry_type != entry_type) {
rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, big_page_size);
rasterizer->ModifyGPUMemory(unique_identifier, current_gpu_addr, big_page_size);
}
if constexpr (entry_type == EntryType::Mapped) {
const VAddr current_cpu_addr = cpu_addr + offset;
@@ -705,10 +705,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
ShaderPools& pools, const ComputePipelineCacheKey& key, Shader::Environment& env,
PipelineStatistics* statistics, bool build_in_parallel) try {
// TODO: Remove this when Intel fixes their shader compiler.
// https://github.com/IGCIT/Intel-GPU-Community-Issue-Tracker-IGCIT/issues/159
if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS &&
!Settings::values.enable_compute_pipelines.GetValue()) {
if (device.HasBrokenCompute()) {
LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash());
return nullptr;
}
+10 -12
View File
@@ -300,7 +300,7 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
}
template <class P>
bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
bool TextureCache<P>::RescaleRenderTargets() {
auto& flags = maxwell3d->dirty.flags;
u32 scale_rating = 0;
bool rescaled = false;
@@ -338,13 +338,13 @@ bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
if (flags[Dirty::ColorBuffer0 + index] || force) {
flags[Dirty::ColorBuffer0 + index] = false;
BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
BindRenderTarget(&color_buffer_id, FindColorBuffer(index));
}
check_rescale(color_buffer_id, tmp_color_images[index]);
}
if (flags[Dirty::ZetaBuffer] || force) {
flags[Dirty::ZetaBuffer] = false;
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer());
}
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
@@ -409,7 +409,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
return;
}
const bool rescaled = RescaleRenderTargets(is_clear);
const bool rescaled = RescaleRenderTargets();
if (is_rescaling != rescaled) {
flags[Dirty::RescaleViewports] = true;
flags[Dirty::RescaleScissors] = true;
@@ -1678,7 +1678,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
}
template <class P>
ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
ImageViewId TextureCache<P>::FindColorBuffer(size_t index) {
const auto& regs = maxwell3d->regs;
if (index >= regs.rt_control.count) {
return ImageViewId{};
@@ -1692,11 +1692,11 @@ ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
return ImageViewId{};
}
const ImageInfo info(regs.rt[index], regs.anti_alias_samples_mode);
return FindRenderTargetView(info, gpu_addr, is_clear);
return FindRenderTargetView(info, gpu_addr);
}
template <class P>
ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) {
ImageViewId TextureCache<P>::FindDepthBuffer() {
const auto& regs = maxwell3d->regs;
if (!regs.zeta_enable) {
return ImageViewId{};
@@ -1706,18 +1706,16 @@ ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) {
return ImageViewId{};
}
const ImageInfo info(regs.zeta, regs.zeta_size, regs.anti_alias_samples_mode);
return FindRenderTargetView(info, gpu_addr, is_clear);
return FindRenderTargetView(info, gpu_addr);
}
template <class P>
ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
bool is_clear) {
const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{};
ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr) {
ImageId image_id{};
bool delete_state = has_deleted_images;
do {
has_deleted_images = false;
image_id = FindOrInsertImage(info, gpu_addr, options);
image_id = FindOrInsertImage(info, gpu_addr);
delete_state |= has_deleted_images;
} while (has_deleted_images);
has_deleted_images = delete_state;
@@ -178,9 +178,8 @@ public:
void SynchronizeComputeDescriptors();
/// Updates the Render Targets if they can be rescaled
/// @param is_clear True when the render targets are being used for clears
/// @retval True if the Render Targets have been rescaled.
bool RescaleRenderTargets(bool is_clear);
bool RescaleRenderTargets();
/// Update bound render targets and upload memory if necessary
/// @param is_clear True when the render targets are being used for clears
@@ -336,14 +335,13 @@ private:
[[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
/// Find or create an image view for the given color buffer index
[[nodiscard]] ImageViewId FindColorBuffer(size_t index, bool is_clear);
[[nodiscard]] ImageViewId FindColorBuffer(size_t index);
/// Find or create an image view for the depth buffer
[[nodiscard]] ImageViewId FindDepthBuffer(bool is_clear);
[[nodiscard]] ImageViewId FindDepthBuffer();
/// Find or create a view for a render target with the given image parameters
[[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
bool is_clear);
[[nodiscard]] ImageViewId FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr);
/// Iterates over all the images in a region calling func
template <typename Func>
@@ -562,6 +562,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits");
cant_blit_msaa = true;
}
has_broken_compute =
CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) &&
!Settings::values.enable_compute_pipelines.GetValue();
if (is_intel_anv || (is_qualcomm && !is_s8gen2)) {
LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format");
must_emulate_bgr565 = true;
@@ -10,6 +10,7 @@
#include <vector>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -518,6 +519,11 @@ public:
return has_renderdoc || has_nsight_graphics || Settings::values.renderer_debug.GetValue();
}
/// @returns True if compute pipelines can cause crashing.
bool HasBrokenCompute() const {
return has_broken_compute;
}
/// Returns true when the device does not properly support cube compatibility.
bool HasBrokenCubeImageCompability() const {
return has_broken_cube_compatibility;
@@ -579,6 +585,22 @@ public:
return supports_conditional_barriers;
}
[[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id,
u32 driver_version) {
if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
const u32 major = VK_API_VERSION_MAJOR(driver_version);
const u32 minor = VK_API_VERSION_MINOR(driver_version);
const u32 patch = VK_API_VERSION_PATCH(driver_version);
if (major == 0 && minor == 405 && patch < 286) {
LOG_WARNING(
Render_Vulkan,
"Intel proprietary drivers 0.405.0 until 0.405.286 have broken compute");
return true;
}
}
return false;
}
private:
/// Checks if the physical device is suitable and configures the object state
/// with all necessary info about its properties.
@@ -672,6 +694,7 @@ private:
bool is_integrated{}; ///< Is GPU an iGPU.
bool is_virtual{}; ///< Is GPU a virtual GPU.
bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device.
bool has_broken_compute{}; ///< Compute shaders can cause crashes
bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit
bool has_renderdoc{}; ///< Has RenderDoc attached
bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
@@ -508,7 +508,7 @@ void ConfigureGraphics::RetrieveVulkanDevices() {
vulkan_devices.push_back(QString::fromStdString(record.name));
device_present_modes.push_back(record.vsync_support);
if (record.is_intel_proprietary) {
if (record.has_broken_compute) {
expose_compute_option();
}
}
+8 -5
View File
@@ -5,10 +5,12 @@
#include <vector>
#include "common/dynamic_library.h"
#include "common/logging/log.h"
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_instance.h"
#include "video_core/vulkan_common/vulkan_library.h"
#include "video_core/vulkan_common/vulkan_surface.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
#include "vulkan/vulkan_core.h"
#include "yuzu/qt_common.h"
#include "yuzu/vk_device_info.h"
@@ -16,8 +18,8 @@ class QWindow;
namespace VkDeviceInfo {
Record::Record(std::string_view name_, const std::vector<VkPresentModeKHR>& vsync_modes_,
bool is_intel_proprietary_)
: name{name_}, vsync_support{vsync_modes_}, is_intel_proprietary{is_intel_proprietary_} {}
bool has_broken_compute_)
: name{name_}, vsync_support{vsync_modes_}, has_broken_compute{has_broken_compute_} {}
Record::~Record() = default;
@@ -48,9 +50,10 @@ void PopulateRecords(std::vector<Record>& records, QWindow* window) try {
properties.pNext = &driver_properties;
dld.vkGetPhysicalDeviceProperties2(physical_device, &properties);
records.push_back(VkDeviceInfo::Record(name, present_modes,
driver_properties.driverID ==
VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS));
bool has_broken_compute{Vulkan::Device::CheckBrokenCompute(
driver_properties.driverID, properties.properties.driverVersion)};
records.push_back(VkDeviceInfo::Record(name, present_modes, has_broken_compute));
}
} catch (const Vulkan::vk::Exception& exception) {
LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what());
+2 -2
View File
@@ -24,12 +24,12 @@ namespace VkDeviceInfo {
class Record {
public:
explicit Record(std::string_view name, const std::vector<VkPresentModeKHR>& vsync_modes,
bool is_intel_proprietary);
bool has_broken_compute);
~Record();
const std::string name;
const std::vector<VkPresentModeKHR> vsync_support;
const bool is_intel_proprietary;
const bool has_broken_compute;
};
void PopulateRecords(std::vector<Record>& records, QWindow* window);