emit_context.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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/bindings.h"
  6. #include "shader_recompiler/backend/glasm/emit_context.h"
  7. #include "shader_recompiler/frontend/ir/program.h"
  8. #include "shader_recompiler/profile.h"
  9. #include "shader_recompiler/runtime_info.h"
  10. namespace Shader::Backend::GLASM {
  11. namespace {
  12. std::string_view InterpDecorator(Interpolation interp) {
  13. switch (interp) {
  14. case Interpolation::Smooth:
  15. return "";
  16. case Interpolation::Flat:
  17. return "FLAT ";
  18. case Interpolation::NoPerspective:
  19. return "NOPERSPECTIVE ";
  20. }
  21. throw InvalidArgument("Invalid interpolation {}", interp);
  22. }
  23. bool IsInputArray(Stage stage) {
  24. return stage == Stage::Geometry || stage == Stage::TessellationControl ||
  25. stage == Stage::TessellationEval;
  26. }
  27. } // Anonymous namespace
  28. EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
  29. const RuntimeInfo& runtime_info_)
  30. : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
  31. // FIXME: Temporary partial implementation
  32. u32 cbuf_index{};
  33. for (const auto& desc : info.constant_buffer_descriptors) {
  34. if (desc.count != 1) {
  35. throw NotImplementedException("Constant buffer descriptor array");
  36. }
  37. Add("CBUFFER c{}[]={{program.buffer[{}]}};", desc.index, cbuf_index);
  38. ++cbuf_index;
  39. }
  40. u32 ssbo_index{};
  41. for (const auto& desc : info.storage_buffers_descriptors) {
  42. if (desc.count != 1) {
  43. throw NotImplementedException("Storage buffer descriptor array");
  44. }
  45. if (runtime_info.glasm_use_storage_buffers) {
  46. Add("STORAGE ssbo{}[]={{program.storage[{}]}};", ssbo_index, bindings.storage_buffer);
  47. ++bindings.storage_buffer;
  48. ++ssbo_index;
  49. }
  50. }
  51. if (!runtime_info.glasm_use_storage_buffers) {
  52. if (const size_t num = info.storage_buffers_descriptors.size(); num > 0) {
  53. Add("PARAM c[{}]={{program.local[0..{}]}};", num, num - 1);
  54. }
  55. }
  56. stage = program.stage;
  57. switch (program.stage) {
  58. case Stage::VertexA:
  59. case Stage::VertexB:
  60. stage_name = "vertex";
  61. attrib_name = "vertex";
  62. break;
  63. case Stage::TessellationControl:
  64. case Stage::TessellationEval:
  65. stage_name = "primitive";
  66. attrib_name = "primitive";
  67. break;
  68. case Stage::Geometry:
  69. stage_name = "primitive";
  70. attrib_name = "vertex";
  71. break;
  72. case Stage::Fragment:
  73. stage_name = "fragment";
  74. attrib_name = "fragment";
  75. break;
  76. case Stage::Compute:
  77. stage_name = "invocation";
  78. break;
  79. }
  80. const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"};
  81. for (size_t index = 0; index < info.input_generics.size(); ++index) {
  82. const auto& generic{info.input_generics[index]};
  83. if (generic.used) {
  84. Add("{}ATTRIB in_attr{}[]={{{}.attrib[{}..{}]}};",
  85. InterpDecorator(generic.interpolation), index, attr_stage, index, index);
  86. }
  87. }
  88. if (IsInputArray(stage) && info.loads_position) {
  89. Add("ATTRIB vertex_position=vertex.position;");
  90. }
  91. if (info.uses_invocation_id) {
  92. Add("ATTRIB primitive_invocation=primitive.invocation;");
  93. }
  94. if (info.stores_tess_level_outer) {
  95. Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};");
  96. }
  97. if (info.stores_tess_level_inner) {
  98. Add("OUTPUT result_patch_tessinner[]={{result.patch.tessinner[0..1]}};");
  99. }
  100. if (info.stores_clip_distance) {
  101. Add("OUTPUT result_clip[]={{result.clip[0..7]}};");
  102. }
  103. for (size_t index = 0; index < info.uses_patches.size(); ++index) {
  104. if (!info.uses_patches[index]) {
  105. continue;
  106. }
  107. if (stage == Stage::TessellationControl) {
  108. Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};"
  109. "ATTRIB primitive_out_patch_attrib{}[]={{primitive.out.patch.attrib[{}..{}]}};",
  110. index, index, index, index, index, index);
  111. } else {
  112. Add("ATTRIB primitive_patch_attrib{}[]={{primitive.patch.attrib[{}..{}]}};", index,
  113. index, index);
  114. }
  115. }
  116. if (stage == Stage::Fragment) {
  117. Add("OUTPUT frag_color0=result.color;");
  118. for (size_t index = 1; index < info.stores_frag_color.size(); ++index) {
  119. Add("OUTPUT frag_color{}=result.color[{}];", index, index);
  120. }
  121. }
  122. for (size_t index = 0; index < info.stores_generics.size(); ++index) {
  123. if (info.stores_generics[index]) {
  124. Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index);
  125. }
  126. }
  127. image_buffer_bindings.reserve(info.image_buffer_descriptors.size());
  128. for (const auto& desc : info.image_buffer_descriptors) {
  129. image_buffer_bindings.push_back(bindings.image);
  130. bindings.image += desc.count;
  131. }
  132. image_bindings.reserve(info.image_descriptors.size());
  133. for (const auto& desc : info.image_descriptors) {
  134. image_bindings.push_back(bindings.image);
  135. bindings.image += desc.count;
  136. }
  137. texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size());
  138. for (const auto& desc : info.texture_buffer_descriptors) {
  139. texture_buffer_bindings.push_back(bindings.texture);
  140. bindings.texture += desc.count;
  141. }
  142. texture_bindings.reserve(info.texture_descriptors.size());
  143. for (const auto& desc : info.texture_descriptors) {
  144. texture_bindings.push_back(bindings.texture);
  145. bindings.texture += desc.count;
  146. }
  147. }
  148. } // namespace Shader::Backend::GLASM