glasm: Add passthrough geometry shader support
This commit is contained in:
		| @@ -83,13 +83,14 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; |     const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"}; | ||||||
|  |     const VaryingState loads{info.loads.mask | info.passthrough.mask}; | ||||||
|     for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { |     for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||||||
|         if (info.loads.Generic(index)) { |         if (loads.Generic(index)) { | ||||||
|             Add("{}ATTRIB in_attr{}[]={{{}.attrib[{}..{}]}};", |             Add("{}ATTRIB in_attr{}[]={{{}.attrib[{}..{}]}};", | ||||||
|                 InterpDecorator(info.interpolation[index]), index, attr_stage, index, index); |                 InterpDecorator(info.interpolation[index]), index, attr_stage, index, index); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (IsInputArray(stage) && info.loads.AnyComponent(IR::Attribute::PositionX)) { |     if (IsInputArray(stage) && loads.AnyComponent(IR::Attribute::PositionX)) { | ||||||
|         Add("ATTRIB vertex_position=vertex.position;"); |         Add("ATTRIB vertex_position=vertex.position;"); | ||||||
|     } |     } | ||||||
|     if (info.uses_invocation_id) { |     if (info.uses_invocation_id) { | ||||||
|   | |||||||
| @@ -304,6 +304,9 @@ void SetupOptions(const IR::Program& program, const Profile& profile, | |||||||
|             header += "OPTION NV_viewport_array2;"; |             header += "OPTION NV_viewport_array2;"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     if (program.is_geometry_passthrough && profile.support_geometry_shader_passthrough) { | ||||||
|  |         header += "OPTION NV_geometry_shader_passthrough;"; | ||||||
|  |     } | ||||||
|     if (info.uses_typeless_image_reads && profile.support_typeless_image_loads) { |     if (info.uses_typeless_image_reads && profile.support_typeless_image_loads) { | ||||||
|         header += "OPTION EXT_shader_image_load_formatted;"; |         header += "OPTION EXT_shader_image_load_formatted;"; | ||||||
|     } |     } | ||||||
| @@ -410,11 +413,26 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I | |||||||
|                               runtime_info.tess_clockwise ? "CW" : "CCW"); |                               runtime_info.tess_clockwise ? "CW" : "CCW"); | ||||||
|         break; |         break; | ||||||
|     case Stage::Geometry: |     case Stage::Geometry: | ||||||
|         header += fmt::format("PRIMITIVE_IN {};" |         header += fmt::format("PRIMITIVE_IN {};", InputPrimitive(runtime_info.input_topology)); | ||||||
|                               "PRIMITIVE_OUT {};" |         if (program.is_geometry_passthrough) { | ||||||
|                               "VERTICES_OUT {};", |             if (profile.support_geometry_shader_passthrough) { | ||||||
|                               InputPrimitive(runtime_info.input_topology), |                 for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { | ||||||
|                               OutputPrimitive(program.output_topology), program.output_vertices); |                     if (program.info.passthrough.Generic(index)) { | ||||||
|  |                         header += fmt::format("PASSTHROUGH result.attrib[{}];", index); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 if (program.info.passthrough.AnyComponent(IR::Attribute::PositionX)) { | ||||||
|  |                     header += "PASSTHROUGH result.position;"; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 LOG_WARNING(Shader_GLASM, "Passthrough geometry program used but not supported"); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             header += | ||||||
|  |                 fmt::format("VERTICES_OUT {};" | ||||||
|  |                             "PRIMITIVE_OUT {};", | ||||||
|  |                             program.output_vertices, OutputPrimitive(program.output_topology)); | ||||||
|  |         } | ||||||
|         break; |         break; | ||||||
|     case Stage::Compute: |     case Stage::Compute: | ||||||
|         header += fmt::format("GROUP_SIZE {} {} {};", program.workgroup_size[0], |         header += fmt::format("GROUP_SIZE {} {} {};", program.workgroup_size[0], | ||||||
|   | |||||||
| @@ -160,6 +160,7 @@ Device::Device() { | |||||||
|     has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory; |     has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory; | ||||||
|     has_debugging_tool_attached = IsDebugToolAttached(extensions); |     has_debugging_tool_attached = IsDebugToolAttached(extensions); | ||||||
|     has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float"); |     has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float"); | ||||||
|  |     has_geometry_shader_passthrough = GLAD_GL_NV_geometry_shader_passthrough; | ||||||
|     has_nv_gpu_shader_5 = GLAD_GL_NV_gpu_shader5; |     has_nv_gpu_shader_5 = GLAD_GL_NV_gpu_shader5; | ||||||
|     has_shader_int64 = HasExtension(extensions, "GL_ARB_gpu_shader_int64"); |     has_shader_int64 = HasExtension(extensions, "GL_ARB_gpu_shader_int64"); | ||||||
|     has_amd_shader_half_float = GLAD_GL_AMD_gpu_shader_half_float; |     has_amd_shader_half_float = GLAD_GL_AMD_gpu_shader_half_float; | ||||||
|   | |||||||
| @@ -120,6 +120,10 @@ public: | |||||||
|         return has_depth_buffer_float; |         return has_depth_buffer_float; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     bool HasGeometryShaderPassthrough() const { | ||||||
|  |         return has_geometry_shader_passthrough; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     bool HasNvGpuShader5() const { |     bool HasNvGpuShader5() const { | ||||||
|         return has_nv_gpu_shader_5; |         return has_nv_gpu_shader_5; | ||||||
|     } |     } | ||||||
| @@ -174,6 +178,7 @@ private: | |||||||
|     bool use_asynchronous_shaders{}; |     bool use_asynchronous_shaders{}; | ||||||
|     bool use_driver_cache{}; |     bool use_driver_cache{}; | ||||||
|     bool has_depth_buffer_float{}; |     bool has_depth_buffer_float{}; | ||||||
|  |     bool has_geometry_shader_passthrough{}; | ||||||
|     bool has_nv_gpu_shader_5{}; |     bool has_nv_gpu_shader_5{}; | ||||||
|     bool has_shader_int64{}; |     bool has_shader_int64{}; | ||||||
|     bool has_amd_shader_half_float{}; |     bool has_amd_shader_half_float{}; | ||||||
|   | |||||||
| @@ -187,7 +187,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | |||||||
|           .support_demote_to_helper_invocation = false, |           .support_demote_to_helper_invocation = false, | ||||||
|           .support_int64_atomics = false, |           .support_int64_atomics = false, | ||||||
|           .support_derivative_control = device.HasDerivativeControl(), |           .support_derivative_control = device.HasDerivativeControl(), | ||||||
|           .support_geometry_shader_passthrough = false, // TODO |           .support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(), | ||||||
|           .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), |           .support_gl_nv_gpu_shader_5 = device.HasNvGpuShader5(), | ||||||
|           .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), |           .support_gl_amd_gpu_shader_half_float = device.HasAmdShaderHalfFloat(), | ||||||
|           .support_gl_texture_shadow_lod = device.HasTextureShadowLod(), |           .support_gl_texture_shadow_lod = device.HasTextureShadowLod(), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user