summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp50
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp15
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp4
4 files changed, 62 insertions, 9 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index 2a5ec7414..923060386 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -21,6 +21,15 @@ std::string_view InterpDecorator(Interpolation interp) {
21 throw InvalidArgument("Invalid interpolation {}", interp); 21 throw InvalidArgument("Invalid interpolation {}", interp);
22} 22}
23 23
24std::string_view ArrayDecorator(Stage stage) {
25 switch (stage) {
26 case Stage::Geometry:
27 return "[1]";
28 default:
29 return "";
30 }
31}
32
24std::string_view SamplerType(TextureType type, bool is_depth) { 33std::string_view SamplerType(TextureType type, bool is_depth) {
25 if (is_depth) { 34 if (is_depth) {
26 switch (type) { 35 switch (type) {
@@ -64,6 +73,33 @@ std::string_view SamplerType(TextureType type, bool is_depth) {
64 } 73 }
65} 74}
66 75
76std::string_view InputPrimitive(InputTopology topology) {
77 switch (topology) {
78 case InputTopology::Points:
79 return "points";
80 case InputTopology::Lines:
81 return "lines";
82 case InputTopology::LinesAdjacency:
83 return "lines_adjacency";
84 case InputTopology::Triangles:
85 return "triangles";
86 case InputTopology::TrianglesAdjacency:
87 return "triangles_adjacency";
88 }
89 throw InvalidArgument("Invalid input topology {}", topology);
90}
91
92std::string_view OutputPrimitive(OutputTopology topology) {
93 switch (topology) {
94 case OutputTopology::PointList:
95 return "points";
96 case OutputTopology::LineStrip:
97 return "line_strip";
98 case OutputTopology::TriangleStrip:
99 return "triangle_strip";
100 }
101 throw InvalidArgument("Invalid output topology {}", topology);
102}
67} // namespace 103} // namespace
68 104
69EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 105EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
@@ -85,6 +121,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
85 break; 121 break;
86 case Stage::Geometry: 122 case Stage::Geometry:
87 stage_name = "gs"; 123 stage_name = "gs";
124 header += fmt::format("layout({})in;layout({}, max_vertices={})out;\n",
125 InputPrimitive(runtime_info.input_topology),
126 OutputPrimitive(program.output_topology), program.output_vertices);
88 break; 127 break;
89 case Stage::Fragment: 128 case Stage::Fragment:
90 stage_name = "fs"; 129 stage_name = "fs";
@@ -99,8 +138,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
99 for (size_t index = 0; index < info.input_generics.size(); ++index) { 138 for (size_t index = 0; index < info.input_generics.size(); ++index) {
100 const auto& generic{info.input_generics[index]}; 139 const auto& generic{info.input_generics[index]};
101 if (generic.used) { 140 if (generic.used) {
102 header += fmt::format("layout(location={}) {} in vec4 in_attr{};", index, 141 header +=
103 InterpDecorator(generic.interpolation), index); 142 fmt::format("layout(location={}){} in vec4 in_attr{}{};", index,
143 InterpDecorator(generic.interpolation), index, ArrayDecorator(stage));
104 } 144 }
105 } 145 }
106 for (size_t index = 0; index < info.stores_frag_color.size(); ++index) { 146 for (size_t index = 0; index < info.stores_frag_color.size(); ++index) {
@@ -126,8 +166,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
126void EmitContext::SetupExtensions(std::string&) { 166void EmitContext::SetupExtensions(std::string&) {
127 // TODO: track this usage 167 // TODO: track this usage
128 header += "#extension GL_ARB_sparse_texture2 : enable\n"; 168 header += "#extension GL_ARB_sparse_texture2 : enable\n";
129 header += "#extension GL_ARB_shader_viewport_layer_array : enable\n";
130 header += "#extension GL_NV_viewport_array2 : enable\n";
131 header += "#extension GL_EXT_texture_shadow_lod : enable\n"; 169 header += "#extension GL_EXT_texture_shadow_lod : enable\n";
132 if (info.uses_int64) { 170 if (info.uses_int64) {
133 header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; 171 header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
@@ -157,6 +195,10 @@ void EmitContext::SetupExtensions(std::string&) {
157 header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; 195 header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
158 } 196 }
159 } 197 }
198 if (info.stores_viewport_index) {
199 header += "#extension GL_ARB_shader_viewport_layer_array : enable\n";
200 header += "#extension GL_NV_viewport_array2 : enable\n";
201 }
160} 202}
161 203
162void EmitContext::DefineConstantBuffers(Bindings& bindings) { 204void EmitContext::DefineConstantBuffers(Bindings& bindings) {
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index 19cf4e46b..f467d978c 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -162,7 +162,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
162 break; 162 break;
163 default: 163 default:
164 fmt::print("{}", node.type); 164 fmt::print("{}", node.type);
165 throw NotImplementedException("{}", node.type); 165 throw NotImplementedException("AbstractSyntaxNode::Type {}", node.type);
166 break; 166 break;
167 } 167 }
168 } 168 }
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
index c66b4b282..28e89a0a6 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
@@ -19,6 +19,15 @@ u32 CbufIndex(u32 offset) {
19char OffsetSwizzle(u32 offset) { 19char OffsetSwizzle(u32 offset) {
20 return SWIZZLE[CbufIndex(offset)]; 20 return SWIZZLE[CbufIndex(offset)];
21} 21}
22
23bool IsInputArray(Stage stage) {
24 return stage == Stage::Geometry || stage == Stage::TessellationControl ||
25 stage == Stage::TessellationEval;
26}
27
28std::string VertexIndex(EmitContext& ctx, std::string_view vertex) {
29 return IsInputArray(ctx.stage) ? fmt::format("[{}]", vertex) : "";
30}
22} // namespace 31} // namespace
23 32
24void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 33void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
@@ -128,7 +137,7 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
128 const char swizzle{"xyzw"[element]}; 137 const char swizzle{"xyzw"[element]};
129 if (IR::IsGeneric(attr)) { 138 if (IR::IsGeneric(attr)) {
130 const u32 index{IR::GenericAttributeIndex(attr)}; 139 const u32 index{IR::GenericAttributeIndex(attr)};
131 ctx.AddF32("{}=in_attr{}.{};", inst, index, swizzle); 140 ctx.AddF32("{}=in_attr{}{}.{};", inst, index, VertexIndex(ctx, vertex), swizzle);
132 return; 141 return;
133 } 142 }
134 switch (attr) { 143 switch (attr) {
@@ -139,9 +148,11 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
139 switch (ctx.stage) { 148 switch (ctx.stage) {
140 case Stage::VertexA: 149 case Stage::VertexA:
141 case Stage::VertexB: 150 case Stage::VertexB:
142 case Stage::Geometry:
143 ctx.AddF32("{}=gl_Position.{};", inst, swizzle); 151 ctx.AddF32("{}=gl_Position.{};", inst, swizzle);
144 break; 152 break;
153 case Stage::Geometry:
154 ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle);
155 break;
145 case Stage::Fragment: 156 case Stage::Fragment:
146 ctx.AddF32("{}=gl_FragCoord.{};", inst, swizzle); 157 ctx.AddF32("{}=gl_FragCoord.{};", inst, swizzle);
147 break; 158 break;
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
index e3d0b15ba..9e5715605 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -103,11 +103,11 @@ void EmitEpilogue(EmitContext& ctx) {
103} 103}
104 104
105void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { 105void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
106 NotImplemented(); 106 ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream));
107} 107}
108 108
109void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { 109void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
110 NotImplemented(); 110 ctx.Add("EndStreamPrimitive(int({}));", ctx.var_alloc.Consume(stream));
111} 111}
112 112
113void EmitGetRegister(EmitContext& ctx) { 113void EmitGetRegister(EmitContext& ctx) {