diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 34592a01ff9aac77bd170b75e39458e2dc04c528..0031fa5fbef3d8679f938373a578d8e0c851b75c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -407,7 +407,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct } 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); } if (info.stores[IR::Attribute::ViewportMask] && profile.support_viewport_mask) { diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 1d77426e010a0d2ad65d26aa7d1c910570aad360..e5a78a9140fb24f8559eab10373a588ab001bb81 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -84,6 +84,10 @@ std::optional<OutAttr> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { } return std::nullopt; 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 || ctx.stage == Shader::Stage::Geometry) { return OutAttr{ctx.viewport_index, ctx.U32[1]}; diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 38d820db2025e69754e61f8fceb0f0a76b8d7266..a9de9f4a958b0ed9574a99987f4c5c99e69d836f 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -43,6 +43,7 @@ struct Profile { bool support_gl_sparse_textures{}; bool support_gl_derivative_control{}; bool support_scaled_attributes{}; + bool support_multi_viewport{}; bool warp_size_potentially_larger_than_guest{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 16ad8d62526c4f23c5abdc68a62943d0823929d7..89b455bff8444613bc0787ec315751d4d7707aa0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -351,6 +351,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), .support_native_ndc = device.IsExtDepthClipControlSupported(), .support_scaled_attributes = !device.MustEmulateScaledFormats(), + .support_multi_viewport = device.SupportsMultiViewport(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 355de06169cadaec647b07ac9a5305a8ba3da4cd..4f3846345c919dbfd8ef94a964dae5b0d563e2d1 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -669,6 +669,10 @@ public: return supports_conditional_barriers; } + bool SupportsMultiViewport() const { + return features2.features.multiViewport; + } + [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, u32 driver_version) { if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {