early-access version 3982

This commit is contained in:
pineappleEA 2023-11-19 22:02:37 +01:00
parent e9dc1e4faf
commit e21a6bb3bc
14 changed files with 75 additions and 15 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3981. This is the source code for early-access 3982.
## Legal Notice ## Legal Notice

View file

@ -856,7 +856,15 @@ std::string Config::AdjustKey(const std::string& key) {
std::string Config::AdjustOutputString(const std::string& string) { std::string Config::AdjustOutputString(const std::string& string) {
std::string adjusted_string(string); std::string adjusted_string(string);
boost::replace_all(adjusted_string, "\\", "/"); boost::replace_all(adjusted_string, "\\", "/");
boost::replace_all(adjusted_string, "//", "/");
// Windows requires that two forward slashes are used at the start of a path for unmapped
// network drives so we have to watch for that here
if (string.substr(0, 2) == "//") {
boost::replace_all(adjusted_string, "//", "/");
adjusted_string.insert(0, "/");
} else {
boost::replace_all(adjusted_string, "//", "/");
}
// Needed for backwards compatibility with QSettings deserialization // Needed for backwards compatibility with QSettings deserialization
for (const auto& special_character : special_characters) { for (const auto& special_character : special_characters) {

View file

@ -407,7 +407,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
} }
ctx.AddCapability(spv::Capability::DemoteToHelperInvocation); ctx.AddCapability(spv::Capability::DemoteToHelperInvocation);
} }
if (info.stores[IR::Attribute::ViewportIndex]) { if (info.stores[IR::Attribute::ViewportIndex] && profile.support_multi_viewport) {
ctx.AddCapability(spv::Capability::MultiViewport); ctx.AddCapability(spv::Capability::MultiViewport);
} }
if (info.stores[IR::Attribute::ViewportMask] && profile.support_viewport_mask) { if (info.stores[IR::Attribute::ViewportMask] && profile.support_viewport_mask) {

View file

@ -84,6 +84,10 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
} }
return std::nullopt; return std::nullopt;
case IR::Attribute::ViewportIndex: case IR::Attribute::ViewportIndex:
if (!ctx.profile.support_multi_viewport) {
LOG_WARNING(Shader, "Ignoring viewport index store on non-supporting driver");
return std::nullopt;
}
if (ctx.profile.support_viewport_index_layer_non_geometry || if (ctx.profile.support_viewport_index_layer_non_geometry ||
ctx.stage == Shader::Stage::Geometry) { ctx.stage == Shader::Stage::Geometry) {
return OutAttr{ctx.viewport_index, ctx.U32[1]}; return OutAttr{ctx.viewport_index, ctx.U32[1]};

View file

@ -43,6 +43,7 @@ struct Profile {
bool support_gl_sparse_textures{}; bool support_gl_sparse_textures{};
bool support_gl_derivative_control{}; bool support_gl_derivative_control{};
bool support_scaled_attributes{}; bool support_scaled_attributes{};
bool support_multi_viewport{};
bool warp_size_potentially_larger_than_guest{}; bool warp_size_potentially_larger_than_guest{};

View file

@ -1209,11 +1209,6 @@ void BufferCache<P>::UpdateDrawIndirect() {
.size = static_cast<u32>(size), .size = static_cast<u32>(size),
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)), .buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
}; };
VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
IntervalType interval{cpu_addr_start, cpu_addr_end};
ClearDownload(interval);
common_ranges.subtract(interval);
}; };
if (current_draw_indirect->include_count) { if (current_draw_indirect->include_count) {
update(current_draw_indirect->count_start_address, sizeof(u32), update(current_draw_indirect->count_start_address, sizeof(u32),

View file

@ -268,7 +268,7 @@ size_t Maxwell3D::EstimateIndexBufferSize() {
std::numeric_limits<u32>::max()}; std::numeric_limits<u32>::max()};
const size_t byte_size = regs.index_buffer.FormatSizeInBytes(); const size_t byte_size = regs.index_buffer.FormatSizeInBytes();
const size_t log2_byte_size = Common::Log2Ceil64(byte_size); const size_t log2_byte_size = Common::Log2Ceil64(byte_size);
const size_t cap{GetMaxCurrentVertices() * 3 * byte_size}; const size_t cap{GetMaxCurrentVertices() * 4 * byte_size};
const size_t lower_cap = const size_t lower_cap =
std::min<size_t>(static_cast<size_t>(end_address - start_address), cap); std::min<size_t>(static_cast<size_t>(end_address - start_address), cap);
return std::min<size_t>( return std::min<size_t>(

View file

@ -559,7 +559,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
} }
void GraphicsPipeline::ConfigureTransformFeedbackImpl() const { void GraphicsPipeline::ConfigureTransformFeedbackImpl() const {
glTransformFeedbackAttribsNV(num_xfb_attribs, xfb_attribs.data(), GL_SEPARATE_ATTRIBS); const GLenum buffer_mode =
num_xfb_buffers_active == 1 ? GL_INTERLEAVED_ATTRIBS : GL_SEPARATE_ATTRIBS;
glTransformFeedbackAttribsNV(num_xfb_attribs, xfb_attribs.data(), buffer_mode);
} }
void GraphicsPipeline::GenerateTransformFeedbackState() { void GraphicsPipeline::GenerateTransformFeedbackState() {
@ -567,12 +569,14 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
// when this is required. // when this is required.
GLint* cursor{xfb_attribs.data()}; GLint* cursor{xfb_attribs.data()};
num_xfb_buffers_active = 0;
for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) { for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) {
const auto& layout = key.xfb_state.layouts[feedback]; const auto& layout = key.xfb_state.layouts[feedback];
UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding"); UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding");
if (layout.varying_count == 0) { if (layout.varying_count == 0) {
continue; continue;
} }
num_xfb_buffers_active++;
const auto& locations = key.xfb_state.varyings[feedback]; const auto& locations = key.xfb_state.varyings[feedback];
std::optional<u32> current_index; std::optional<u32> current_index;

View file

@ -154,6 +154,7 @@ private:
static constexpr std::size_t XFB_ENTRY_STRIDE = 3; static constexpr std::size_t XFB_ENTRY_STRIDE = 3;
GLsizei num_xfb_attribs{}; GLsizei num_xfb_attribs{};
u32 num_xfb_buffers_active{};
std::array<GLint, 128 * XFB_ENTRY_STRIDE * Maxwell::NumTransformFeedbackBuffers> xfb_attribs{}; std::array<GLint, 128 * XFB_ENTRY_STRIDE * Maxwell::NumTransformFeedbackBuffers> xfb_attribs{};
std::mutex built_mutex; std::mutex built_mutex;

View file

@ -263,6 +263,22 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
info.y_negate = key.state.y_negate != 0; info.y_negate = key.state.y_negate != 0;
return info; return info;
} }
size_t GetTotalPipelineWorkers() {
const size_t max_core_threads =
std::max<size_t>(static_cast<size_t>(std::thread::hardware_concurrency()), 2ULL) - 1ULL;
#ifdef ANDROID
// Leave at least a few cores free in android
constexpr size_t free_cores = 3ULL;
if (max_core_threads <= free_cores) {
return 1ULL;
}
return max_core_threads - free_cores;
#else
return max_core_threads;
#endif
}
} // Anonymous namespace } // Anonymous namespace
size_t ComputePipelineCacheKey::Hash() const noexcept { size_t ComputePipelineCacheKey::Hash() const noexcept {
@ -294,11 +310,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
texture_cache{texture_cache_}, shader_notify{shader_notify_}, texture_cache{texture_cache_}, shader_notify{shader_notify_},
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()}, use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()},
#ifdef ANDROID workers(device.HasBrokenParallelShaderCompiling() ? 1ULL : GetTotalPipelineWorkers(),
workers(1, "VkPipelineBuilder"), "VkPipelineBuilder"),
#else
workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"),
#endif
serialization_thread(1, "VkPipelineSerialization") { serialization_thread(1, "VkPipelineSerialization") {
const auto& float_control{device.FloatControlProperties()}; const auto& float_control{device.FloatControlProperties()};
const VkDriverId driver_id{device.GetDriverID()}; const VkDriverId driver_id{device.GetDriverID()};
@ -338,6 +351,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(),
.support_native_ndc = device.IsExtDepthClipControlSupported(), .support_native_ndc = device.IsExtDepthClipControlSupported(),
.support_scaled_attributes = !device.MustEmulateScaledFormats(), .support_scaled_attributes = !device.MustEmulateScaledFormats(),
.support_multi_viewport = device.SupportsMultiViewport(),
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),

View file

@ -211,6 +211,13 @@ public:
return; return;
} }
PauseCounter(); PauseCounter();
const auto driver_id = device.GetDriverID();
if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
pending_sync.clear();
sync_values_stash.clear();
return;
}
sync_values_stash.clear(); sync_values_stash.clear();
sync_values_stash.emplace_back(); sync_values_stash.emplace_back();
std::vector<HostSyncValues>* sync_values = &sync_values_stash.back(); std::vector<HostSyncValues>* sync_values = &sync_values_stash.back();
@ -1378,6 +1385,12 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku
return true; return true;
} }
auto driver_id = impl->device.GetDriverID();
if (driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP) {
return true;
}
for (size_t i = 0; i < 2; i++) { for (size_t i = 0; i < 2; i++) {
is_null[i] = !is_in_ac[i] && check_value(objects[i]->address); is_null[i] = !is_in_ac[i] && check_value(objects[i]->address);
} }

