glasm: Implement indirect attribute loads
This commit is contained in:
parent
c8414e686f
commit
e30d4fa976
4 changed files with 65 additions and 6 deletions
|
@ -30,9 +30,8 @@ bool IsInputArray(Stage stage) {
|
||||||
|
|
||||||
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
|
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
|
||||||
const RuntimeInfo& runtime_info_)
|
const RuntimeInfo& runtime_info_)
|
||||||
: profile{profile_}, runtime_info{runtime_info_} {
|
: info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
|
||||||
// FIXME: Temporary partial implementation
|
// FIXME: Temporary partial implementation
|
||||||
const auto& info{program.info};
|
|
||||||
u32 cbuf_index{};
|
u32 cbuf_index{};
|
||||||
for (const auto& desc : info.constant_buffer_descriptors) {
|
for (const auto& desc : info.constant_buffer_descriptors) {
|
||||||
if (desc.count != 1) {
|
if (desc.count != 1) {
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
RegAlloc reg_alloc{*this};
|
RegAlloc reg_alloc{*this};
|
||||||
|
const Info& info;
|
||||||
const Profile& profile;
|
const Profile& profile;
|
||||||
const RuntimeInfo& runtime_info;
|
const RuntimeInfo& runtime_info;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
|
#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
|
||||||
#include "shader_recompiler/frontend/ir/value.h"
|
#include "shader_recompiler/frontend/ir/value.h"
|
||||||
#include "shader_recompiler/profile.h"
|
#include "shader_recompiler/profile.h"
|
||||||
|
#include "shader_recompiler/shader_info.h"
|
||||||
|
|
||||||
namespace Shader::Backend::GLASM {
|
namespace Shader::Backend::GLASM {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -153,9 +154,67 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitGetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset,
|
void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, ScalarS32 offset, ScalarU32 vertex) {
|
||||||
[[maybe_unused]] ScalarU32 vertex) {
|
// RC.x = base_index
|
||||||
throw NotImplementedException("GLASM instruction");
|
// 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,
|
void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarU32 offset,
|
||||||
|
|
|
@ -51,7 +51,7 @@ void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
|
||||||
void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset);
|
void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset);
|
||||||
void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ScalarU32 vertex);
|
void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ScalarU32 vertex);
|
||||||
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value, ScalarU32 vertex);
|
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, ScalarF32 value, ScalarU32 vertex);
|
||||||
void EmitGetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarU32 vertex);
|
void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, ScalarS32 offset, ScalarU32 vertex);
|
||||||
void EmitSetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarF32 value, ScalarU32 vertex);
|
void EmitSetAttributeIndexed(EmitContext& ctx, ScalarU32 offset, ScalarF32 value, ScalarU32 vertex);
|
||||||
void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch);
|
void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch);
|
||||||
void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value);
|
void EmitSetPatch(EmitContext& ctx, IR::Patch patch, ScalarF32 value);
|
||||||
|
|
Loading…
Reference in a new issue