emit_context.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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/glasm/emit_context.h"
  6. #include "shader_recompiler/frontend/ir/program.h"
  7. namespace Shader::Backend::GLASM {
  8. namespace {
  9. std::string_view InterpDecorator(Interpolation interp) {
  10. switch (interp) {
  11. case Interpolation::Smooth:
  12. return "";
  13. case Interpolation::Flat:
  14. return "FLAT ";
  15. case Interpolation::NoPerspective:
  16. return "NOPERSPECTIVE ";
  17. }
  18. throw InvalidArgument("Invalid interpolation {}", interp);
  19. }
  20. } // Anonymous namespace
  21. EmitContext::EmitContext(IR::Program& program) {
  22. // FIXME: Temporary partial implementation
  23. u32 cbuf_index{};
  24. for (const auto& desc : program.info.constant_buffer_descriptors) {
  25. if (desc.count != 1) {
  26. throw NotImplementedException("Constant buffer descriptor array");
  27. }
  28. Add("CBUFFER c{}[]={{program.buffer[{}]}};", desc.index, cbuf_index);
  29. ++cbuf_index;
  30. }
  31. for (const auto& desc : program.info.storage_buffers_descriptors) {
  32. if (desc.count != 1) {
  33. throw NotImplementedException("Storage buffer descriptor array");
  34. }
  35. }
  36. if (const size_t num = program.info.storage_buffers_descriptors.size(); num > 0) {
  37. Add("PARAM c[{}]={{program.local[0..{}]}};", num, num - 1);
  38. }
  39. switch (program.stage) {
  40. case Stage::VertexA:
  41. case Stage::VertexB:
  42. stage_name = "vertex";
  43. break;
  44. case Stage::TessellationControl:
  45. case Stage::TessellationEval:
  46. case Stage::Geometry:
  47. stage_name = "primitive";
  48. break;
  49. case Stage::Fragment:
  50. stage_name = "fragment";
  51. break;
  52. case Stage::Compute:
  53. stage_name = "compute";
  54. break;
  55. }
  56. for (size_t index = 0; index < program.info.input_generics.size(); ++index) {
  57. const auto& generic{program.info.input_generics[index]};
  58. if (generic.used) {
  59. Add("{}ATTRIB in_attr{}[]={{{}.attrib[{}..{}]}};",
  60. InterpDecorator(generic.interpolation), index, stage_name, index, index);
  61. }
  62. }
  63. for (size_t index = 0; index < program.info.stores_frag_color.size(); ++index) {
  64. if (!program.info.stores_frag_color[index]) {
  65. continue;
  66. }
  67. if (index == 0) {
  68. Add("OUTPUT frag_color0=result.color;");
  69. } else {
  70. Add("OUTPUT frag_color{}=result.color[{}];", index, index);
  71. }
  72. }
  73. for (size_t index = 0; index < program.info.stores_generics.size(); ++index) {
  74. if (program.info.stores_generics[index]) {
  75. Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index);
  76. }
  77. }
  78. }
  79. } // namespace Shader::Backend::GLASM