emit_glsl_special.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <string_view>
  5. #include "shader_recompiler/backend/glsl/emit_context.h"
  6. #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
  7. #include "shader_recompiler/frontend/ir/program.h"
  8. #include "shader_recompiler/frontend/ir/value.h"
  9. #include "shader_recompiler/profile.h"
  10. namespace Shader::Backend::GLSL {
  11. namespace {
  12. void InitializeOutputVaryings(EmitContext& ctx) {
  13. if (ctx.stage == Stage::VertexB || ctx.stage == Stage::Geometry) {
  14. ctx.Add("gl_Position=vec4(0,0,0,1);");
  15. }
  16. for (size_t index = 0; index < 16; ++index) {
  17. if (ctx.info.stores_generics[index]) {
  18. ctx.Add("out_attr{}=vec4(0,0,0,1);", index);
  19. }
  20. }
  21. }
  22. } // Anonymous namespace
  23. void EmitPhi(EmitContext& ctx, IR::Inst& phi) {
  24. const size_t num_args{phi.NumArgs()};
  25. for (size_t i = 0; i < num_args; ++i) {
  26. ctx.var_alloc.Consume(phi.Arg(i));
  27. }
  28. if (!phi.Definition<Id>().is_valid) {
  29. // The phi node wasn't forward defined
  30. ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type());
  31. }
  32. }
  33. void EmitVoid(EmitContext&) {}
  34. void EmitReference(EmitContext& ctx, const IR::Value& value) {
  35. ctx.var_alloc.Consume(value);
  36. }
  37. void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) {
  38. IR::Inst& phi{*phi_value.InstRecursive()};
  39. const auto phi_type{phi.Arg(0).Type()};
  40. if (!phi.Definition<Id>().is_valid) {
  41. // The phi node wasn't forward defined
  42. ctx.var_alloc.PhiDefine(phi, phi_type);
  43. }
  44. const auto phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})};
  45. const auto val_reg{ctx.var_alloc.Consume(value)};
  46. if (phi_reg == val_reg) {
  47. return;
  48. }
  49. ctx.Add("{}={};", phi_reg, val_reg);
  50. }
  51. void EmitPrologue(EmitContext& ctx) {
  52. InitializeOutputVaryings(ctx);
  53. if (ctx.stage == Stage::Fragment && ctx.profile.need_declared_frag_colors) {
  54. for (size_t index = 0; index < ctx.info.stores_frag_color.size(); ++index) {
  55. if (ctx.info.stores_frag_color[index]) {
  56. continue;
  57. }
  58. ctx.Add("frag_color{}=vec4(0,0,0,1);", index);
  59. }
  60. }
  61. }
  62. void EmitEpilogue(EmitContext&) {}
  63. void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) {
  64. ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream));
  65. InitializeOutputVaryings(ctx);
  66. }
  67. void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
  68. ctx.Add("EndStreamPrimitive(int({}));", ctx.var_alloc.Consume(stream));
  69. }
  70. } // namespace Shader::Backend::GLSL