early-access version 3982
This commit is contained in:
parent
e9dc1e4faf
commit
e21a6bb3bc
14 changed files with 75 additions and 15 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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, "\\", "/");
|
||||||
|
|
||||||
|
// 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, "//", "/");
|
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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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]};
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue