summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2021-05-22 23:29:43 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-07-23 03:51:33 +0200
commite30d4fa976f608a79629e12cac25f7b951e6b8fb (patch)
treef0bdf0d2f91fdf4faff7e746c31e71fac25d39b3 /src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
parentglasm: Implement image atomics (diff)
downloadyuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar.gz
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar.bz2
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar.lz
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar.xz
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.tar.zst
yuzu-e30d4fa976f608a79629e12cac25f7b951e6b8fb.zip
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp65
1 files changed, 62 insertions, 3 deletions
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 @@
#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
#include "shader_recompiler/frontend/ir/value.h"
#include "shader_recompiler/profile.h"
+#include "shader_recompiler/shader_info.h"
namespace Shader::Backend::GLASM {
namespace {
@@ -153,9 +154,67 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value,
}
}
-void EmitGetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset,
- [[maybe_unused]] ScalarU32 vertex) {
- throw NotImplementedException("GLASM instruction");
+void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, ScalarS32 offset, ScalarU32 vertex) {
+ // RC.x = base_index
+ // RC.y = masked_index
+ // RC.z = compare_index
+ ctx.Add("SHR.S RC.x,{},2;"
+ "AND.S RC.y,RC.x,3;"
+ "SHR.S RC.z,{},4;",
+ offset, offset);
+
+ const Register ret{ctx.reg_alloc.Define(inst)};
+ u32 num_endifs{};
+ const auto read{[&](u32 compare_index, const std::array<std::string, 4>& values) {
+ ++num_endifs;
+ ctx.Add("SEQ.S.CC RC.w,RC.z,{};" // compare_index
+ "IF NE.w;"
+ // X
+ "SEQ.S.CC RC.w,RC.y,0;"
+ "IF NE.w;"
+ "MOV {}.x,{};"
+ "ELSE;"
+ // Y
+ "SEQ.S.CC RC.w,RC.y,1;"
+ "IF NE.w;"
+ "MOV {}.x,{};"
+ "ELSE;"
+ // Z
+ "SEQ.S.CC RC.w,RC.y,2;"
+ "IF NE.w;"
+ "MOV {}.x,{};"
+ "ELSE;"
+ // W
+ "MOV {}.x,{};"
+ "ENDIF;"
+ "ENDIF;"
+ "ENDIF;"
+ "ELSE;",
+ compare_index, ret, values[0], ret, values[1], ret, values[2], ret, values[3]);
+ }};
+ const auto read_swizzled{[&](u32 compare_index, std::string_view value) {
+ const std::array values{fmt::format("{}.x", value), fmt::format("{}.y", value),
+ fmt::format("{}.z", value), fmt::format("{}.w", value)};
+ read(compare_index, values);
+ }};
+ if (ctx.info.loads_position) {
+ const u32 index{static_cast<u32>(IR::Attribute::PositionX)};
+ if (IsInputArray(ctx.stage)) {
+ read_swizzled(index, fmt::format("vertex_position{}", VertexIndex(ctx, vertex)));
+ } else {
+ read_swizzled(index, fmt::format("{}.position", ctx.attrib_name));
+ }
+ }
+ const u32 base_attribute_value{static_cast<u32>(IR::Attribute::Generic0X) >> 2};
+ for (u32 index = 0; index < ctx.info.input_generics.size(); ++index) {
+ if (!ctx.info.input_generics[index].used) {
+ continue;
+ }
+ read_swizzled(index, fmt::format("in_attr{}{}[0]", index, VertexIndex(ctx, vertex)));
+ }
+ for (u32 i = 0; i < num_endifs; ++i) {
+ ctx.Add("ENDIF;");
+ }
}
void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset,