summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp53
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h8
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp15
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp18
4 files changed, 76 insertions, 18 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index 6f10002fe..58355d5e3 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -37,7 +37,6 @@ bool StoresPerVertexAttributes(Stage stage) {
37 case Stage::VertexA: 37 case Stage::VertexA:
38 case Stage::VertexB: 38 case Stage::VertexB:
39 case Stage::Geometry: 39 case Stage::Geometry:
40 case Stage::TessellationControl:
41 case Stage::TessellationEval: 40 case Stage::TessellationEval:
42 return true; 41 return true;
43 default: 42 default:
@@ -154,9 +153,7 @@ void SetupOutPerVertex(Stage stage, const Info& info, std::string& header) {
154 return; 153 return;
155 } 154 }
156 header += "out gl_PerVertex{"; 155 header += "out gl_PerVertex{";
157 if (info.stores_position) { 156 header += "vec4 gl_Position;";
158 header += "vec4 gl_Position;";
159 }
160 if (info.stores_point_size) { 157 if (info.stores_point_size) {
161 header += "float gl_PointSize;"; 158 header += "float gl_PointSize;";
162 } 159 }
@@ -236,10 +233,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
236 } 233 }
237 for (size_t index = 0; index < info.stores_generics.size(); ++index) { 234 for (size_t index = 0; index < info.stores_generics.size(); ++index) {
238 // TODO: Properly resolve attribute issues 235 // TODO: Properly resolve attribute issues
239 const auto declaration{fmt::format("layout(location={}) out vec4 out_attr{}{};", index,
240 index, OutputDecorator(stage, program.invocations))};
241 if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) { 236 if (info.stores_generics[index] || stage == Stage::VertexA || stage == Stage::VertexB) {
242 header += declaration; 237 DefineGenericOutput(index, program.invocations);
243 } 238 }
244 } 239 }
245 header += "\n"; 240 header += "\n";
@@ -312,13 +307,53 @@ void EmitContext::DefineStorageBuffers(Bindings& bindings) {
312 } 307 }
313} 308}
314 309
310void EmitContext::DefineGenericOutput(size_t index, u32 invocations) {
311 static constexpr std::string_view swizzle{"xyzw"};
312 const size_t base_index{static_cast<size_t>(IR::Attribute::Generic0X) + index * 4};
313 u32 element{0};
314 while (element < 4) {
315 std::string definition{fmt::format("layout(location={}", index)};
316 const u32 remainder{4 - element};
317 const TransformFeedbackVarying* xfb_varying{};
318 if (!runtime_info.xfb_varyings.empty()) {
319 xfb_varying = &runtime_info.xfb_varyings[base_index + element];
320 xfb_varying = xfb_varying && xfb_varying->components > 0 ? xfb_varying : nullptr;
321 }
322 const u32 num_components{xfb_varying ? xfb_varying->components : remainder};
323 if (element > 0) {
324 definition += fmt::format(",component={}", element);
325 }
326 if (xfb_varying) {
327 definition +=
328 fmt::format(",xfb_buffer={},xfb_stride={},xfb_offset={}", xfb_varying->buffer,
329 xfb_varying->stride, xfb_varying->offset);
330 }
331 std::string name{fmt::format("out_attr{}", index)};
332 if (num_components < 4 || element > 0) {
333 name += fmt::format("_{}", swizzle.substr(element, num_components));
334 }
335 const auto type{num_components == 1 ? "float" : fmt::format("vec{}", num_components)};
336 definition += fmt::format(")out {} {}{};", type, name, OutputDecorator(stage, invocations));
337 header += definition;
338
339 const GenericElementInfo element_info{
340 .name = name,
341 .first_element = element,
342 .num_components = num_components,
343 };
344 std::fill_n(output_generics[index].begin() + element, num_components, element_info);
345 element += num_components;
346 }
347 header += "\n";
348}
349
315void EmitContext::DefineHelperFunctions() { 350void EmitContext::DefineHelperFunctions() {
316 if (info.uses_global_increment || info.uses_shared_increment) { 351 if (info.uses_global_increment || info.uses_shared_increment) {
317 header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; 352 header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n";
318 } 353 }
319 if (info.uses_global_decrement || info.uses_shared_decrement) { 354 if (info.uses_global_decrement || info.uses_shared_decrement) {
320 header += 355 header += "uint CasDecrement(uint op_a,uint "
321 "uint CasDecrement(uint op_a,uint op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n"; 356 "op_b){return(op_a==0||op_a>op_b)?op_b:(op_a-1u);}\n";
322 } 357 }
323 if (info.uses_atomic_f32_add) { 358 if (info.uses_atomic_f32_add) {
324 header += "uint CasFloatAdd(uint op_a,float op_b){return " 359 header += "uint CasFloatAdd(uint op_a,float op_b){return "
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 48786a2c7..5d48675e6 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -30,6 +30,12 @@ struct Program;
30 30
31namespace Shader::Backend::GLSL { 31namespace Shader::Backend::GLSL {
32 32
33struct GenericElementInfo {
34 std::string name{};
35 u32 first_element{};
36 u32 num_components{};
37};
38
33class EmitContext { 39class EmitContext {
34public: 40public:
35 explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 41 explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
@@ -149,6 +155,7 @@ public:
149 std::vector<u32> image_buffer_bindings; 155 std::vector<u32> image_buffer_bindings;
150 std::vector<u32> texture_bindings; 156 std::vector<u32> texture_bindings;
151 std::vector<u32> image_bindings; 157 std::vector<u32> image_bindings;
158 std::array<std::array<GenericElementInfo, 4>, 32> output_generics{};
152 159
153 bool uses_y_direction{}; 160 bool uses_y_direction{};
154 bool uses_cc_carry{}; 161 bool uses_cc_carry{};
@@ -157,6 +164,7 @@ private:
157 void SetupExtensions(std::string& header); 164 void SetupExtensions(std::string& header);
158 void DefineConstantBuffers(Bindings& bindings); 165 void DefineConstantBuffers(Bindings& bindings);
159 void DefineStorageBuffers(Bindings& bindings); 166 void DefineStorageBuffers(Bindings& bindings);
167 void DefineGenericOutput(size_t index, u32 invocations);
160 void DefineHelperFunctions(); 168 void DefineHelperFunctions();
161 void SetupImages(Bindings& bindings); 169 void SetupImages(Bindings& bindings);
162}; 170};
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 0cf31329d..c48492a17 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
@@ -200,13 +200,21 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
200 200
201void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, 201void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value,
202 [[maybe_unused]] std::string_view vertex) { 202 [[maybe_unused]] std::string_view vertex) {
203 const u32 element{static_cast<u32>(attr) % 4};
204 const char swizzle{"xyzw"[element]};
205 if (IR::IsGeneric(attr)) { 203 if (IR::IsGeneric(attr)) {
206 const u32 index{IR::GenericAttributeIndex(attr)}; 204 const u32 index{IR::GenericAttributeIndex(attr)};
207 ctx.Add("out_attr{}{}.{}={};", index, OutputVertexIndex(ctx, vertex), swizzle, value); 205 const u32 element{IR::GenericAttributeElement(attr)};
206 const GenericElementInfo& info{ctx.output_generics.at(index).at(element)};
207 const auto output_decorator{OutputVertexIndex(ctx, vertex)};
208 if (info.num_components == 1) {
209 ctx.Add("{}{}={};", info.name, output_decorator, value);
210 } else {
211 const u32 index_element{element - info.first_element};
212 ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value);
213 }
208 return; 214 return;
209 } 215 }
216 const u32 element{static_cast<u32>(attr) % 4};
217 const char swizzle{"xyzw"[element]};
210 switch (attr) { 218 switch (attr) {
211 case IR::Attribute::PointSize: 219 case IR::Attribute::PointSize:
212 ctx.Add("gl_PointSize={};", value); 220 ctx.Add("gl_PointSize={};", value);
@@ -233,7 +241,6 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
233 break; 241 break;
234 } 242 }
235 default: 243 default:
236 fmt::print("Set attribute {}", attr);
237 throw NotImplementedException("Set attribute {}", attr); 244 throw NotImplementedException("Set attribute {}", attr);
238 } 245 }
239} 246}
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index cd11ff653..0a1ba363b 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -92,9 +92,15 @@ GLenum AssemblyStage(size_t stage_index) {
92 92
93Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, 93Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
94 const Shader::IR::Program& program, 94 const Shader::IR::Program& program,
95 bool glasm_use_storage_buffers) { 95 bool glasm_use_storage_buffers, bool use_assembly_shaders) {
96 Shader::RuntimeInfo info; 96 Shader::RuntimeInfo info;
97 switch (program.stage) { 97 switch (program.stage) {
98 case Shader::Stage::VertexB:
99 case Shader::Stage::Geometry:
100 if (!use_assembly_shaders && key.xfb_enabled != 0) {
101 info.xfb_varyings = VideoCommon::MakeTransformFeedbackVaryings(key.xfb_state);
102 }
103 break;
98 case Shader::Stage::TessellationEval: 104 case Shader::Stage::TessellationEval:
99 info.tess_clockwise = key.tessellation_clockwise != 0; 105 info.tess_clockwise = key.tessellation_clockwise != 0;
100 info.tess_primitive = [&key] { 106 info.tess_primitive = [&key] {
@@ -420,7 +426,8 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
420 OGLProgram source_program; 426 OGLProgram source_program;
421 std::array<OGLAssemblyProgram, 5> assembly_programs; 427 std::array<OGLAssemblyProgram, 5> assembly_programs;
422 Shader::Backend::Bindings binding; 428 Shader::Backend::Bindings binding;
423 if (!device.UseAssemblyShaders()) { 429 const bool use_glasm{device.UseAssemblyShaders()};
430 if (!use_glasm) {
424 source_program.handle = glCreateProgram(); 431 source_program.handle = glCreateProgram();
425 } 432 }
426 const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; 433 const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0;
@@ -434,8 +441,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
434 const size_t stage_index{index - 1}; 441 const size_t stage_index{index - 1};
435 infos[stage_index] = &program.info; 442 infos[stage_index] = &program.info;
436 443
437 const auto runtime_info{MakeRuntimeInfo(key, program, glasm_use_storage_buffers)}; 444 const auto runtime_info{
438 if (device.UseAssemblyShaders()) { 445 MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)};
446 if (use_glasm) {
439 const std::string code{EmitGLASM(profile, runtime_info, program, binding)}; 447 const std::string code{EmitGLASM(profile, runtime_info, program, binding)};
440 assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index)); 448 assembly_programs[stage_index] = CompileProgram(code, AssemblyStage(stage_index));
441 } else { 449 } else {
@@ -443,7 +451,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
443 AttachShader(Stage(stage_index), source_program.handle, code); 451 AttachShader(Stage(stage_index), source_program.handle, code);
444 } 452 }
445 } 453 }
446 if (!device.UseAssemblyShaders()) { 454 if (!use_glasm) {
447 LinkProgram(source_program.handle); 455 LinkProgram(source_program.handle);
448 } 456 }
449 return std::make_unique<GraphicsPipeline>( 457 return std::make_unique<GraphicsPipeline>(