diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_context.cpp | 90 |
1 files changed, 78 insertions, 12 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 923060386..01403ca17 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -21,10 +21,21 @@ std::string_view InterpDecorator(Interpolation interp) { | |||
| 21 | throw InvalidArgument("Invalid interpolation {}", interp); | 21 | throw InvalidArgument("Invalid interpolation {}", interp); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | std::string_view ArrayDecorator(Stage stage) { | 24 | std::string_view InputArrayDecorator(Stage stage) { |
| 25 | switch (stage) { | 25 | switch (stage) { |
| 26 | case Stage::Geometry: | 26 | case Stage::Geometry: |
| 27 | return "[1]"; | 27 | case Stage::TessellationControl: |
| 28 | case Stage::TessellationEval: | ||
| 29 | return "[]"; | ||
| 30 | default: | ||
| 31 | return ""; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | std::string OutputDecorator(Stage stage, u32 size) { | ||
| 36 | switch (stage) { | ||
| 37 | case Stage::TessellationControl: | ||
| 38 | return fmt::format("[{}]", size); | ||
| 28 | default: | 39 | default: |
| 29 | return ""; | 40 | return ""; |
| 30 | } | 41 | } |
| @@ -73,6 +84,30 @@ std::string_view SamplerType(TextureType type, bool is_depth) { | |||
| 73 | } | 84 | } |
| 74 | } | 85 | } |
| 75 | 86 | ||
| 87 | std::string_view GetTessMode(TessPrimitive primitive) { | ||
| 88 | switch (primitive) { | ||
| 89 | case TessPrimitive::Triangles: | ||
| 90 | return "triangles"; | ||
| 91 | case TessPrimitive::Quads: | ||
| 92 | return "quads"; | ||
| 93 | case TessPrimitive::Isolines: | ||
| 94 | return "isolines"; | ||
| 95 | } | ||
| 96 | throw InvalidArgument("Invalid tessellation primitive {}", primitive); | ||
| 97 | } | ||
| 98 | |||
| 99 | std::string_view GetTessSpacing(TessSpacing spacing) { | ||
| 100 | switch (spacing) { | ||
| 101 | case TessSpacing::Equal: | ||
| 102 | return "equal_spacing"; | ||
| 103 | case TessSpacing::FractionalOdd: | ||
| 104 | return "fractional_odd_spacing"; | ||
| 105 | case TessSpacing::FractionalEven: | ||
| 106 | return "fractional_even_spacing"; | ||
| 107 | } | ||
| 108 | throw InvalidArgument("Invalid tessellation spacing {}", spacing); | ||
| 109 | } | ||
| 110 | |||
| 76 | std::string_view InputPrimitive(InputTopology topology) { | 111 | std::string_view InputPrimitive(InputTopology topology) { |
| 77 | switch (topology) { | 112 | switch (topology) { |
| 78 | case InputTopology::Points: | 113 | case InputTopology::Points: |
| @@ -100,6 +135,23 @@ std::string_view OutputPrimitive(OutputTopology topology) { | |||
| 100 | } | 135 | } |
| 101 | throw InvalidArgument("Invalid output topology {}", topology); | 136 | throw InvalidArgument("Invalid output topology {}", topology); |
| 102 | } | 137 | } |
| 138 | |||
| 139 | void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) { | ||
| 140 | if (stage != Stage::VertexA && stage != Stage::VertexB && stage != Stage::Geometry) { | ||
| 141 | return; | ||
| 142 | } | ||
| 143 | header += "out gl_PerVertex{"; | ||
| 144 | if (info.stores_position) { | ||
| 145 | header += "vec4 gl_Position;"; | ||
| 146 | } | ||
| 147 | if (info.stores_point_size) { | ||
| 148 | header += "float gl_PointSize;"; | ||
| 149 | } | ||
| 150 | if (info.stores_clip_distance) { | ||
| 151 | header += "float gl_ClipDistance[];"; | ||
| 152 | } | ||
| 153 | header += "};"; | ||
| 154 | } | ||
| 103 | } // namespace | 155 | } // namespace |
| 104 | 156 | ||
| 105 | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, | 157 | EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, |
| @@ -111,17 +163,20 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 111 | case Stage::VertexA: | 163 | case Stage::VertexA: |
| 112 | case Stage::VertexB: | 164 | case Stage::VertexB: |
| 113 | stage_name = "vs"; | 165 | stage_name = "vs"; |
| 114 | // TODO: add only what's used by the shader | ||
| 115 | header += | ||
| 116 | "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; | ||
| 117 | break; | 166 | break; |
| 118 | case Stage::TessellationControl: | 167 | case Stage::TessellationControl: |
| 168 | stage_name = "tsc"; | ||
| 169 | header += fmt::format("layout(vertices={})out;\n", program.invocations); | ||
| 170 | break; | ||
| 119 | case Stage::TessellationEval: | 171 | case Stage::TessellationEval: |
| 120 | stage_name = "ts"; | 172 | stage_name = "tse"; |
| 173 | header += fmt::format("layout({},{},{})in;\n", GetTessMode(runtime_info.tess_primitive), | ||
| 174 | GetTessSpacing(runtime_info.tess_spacing), | ||
| 175 | runtime_info.tess_clockwise ? "cw" : "ccw"); | ||
| 121 | break; | 176 | break; |
| 122 | case Stage::Geometry: | 177 | case Stage::Geometry: |
| 123 | stage_name = "gs"; | 178 | stage_name = "gs"; |
| 124 | header += fmt::format("layout({})in;layout({}, max_vertices={})out;\n", | 179 | header += fmt::format("layout({})in;layout({},max_vertices={})out;\n", |
| 125 | InputPrimitive(runtime_info.input_topology), | 180 | InputPrimitive(runtime_info.input_topology), |
| 126 | OutputPrimitive(program.output_topology), program.output_vertices); | 181 | OutputPrimitive(program.output_topology), program.output_vertices); |
| 127 | break; | 182 | break; |
| @@ -135,12 +190,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 135 | program.workgroup_size[2]); | 190 | program.workgroup_size[2]); |
| 136 | break; | 191 | break; |
| 137 | } | 192 | } |
| 193 | SetupOutPerVertex(stage, info, header); | ||
| 138 | for (size_t index = 0; index < info.input_generics.size(); ++index) { | 194 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 139 | const auto& generic{info.input_generics[index]}; | 195 | const auto& generic{info.input_generics[index]}; |
| 140 | if (generic.used) { | 196 | if (generic.used) { |
| 141 | header += | 197 | header += fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, |
| 142 | fmt::format("layout(location={}){} in vec4 in_attr{}{};", index, | 198 | InterpDecorator(generic.interpolation), index, |
| 143 | InterpDecorator(generic.interpolation), index, ArrayDecorator(stage)); | 199 | InputArrayDecorator(stage)); |
| 200 | } | ||
| 201 | } | ||
| 202 | for (size_t index = 0; index < info.uses_patches.size(); ++index) { | ||
| 203 | if (!info.uses_patches[index]) { | ||
| 204 | continue; | ||
| 205 | } | ||
| 206 | if (stage == Stage::TessellationControl) { | ||
| 207 | header += fmt::format("layout(location={})patch out vec4 patch{};", index, index); | ||
| 208 | } else { | ||
| 209 | header += fmt::format("layout(location={})patch in vec4 patch{};", index, index); | ||
| 144 | } | 210 | } |
| 145 | } | 211 | } |
| 146 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { | 212 | for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { |
| @@ -151,8 +217,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 151 | } | 217 | } |
| 152 | for (size_t index = 0; index < info.stores_generics.size(); ++index) { | 218 | for (size_t index = 0; index < info.stores_generics.size(); ++index) { |
| 153 | // TODO: Properly resolve attribute issues | 219 | // TODO: Properly resolve attribute issues |
| 154 | const auto declaration{ | 220 | const auto declaration{fmt::format("layout(location={}) out vec4 out_attr{}{};", index, |
| 155 | fmt::format("layout(location={}) out vec4 out_attr{};", index, index)}; | 221 | index, OutputDecorator(stage, program.invocations))}; |
| 156 | if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { | 222 | if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { |
| 157 | header += declaration; | 223 | header += declaration; |
| 158 | } | 224 | } |