summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.cpp3
-rw-r--r--src/shader_recompiler/backend/glasm/emit_context.h1
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp65
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h2
4 files changed, 65 insertions, 6 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp
index 0f7d79843..b5b0e2204 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_context.cpp
@@ -30,9 +30,8 @@ bool IsInputArray(Stage stage) {
30 30
31EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, 31EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
32 const RuntimeInfo& runtime_info_) 32 const RuntimeInfo& runtime_info_)
33 : profile{profile_}, runtime_info{runtime_info_} { 33 : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
34 // FIXME: Temporary partial implementation 34 // FIXME: Temporary partial implementation
35 const auto& info{program.info};
36 u32 cbuf_index{}; 35 u32 cbuf_index{};
37 for (const auto& desc : info.constant_buffer_descriptors) { 36 for (const auto& desc : info.constant_buffer_descriptors) {
38 if (desc.count != 1) { 37 if (desc.count != 1) {
diff --git a/src/shader_recompiler/backend/glasm/emit_context.h b/src/shader_recompiler/backend/glasm/emit_context.h
index 1f057fdd5..057d74790 100644
--- a/src/shader_recompiler/backend/glasm/emit_context.h
+++ b/src/shader_recompiler/backend/glasm/emit_context.h
@@ -58,6 +58,7 @@ public:
58 58
59 std::string code; 59 std::string code;
60 RegAlloc reg_alloc{*this}; 60 RegAlloc reg_alloc{*this};
61 const Info& info;
61 const Profile& profile; 62 const Profile& profile;
62 const RuntimeInfo& runtime_info; 63 const RuntimeInfo& runtime_info;
63 64
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index 7a7297801..b44c00c73 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -8,6 +8,7 @@
8#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h" 8#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
9#include "shader_recompiler/frontend/ir/value.h" 9#include "shader_recompiler/frontend/ir/value.h"
10#include "shader_recompiler/profile.h" 10#include "shader_recompiler/profile.h"
11#include "shader_recompiler/shader_info.h"
11 12
12namespace Shader::Backend::GLASM { 13namespace Shader::Backend::GLASM {
13namespace { 14namespace {
@@ -153,9 +154,67 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value,
153 } 154 }
154} 155}
155 156
156void EmitGetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset, 157void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, ScalarS32 offset, ScalarU32 vertex) {
157 [[maybe_unused]] ScalarU32 vertex) { 158 // RC.x = base_index
158 throw NotImplementedException("GLASM instruction"); 159 // RC.y = masked_index
160 // RC.z = compare_index
161 ctx.Add("SHR.S RC.x,{},2;"
162 "AND.S RC.y,RC.x,3;"
163 "SHR.S RC.z,{},4;",
164 offset, offset);
165
166 const Register ret{ctx.reg_alloc.Define(inst)};
167 u32 num_endifs{};
168 const auto read{[&](u32 compare_index, const std::array<std::string, 4>& values) {
169 ++num_endifs;
170 ctx.Add("SEQ.S.CC RC.w,RC.z,{};" // compare_index
171 "IF NE.w;"
172 // X
173 "SEQ.S.CC RC.w,RC.y,0;"
174 "IF NE.w;"
175 "MOV {}.x,{};"
176 "ELSE;"
177 // Y
178 "SEQ.S.CC RC.w,RC.y,1;"
179 "IF NE.w;"
180 "MOV {}.x,{};"
181 "ELSE;"
182 // Z
183 "SEQ.S.CC RC.w,RC.y,2;"
184 "IF NE.w;"
185 "MOV {}.x,{};"
186 "ELSE;"
187 // W
188 "MOV {}.x,{};"
189 "ENDIF;"
190 "ENDIF;"
191 "ENDIF;"
192 "ELSE;",
193 compare_index, ret, values[0], ret, values[1], ret, values[2], ret, values[3]);
194 }};
195 const auto read_swizzled{[&](u32 compare_index, std::string_view value) {
196 const std::array values{fmt::format("{}.x", value), fmt::format("{}.y", value),
197 fmt::format("{}.z", value), fmt::format("{}.w", value)};
198 read(compare_index, values);
199 }};
200 if (ctx.info.loads_position) {
201 const u32 index{static_cast<u32>(IR::Attribute::PositionX)};
202 if (IsInputArray(ctx.stage)) {
203 read_swizzled(index, fmt::format("vertex_position{}", VertexIndex(ctx, vertex)));
204 } else {
205 read_swizzled(index, fmt::format("{}.position", ctx.attrib_name));
206 }
207 }
208 const u32 base_attribute_value{static_cast<u32>(IR::Attribute::Generic0X) >> 2};
209 for (u32 index = 0; index < ctx.info.input_generics.size(); ++index) {
210 if (!ctx.info.input_generics[index].used) {
211 continue;
212 }
213 read_swizzled(index, fmt::format("in_attr{}{}[0]", index, VertexIndex(ctx, vertex)));
214 }
215 for (u32 i = 0; i < num_endifs; ++i) {
216 ctx.Add("ENDIF;");
217 }
159} 218}
160 219
161void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset, 220void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset,
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 2cc3acedf..e205c3d14 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -51,7 +51,7 @@ void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
51void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset); 51void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset);
52void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ScalarU32 vertex); 52void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ScalarU32 vertex);
53void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value, ScalarU32 vertex); 53void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value, ScalarU32 vertex);
54void EmitGetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarU32 vertex); 54void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, ScalarS32 offset, ScalarU32 vertex);
55void EmitSetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarF32 value, ScalarU32 vertex); 55void EmitSetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarF32 value, ScalarU32 vertex);
56void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch); 56void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch);
57void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value); 57void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value);