aboutsummaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/fence_manager.h5
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp35
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h18
7 files changed, 61 insertions, 31 deletions
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 805a89900..c0e6471fe 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -86,7 +86,10 @@ public:
uncommitted_operations.emplace_back(std::move(func));
}
pending_operations.emplace_back(std::move(uncommitted_operations));
- QueueFence(new_fence);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ QueueFence(new_fence);
+ }
if (!delay_fence) {
func();
}
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index c4c30d807..7e7a80740 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -132,12 +132,16 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
const bool use_accelerated =
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
const bool is_srgb = use_accelerated && screen_info.is_srgb;
- RenderScreenshot(*framebuffer, use_accelerated);
- Frame* frame = present_manager.GetRenderFrame();
- blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
- scheduler.Flush(*frame->render_ready);
- present_manager.Present(frame);
+ {
+ std::scoped_lock lock{rasterizer.LockCaches()};
+ RenderScreenshot(*framebuffer, use_accelerated);
+
+ Frame* frame = present_manager.GetRenderFrame();
+ blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
+ scheduler.Flush(*frame->render_ready);
+ present_manager.Present(frame);
+ }
gpu.RendererFrameEndNotify();
rasterizer.TickFrame();
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index a1ec1a100..804b95989 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -356,7 +356,11 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
.has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY,
.ignore_nan_fp_comparisons = false,
.has_broken_spirv_subgroup_mask_vector_extract_dynamic =
- driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY};
+ driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+ .has_broken_robust =
+ device.IsNvidia() && device.GetNvidiaArch() <= NvidiaArchitecture::Arch_Maxwell,
+ };
+
host_info = Shader::HostTranslateInfo{
.support_float64 = device.IsFloat64Supported(),
.support_float16 = device.IsFloat16Supported(),
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 61d03daae..465eac37e 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -198,7 +198,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
if (!pipeline) {
return;
}
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ std::scoped_lock lock{LockCaches()};
// update engine as channel may be different.
pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
@@ -708,6 +708,7 @@ void RasterizerVulkan::TiledCacheBarrier() {
}
void RasterizerVulkan::FlushCommands() {
+ std::scoped_lock lock{LockCaches()};
if (draw_counter == 0) {
return;
}
@@ -805,6 +806,7 @@ void RasterizerVulkan::FlushWork() {
if ((++draw_counter & 7) != 7) {
return;
}
+ std::scoped_lock lock{LockCaches()};
if (draw_counter < DRAWS_TO_DISPATCH) {
// Send recorded tasks to the worker thread
scheduler.DispatchWork();
@@ -1499,7 +1501,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
CreateChannel(channel);
{
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ std::scoped_lock lock{LockCaches()};
texture_cache.CreateChannel(channel);
buffer_cache.CreateChannel(channel);
}
@@ -1512,7 +1514,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
const s32 channel_id = channel.bind_id;
BindToChannel(channel_id);
{
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ std::scoped_lock lock{LockCaches()};
texture_cache.BindToChannel(channel_id);
buffer_cache.BindToChannel(channel_id);
}
@@ -1525,7 +1527,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
EraseChannel(channel_id);
{
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ std::scoped_lock lock{LockCaches()};
texture_cache.EraseChannel(channel_id);
buffer_cache.EraseChannel(channel_id);
}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index ad069556c..ce3dfbaab 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -133,6 +133,10 @@ public:
void ReleaseChannel(s32 channel_id) override;
+ std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
+ return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
+ }
+
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 876cec2e8..e518756d2 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -83,15 +83,6 @@ constexpr std::array VK_FORMAT_A4B4G4R4_UNORM_PACK16{
} // namespace Alternatives
-enum class NvidiaArchitecture {
- KeplerOrOlder,
- Maxwell,
- Pascal,
- Volta,
- Turing,
- AmpereOrNewer,
-};
-
template <typename T>
void SetNext(void**& next, T& data) {
*next = &data;
@@ -326,9 +317,9 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) {
// Only Ampere and newer support this feature
// TODO: Find a way to differentiate Ampere and Ada
- return NvidiaArchitecture::AmpereOrNewer;
+ return NvidiaArchitecture::Arch_AmpereOrNewer;
}
- return NvidiaArchitecture::Turing;
+ return NvidiaArchitecture::Arch_Turing;
}
if (exts.contains(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) {
@@ -340,7 +331,7 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical_properties.pNext = &advanced_blending_props;
physical.GetProperties2(physical_properties);
if (advanced_blending_props.advancedBlendMaxColorAttachments == 1) {
- return NvidiaArchitecture::Maxwell;
+ return NvidiaArchitecture::Arch_Maxwell;
}
if (exts.contains(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) {
@@ -350,13 +341,13 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical_properties.pNext = &conservative_raster_props;
physical.GetProperties2(physical_properties);
if (conservative_raster_props.degenerateLinesRasterized) {
- return NvidiaArchitecture::Volta;
+ return NvidiaArchitecture::Arch_Volta;
}
- return NvidiaArchitecture::Pascal;
+ return NvidiaArchitecture::Arch_Pascal;
}
}
- return NvidiaArchitecture::KeplerOrOlder;
+ return NvidiaArchitecture::Arch_KeplerOrOlder;
}
std::vector<const char*> ExtensionListForVulkan(
@@ -436,6 +427,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
}
+ if (is_nvidia) {
+ nvidia_arch = GetNvidiaArchitecture(physical, supported_extensions);
+ }
+
SetupFamilies(surface);
const auto queue_cis = GetDeviceQueueCreateInfos();
@@ -532,11 +527,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_nvidia) {
const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff;
- const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
- if (arch >= NvidiaArchitecture::AmpereOrNewer) {
+ const auto arch = GetNvidiaArch();
+ if (arch >= NvidiaArchitecture::Arch_AmpereOrNewer) {
LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math");
features.shader_float16_int8.shaderFloat16 = false;
- } else if (arch <= NvidiaArchitecture::Volta) {
+ } else if (arch <= NvidiaArchitecture::Arch_Volta) {
if (nv_major_version < 527) {
LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
@@ -686,8 +681,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
}
} else if (extensions.push_descriptor && is_nvidia) {
- const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
- if (arch <= NvidiaArchitecture::Pascal) {
+ const auto arch = GetNvidiaArch();
+ if (arch <= NvidiaArchitecture::Arch_Pascal) {
LOG_WARNING(Render_Vulkan,
"Pascal and older architectures have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 282a2925d..b213ed7dd 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -177,6 +177,15 @@ enum class FormatType { Linear, Optimal, Buffer };
/// Subgroup size of the guest emulated hardware (Nvidia has 32 threads per subgroup).
const u32 GuestWarpSize = 32;
+enum class NvidiaArchitecture {
+ Arch_KeplerOrOlder,
+ Arch_Maxwell,
+ Arch_Pascal,
+ Arch_Volta,
+ Arch_Turing,
+ Arch_AmpereOrNewer,
+};
+
/// Handles data specific to a physical device.
class Device {
public:
@@ -670,6 +679,14 @@ public:
return false;
}
+ bool IsNvidia() const noexcept {
+ return properties.driver.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
+ }
+
+ NvidiaArchitecture GetNvidiaArch() const noexcept {
+ return nvidia_arch;
+ }
+
private:
/// Checks if the physical device is suitable and configures the object state
/// with all necessary info about its properties.
@@ -788,6 +805,7 @@ private:
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
u64 device_access_memory{}; ///< Total size of device local memory in bytes.
u32 sets_per_pool{}; ///< Sets per Description Pool
+ NvidiaArchitecture nvidia_arch{NvidiaArchitecture::Arch_AmpereOrNewer};
// Telemetry parameters
std::set<std::string, std::less<>> supported_extensions; ///< Reported Vulkan extensions.