View file

@ -635,6 +635,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
has_broken_cube_compatibility = true; has_broken_cube_compatibility = true;
} }
} }
if (is_qualcomm) {
const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(0, 255, 615, 512)) {
has_broken_parallel_compiling = true;
}
}
if (extensions.sampler_filter_minmax && is_amd) { if (extensions.sampler_filter_minmax && is_amd) {
// Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken. // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken.
if (!features.shader_float16_int8.shaderFloat16) { if (!features.shader_float16_int8.shaderFloat16) {

View file

@ -102,6 +102,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
@ -599,6 +600,11 @@ public:
return has_broken_cube_compatibility; return has_broken_cube_compatibility;
} }
/// Returns true if parallel shader compiling has issues with the current driver.
bool HasBrokenParallelShaderCompiling() const {
return has_broken_parallel_compiling;
}
/// Returns the vendor name reported from Vulkan. /// Returns the vendor name reported from Vulkan.
std::string_view GetVendorName() const { std::string_view GetVendorName() const {
return properties.driver.driverName; return properties.driver.driverName;
@ -663,6 +669,10 @@ public:
return supports_conditional_barriers; return supports_conditional_barriers;
} }
bool SupportsMultiViewport() const {
return features2.features.multiViewport;
}
[[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id,
u32 driver_version) { u32 driver_version) {
if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
@ -794,6 +804,7 @@ private:
bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device.
bool has_broken_compute{}; ///< Compute shaders can cause crashes bool has_broken_compute{}; ///< Compute shaders can cause crashes
bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit bool has_broken_cube_compatibility{}; ///< Has broken cube compatibility bit
bool has_broken_parallel_compiling{}; ///< Has broken parallel shader compiling.
bool has_renderdoc{}; ///< Has RenderDoc attached bool has_renderdoc{}; ///< Has RenderDoc attached
bool has_nsight_graphics{}; ///< Has Nsight Graphics attached bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
bool supports_d24_depth{}; ///< Supports D24 depth buffers. bool supports_d24_depth{}; ///< Supports D24 depth buffers.

View file

@ -4,7 +4,10 @@
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <QPainter> #include <QPainter>
#include "common/logging/log.h"
#include "yuzu/util/util.h" #include "yuzu/util/util.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include "common/fs/file.h" #include "common/fs/file.h"