diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate_program.cpp | 81 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate_program.h | 9 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 376aae0ea..3adbd2b16 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/settings.h" | 9 | #include "common/settings.h" |
| 10 | #include "shader_recompiler/exception.h" | 10 | #include "shader_recompiler/exception.h" |
| 11 | #include "shader_recompiler/frontend/ir/basic_block.h" | 11 | #include "shader_recompiler/frontend/ir/basic_block.h" |
| 12 | #include "shader_recompiler/frontend/ir/ir_emitter.h" | ||
| 12 | #include "shader_recompiler/frontend/ir/post_order.h" | 13 | #include "shader_recompiler/frontend/ir/post_order.h" |
| 13 | #include "shader_recompiler/frontend/maxwell/structured_control_flow.h" | 14 | #include "shader_recompiler/frontend/maxwell/structured_control_flow.h" |
| 14 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" | 15 | #include "shader_recompiler/frontend/maxwell/translate/translate.h" |
| @@ -233,6 +234,8 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo | |||
| 233 | Optimization::VerificationPass(program); | 234 | Optimization::VerificationPass(program); |
| 234 | } | 235 | } |
| 235 | Optimization::CollectShaderInfoPass(env, program); | 236 | Optimization::CollectShaderInfoPass(env, program); |
| 237 | Optimization::LayerPass(program, host_info); | ||
| 238 | |||
| 236 | CollectInterpolationInfo(env, program); | 239 | CollectInterpolationInfo(env, program); |
| 237 | AddNVNStorageBuffers(program); | 240 | AddNVNStorageBuffers(program); |
| 238 | return program; | 241 | return program; |
| @@ -331,4 +334,82 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run | |||
| 331 | } | 334 | } |
| 332 | } | 335 | } |
| 333 | 336 | ||
| 337 | IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool, | ||
| 338 | ObjectPool<IR::Block>& block_pool, | ||
| 339 | const HostTranslateInfo& host_info, | ||
| 340 | IR::Program& source_program, | ||
| 341 | Shader::OutputTopology output_topology) { | ||
| 342 | IR::Program program; | ||
| 343 | program.stage = Stage::Geometry; | ||
| 344 | program.output_topology = output_topology; | ||
| 345 | switch (output_topology) { | ||
| 346 | case OutputTopology::PointList: | ||
| 347 | program.output_vertices = 1; | ||
| 348 | break; | ||
| 349 | case OutputTopology::LineStrip: | ||
| 350 | program.output_vertices = 2; | ||
| 351 | break; | ||
| 352 | default: | ||
| 353 | program.output_vertices = 3; | ||
| 354 | break; | ||
| 355 | } | ||
| 356 | |||
| 357 | program.is_geometry_passthrough = false; | ||
| 358 | program.info.loads.mask = source_program.info.stores.mask; | ||
| 359 | program.info.stores.mask = source_program.info.stores.mask; | ||
| 360 | program.info.stores.Set(IR::Attribute::Layer, true); | ||
| 361 | program.info.stores.Set(source_program.info.emulated_layer, false); | ||
| 362 | |||
| 363 | IR::Block* current_block = block_pool.Create(inst_pool); | ||
| 364 | auto& node{program.syntax_list.emplace_back()}; | ||
| 365 | node.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 366 | node.data.block = current_block; | ||
| 367 | |||
| 368 | IR::IREmitter ir{*current_block}; | ||
| 369 | for (u32 i = 0; i < program.output_vertices; i++) { | ||
| 370 | // Assign generics from input | ||
| 371 | for (u32 j = 0; j < 32; j++) { | ||
| 372 | if (!program.info.stores.Generic(j)) { | ||
| 373 | continue; | ||
| 374 | } | ||
| 375 | |||
| 376 | const IR::Attribute attr = IR::Attribute::Generic0X + (j * 4); | ||
| 377 | ir.SetAttribute(attr + 0, ir.GetAttribute(attr + 0, ir.Imm32(i)), ir.Imm32(0)); | ||
| 378 | ir.SetAttribute(attr + 1, ir.GetAttribute(attr + 1, ir.Imm32(i)), ir.Imm32(0)); | ||
| 379 | ir.SetAttribute(attr + 2, ir.GetAttribute(attr + 2, ir.Imm32(i)), ir.Imm32(0)); | ||
| 380 | ir.SetAttribute(attr + 3, ir.GetAttribute(attr + 3, ir.Imm32(i)), ir.Imm32(0)); | ||
| 381 | } | ||
| 382 | |||
| 383 | // Assign position from input | ||
| 384 | const IR::Attribute attr = IR::Attribute::PositionX; | ||
| 385 | ir.SetAttribute(attr + 0, ir.GetAttribute(attr + 0, ir.Imm32(i)), ir.Imm32(0)); | ||
| 386 | ir.SetAttribute(attr + 1, ir.GetAttribute(attr + 1, ir.Imm32(i)), ir.Imm32(0)); | ||
| 387 | ir.SetAttribute(attr + 2, ir.GetAttribute(attr + 2, ir.Imm32(i)), ir.Imm32(0)); | ||
| 388 | ir.SetAttribute(attr + 3, ir.GetAttribute(attr + 3, ir.Imm32(i)), ir.Imm32(0)); | ||
| 389 | |||
| 390 | // Assign layer | ||
| 391 | ir.SetAttribute(IR::Attribute::Layer, ir.GetAttribute(source_program.info.emulated_layer), | ||
| 392 | ir.Imm32(0)); | ||
| 393 | |||
| 394 | // Emit vertex | ||
| 395 | ir.EmitVertex(ir.Imm32(0)); | ||
| 396 | } | ||
| 397 | ir.EndPrimitive(ir.Imm32(0)); | ||
| 398 | |||
| 399 | IR::Block* return_block{block_pool.Create(inst_pool)}; | ||
| 400 | IR::IREmitter{*return_block}.Epilogue(); | ||
| 401 | current_block->AddBranch(return_block); | ||
| 402 | |||
| 403 | auto& merge{program.syntax_list.emplace_back()}; | ||
| 404 | merge.type = IR::AbstractSyntaxNode::Type::Block; | ||
| 405 | merge.data.block = return_block; | ||
| 406 | program.syntax_list.emplace_back().type = IR::AbstractSyntaxNode::Type::Return; | ||
| 407 | |||
| 408 | program.blocks = GenerateBlocks(program.syntax_list); | ||
| 409 | program.post_order_blocks = PostOrder(program.syntax_list.front()); | ||
| 410 | Optimization::SsaRewritePass(program); | ||
| 411 | |||
| 412 | return program; | ||
| 413 | } | ||
| 414 | |||
| 334 | } // namespace Shader::Maxwell | 415 | } // namespace Shader::Maxwell |
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.h b/src/shader_recompiler/frontend/maxwell/translate_program.h index 02ede8c9c..497afe7cb 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.h +++ b/src/shader_recompiler/frontend/maxwell/translate_program.h | |||
| @@ -25,4 +25,13 @@ namespace Shader::Maxwell { | |||
| 25 | 25 | ||
| 26 | void ConvertLegacyToGeneric(IR::Program& program, const RuntimeInfo& runtime_info); | 26 | void ConvertLegacyToGeneric(IR::Program& program, const RuntimeInfo& runtime_info); |
| 27 | 27 | ||
| 28 | // Maxwell v1 and older Nvidia cards don't support setting gl_Layer from non-geometry stages. | ||
| 29 | // This creates a workaround by setting the layer as a generic output and creating a | ||
| 30 | // passthrough geometry shader that reads the generic and sets the layer. | ||
| 31 | [[nodiscard]] IR::Program GenerateGeometryPassthrough(ObjectPool<IR::Inst>& inst_pool, | ||
| 32 | ObjectPool<IR::Block>& block_pool, | ||
| 33 | const HostTranslateInfo& host_info, | ||
| 34 | IR::Program& source_program, | ||
| 35 | Shader::OutputTopology output_topology); | ||
| 36 | |||
| 28 | } // namespace Shader::Maxwell | 37 | } // namespace Shader::Maxwell |