diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index bcd40354d..18b93d602 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp @@ -244,6 +244,11 @@ void RasterizerAccelerated::NotifyPicaRegisterChanged(u32 id) { } break; + // Fragment operation mode + case PICA_REG_INDEX(framebuffer.output_merger.fragment_operation_mode): + shader_dirty = true; + break; + // Alpha test case PICA_REG_INDEX(framebuffer.output_merger.alpha_test): SyncAlphaTest(); @@ -617,11 +622,10 @@ void RasterizerAccelerated::NotifyPicaRegisterChanged(u32 id) { case PICA_REG_INDEX(rasterizer.clip_coef[3]): SyncClipCoef(); break; - - default: - // Forward registers that map to fixed function API features to the video backend - NotifyFixedFunctionPicaRegisterChanged(id); } + + // Forward registers that map to fixed function API features to the video backend + NotifyFixedFunctionPicaRegisterChanged(id); } void RasterizerAccelerated::SyncDepthScale() { diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index caee255d4..3891393fb 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -632,9 +632,16 @@ bool Instance::SetMoltenVkConfig() { return false; } + // Use synchronous queue submits if async presentation is enabled, to avoid threading + // indirection. mvk_config.synchronousQueueSubmits = Settings::values.async_presentation.GetValue(); + // If the device is lost, make an attempt to resume if possible to avoid crashes. mvk_config.resumeLostDevice = true; + // Maximize concurrency to improve shader compilation performance. mvk_config.shouldMaximizeConcurrentCompilation = true; + // Use Metal argument buffers as otherwise we run into issues with shadow rendering + // image atomics. + mvk_config.useMetalArgumentBuffers = MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS_ALWAYS; if (_vkSetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &mvk_config, &mvk_config_size) != VK_SUCCESS) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 62ce0de09..5511f4335 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -471,6 +471,9 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { if (shadow_rendering) { pipeline_cache.BindStorageImage(6, framebuffer->ImageView(SurfaceType::Color)); + } else { + Surface& null_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_ID); + pipeline_cache.BindStorageImage(6, null_surface.StorageView()); } // Update scissor uniforms @@ -660,7 +663,7 @@ void RasterizerVulkan::UnbindSpecial() { const Surface& null_cube_surface = res_cache.GetSurface(VideoCore::NULL_SURFACE_CUBE_ID); const Sampler& null_sampler = res_cache.GetSampler(VideoCore::NULL_SAMPLER_ID); pipeline_cache.BindTexture(3, null_cube_surface.ImageView(), null_sampler.Handle()); - for (u32 i = 0; i < 7; i++) { + for (u32 i = 0; i < 6; i++) { pipeline_cache.BindStorageImage(i, null_surface.StorageView()); } }