summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
diff options
context:
space:
mode:
authorGravatar ameerj2021-12-05 16:33:44 -0500
committerGravatar ameerj2021-12-05 16:33:44 -0500
commit5286a7bc4ccf8da0827b0352f40dbce651b57d09 (patch)
tree083afe39f09a03615ea4b629e4d05522a587dbc7 /src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
parentMerge pull request #7518 from german77/is_npad_valid (diff)
downloadyuzu-5286a7bc4ccf8da0827b0352f40dbce651b57d09.tar.gz
yuzu-5286a7bc4ccf8da0827b0352f40dbce651b57d09.tar.xz
yuzu-5286a7bc4ccf8da0827b0352f40dbce651b57d09.zip
shader_recompiler: Rename backend emit_context files
Diffstat (limited to 'src/shader_recompiler/backend/glasm/glasm_emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/glasm_emit_context.cpp156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
new file mode 100644
index 000000000..8fd459dfe
--- /dev/null
+++ b/src/shader_recompiler/backend/glasm/glasm_emit_context.cpp
@@ -0,0 +1,156 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <string_view>
6
7#include "shader_recompiler/backend/bindings.h"
8#include "shader_recompiler/backend/glasm/emit_context.h"
9#include "shader_recompiler/backend/glasm/emit_glasm.h"
10#include "shader_recompiler/frontend/ir/program.h"
11#include "shader_recompiler/profile.h"
12#include "shader_recompiler/runtime_info.h"
13
14namespace Shader::Backend::GLASM {
15namespace {
16std::string_view InterpDecorator(Interpolation interp) {
17 switch (interp) {
18 case Interpolation::Smooth:
19 return "";
20 case Interpolation::Flat:
21 return "FLAT ";
22 case Interpolation::NoPerspective:
23 return "NOPERSPECTIVE ";
24 }
25 throw InvalidArgument("Invalid interpolation {}", interp);
26}
27
28bool IsInputArray(Stage stage) {
29 return stage == Stage::Geometry || stage == Stage::TessellationControl ||
30 stage == Stage::TessellationEval;
31}
32} // Anonymous namespace
33
34EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
35 const RuntimeInfo& runtime_info_)
36 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
37 // FIXME: Temporary partial implementation
38 u32 cbuf_index{};
39 for (const auto& desc : info.constant_buffer_descriptors) {
40 if (desc.count != 1) {
41 throw NotImplementedException("Constant buffer descriptor array");
42 }
43 Add("CBUFFER c{}[]={{program.buffer[{}]}};", desc.index, cbuf_index);
44 ++cbuf_index;
45 }
46 u32 ssbo_index{};
47 for (const auto& desc : info.storage_buffers_descriptors) {
48 if (desc.count != 1) {
49 throw NotImplementedException("Storage buffer descriptor array");
50 }
51 if (runtime_info.glasm_use_storage_buffers) {
52 Add("STORAGE ssbo{}[]={{program.storage[{}]}};", ssbo_index, bindings.storage_buffer);
53 ++bindings.storage_buffer;
54 ++ssbo_index;
55 }
56 }
57 if (!runtime_info.glasm_use_storage_buffers) {
58 if (const size_t num = info.storage_buffers_descriptors.size(); num > 0) {
59 const size_t index{num + PROGRAM_LOCAL_PARAMETER_STORAGE_BUFFER_BASE};
60 Add("PARAM c[{}]={{program.local[0..{}]}};", index, index - 1);
61 }
62 }
63 stage = program.stage;
64 switch (program.stage) {
65 case Stage::VertexA:
66 case Stage::VertexB:
67 stage_name = "vertex";
68 attrib_name = "vertex";
69 break;
70 case Stage::TessellationControl:
71 case Stage::TessellationEval:
72 stage_name = "primitive";
73 attrib_name = "primitive";
74 break;
75 case Stage::Geometry:
76 stage_name = "primitive";
77 attrib_name = "vertex";
78 break;
79 case Stage::Fragment:
80 stage_name = "fragment";
81 attrib_name = "fragment";
82 break;
83 case Stage::Compute:
84 stage_name = "invocation";
85 break;
86 }
87 const std::string_view attr_stage{stage == Stage::Fragment ? "fragment" : "vertex"};
88 const VaryingState loads{info.loads.mask | info.passthrough.mask};
89 for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
90 if (loads.Generic(index)) {
91 Add("{}ATTRIB in_attr{}[]={{{}.attrib[{}..{}]}};",
92 InterpDecorator(info.interpolation[index]), index, attr_stage, index, index);
93 }
94 }
95 if (IsInputArray(stage) && loads.AnyComponent(IR::Attribute::PositionX)) {
96 Add("ATTRIB vertex_position=vertex.position;");
97 }
98 if (info.uses_invocation_id) {
99 Add("ATTRIB primitive_invocation=primitive.invocation;");
100 }
101 if (info.stores_tess_level_outer) {
102 Add("OUTPUT result_patch_tessouter[]={{result.patch.tessouter[0..3]}};");
103 }
104 if (info.stores_tess_level_inner) {
105 Add("OUTPUT result_patch_tessinner[]={{result.patch.tessinner[0..1]}};");
106 }
107 if (info.stores.ClipDistances()) {
108 Add("OUTPUT result_clip[]={{result.clip[0..7]}};");
109 }
110 for (size_t index = 0; index < info.uses_patches.size(); ++index) {
111 if (!info.uses_patches[index]) {
112 continue;
113 }
114 if (stage == Stage::TessellationControl) {
115 Add("OUTPUT result_patch_attrib{}[]={{result.patch.attrib[{}..{}]}};"
116 "ATTRIB primitive_out_patch_attrib{}[]={{primitive.out.patch.attrib[{}..{}]}};",
117 index, index, index, index, index, index);
118 } else {
119 Add("ATTRIB primitive_patch_attrib{}[]={{primitive.patch.attrib[{}..{}]}};", index,
120 index, index);
121 }
122 }
123 if (stage == Stage::Fragment) {
124 Add("OUTPUT frag_color0=result.color;");
125 for (size_t index = 1; index < info.stores_frag_color.size(); ++index) {
126 Add("OUTPUT frag_color{}=result.color[{}];", index, index);
127 }
128 }
129 for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
130 if (info.stores.Generic(index)) {
131 Add("OUTPUT out_attr{}[]={{result.attrib[{}..{}]}};", index, index, index);
132 }
133 }
134 image_buffer_bindings.reserve(info.image_buffer_descriptors.size());
135 for (const auto& desc : info.image_buffer_descriptors) {
136 image_buffer_bindings.push_back(bindings.image);
137 bindings.image += desc.count;
138 }
139 image_bindings.reserve(info.image_descriptors.size());
140 for (const auto& desc : info.image_descriptors) {
141 image_bindings.push_back(bindings.image);
142 bindings.image += desc.count;
143 }
144 texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size());
145 for (const auto& desc : info.texture_buffer_descriptors) {
146 texture_buffer_bindings.push_back(bindings.texture);
147 bindings.texture += desc.count;
148 }
149 texture_bindings.reserve(info.texture_descriptors.size());
150 for (const auto& desc : info.texture_descriptors) {
151 texture_bindings.push_back(bindings.texture);
152 bindings.texture += desc.count;
153 }
154}
155
156} // namespace Shader::Backend::GLASM