Просмотр исходного кода

shader_recompiler: throw on missing geometry streams in geometry shaders

Liam 2 лет назад
Родитель
Сommit
f46dc31683

+ 3 - 1
src/shader_recompiler/backend/spirv/emit_spirv.cpp

@@ -261,7 +261,9 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
     case Stage::Geometry:
         execution_model = spv::ExecutionModel::Geometry;
         ctx.AddCapability(spv::Capability::Geometry);
-        ctx.AddCapability(spv::Capability::GeometryStreams);
+        if (ctx.profile.support_geometry_streams) {
+            ctx.AddCapability(spv::Capability::GeometryStreams);
+        }
         switch (ctx.runtime_info.input_topology) {
         case InputTopology::Points:
             ctx.AddExecutionMode(main, spv::ExecutionMode::InputPoints);

+ 6 - 2
src/shader_recompiler/backend/spirv/emit_spirv_special.cpp

@@ -129,7 +129,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
     if (ctx.runtime_info.convert_depth_mode && !ctx.profile.support_native_ndc) {
         ConvertDepthMode(ctx);
     }
-    if (stream.IsImmediate()) {
+    if (!ctx.profile.support_geometry_streams) {
+        throw NotImplementedException("Geometry streams");
+    } else if (stream.IsImmediate()) {
         ctx.OpEmitStreamVertex(ctx.Def(stream));
     } else {
         LOG_WARNING(Shader_SPIRV, "Stream is not immediate");
@@ -140,7 +142,9 @@ void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
 }
 
 void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
-    if (stream.IsImmediate()) {
+    if (!ctx.profile.support_geometry_streams) {
+        throw NotImplementedException("Geometry streams");
+    } else if (stream.IsImmediate()) {
         ctx.OpEndStreamPrimitive(ctx.Def(stream));
     } else {
         LOG_WARNING(Shader_SPIRV, "Stream is not immediate");

+ 1 - 0
src/shader_recompiler/profile.h

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

+ 1 - 0
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@@ -352,6 +352,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
         .support_native_ndc = device.IsExtDepthClipControlSupported(),
         .support_scaled_attributes = !device.MustEmulateScaledFormats(),
         .support_multi_viewport = device.SupportsMultiViewport(),
+        .support_geometry_streams = device.AreTransformFeedbackGeometryStreamsSupported(),
 
         .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
 

+ 5 - 0
src/video_core/vulkan_common/vulkan_device.h

@@ -499,6 +499,11 @@ public:
         return extensions.transform_feedback;
     }
 
+    /// Returns true if the device supports VK_EXT_transform_feedback properly.
+    bool AreTransformFeedbackGeometryStreamsSupported() const {
+        return features.transform_feedback.geometryStreams;
+    }
+
     /// Returns true if the device supports VK_EXT_custom_border_color.
     bool IsExtCustomBorderColorSupported() const {
         return extensions.custom_border_color;