yuzu-emu
/
yuzu
Archived
1
0
Fork 0

glsl: TLD4 implementation

This commit is contained in:
ameerj 2021-05-29 16:58:33 -04:00
parent 697eacd095
commit 5fd92780b2
1 changed files with 89 additions and 2 deletions

View File

@ -67,6 +67,23 @@ std::string ShadowSamplerVecCast(TextureType type) {
} }
} }
std::string PtpOffsets(const IR::Value& offset, const IR::Value& offset2) {
const std::array values{offset.InstRecursive(), offset2.InstRecursive()};
if (!values[0]->AreAllArgsImmediates() || !values[1]->AreAllArgsImmediates()) {
// LOG_WARNING("Not all arguments in PTP are immediate, STUBBING");
return "";
}
const IR::Opcode opcode{values[0]->GetOpcode()};
if (opcode != values[1]->GetOpcode() || opcode != IR::Opcode::CompositeConstructU32x4) {
throw LogicError("Invalid PTP arguments");
}
auto read{[&](unsigned int a, unsigned int b) { return values[a]->Arg(b).U32(); }};
return fmt::format("ivec2[](ivec2({},{}),ivec2({},{}),ivec2({},{}),ivec2({},{}))", read(0, 0),
read(0, 1), read(0, 2), read(0, 3), read(1, 0), read(1, 1), read(1, 2),
read(1, 3));
}
IR::Inst* PrepareSparse(IR::Inst& inst) { IR::Inst* PrepareSparse(IR::Inst& inst) {
const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
if (sparse_inst) { if (sparse_inst) {
@ -213,7 +230,45 @@ void EmitImageGather([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Ins
[[maybe_unused]] std::string_view coords, [[maybe_unused]] std::string_view coords,
[[maybe_unused]] const IR::Value& offset, [[maybe_unused]] const IR::Value& offset,
[[maybe_unused]] const IR::Value& offset2) { [[maybe_unused]] const IR::Value& offset2) {
throw NotImplementedException("GLSL Instruction"); const auto info{inst.Flags<IR::TextureInstInfo>()};
const auto texture{Texture(ctx, info, index)};
const auto texel{ctx.reg_alloc.Define(inst, Type::F32x4)};
const auto sparse_inst{PrepareSparse(inst)};
if (!offset2.IsEmpty()) {
ctx.Add("/*OFFSET 2 IS {}*/", ctx.reg_alloc.Consume(offset2));
}
if (!sparse_inst) {
if (offset.IsEmpty()) {
ctx.Add("{}=textureGather({},{},int({}));", texel, texture, coords,
info.gather_component);
return;
}
if (offset2.IsEmpty()) {
ctx.Add("{}=textureGatherOffset({},{},{},int({}));", texel, texture, coords,
CastToIntVec(ctx.reg_alloc.Consume(offset), info), info.gather_component);
return;
}
// PTP
const auto offsets{PtpOffsets(offset, offset2)};
ctx.Add("{}=textureGatherOffsets({},{},{},int({}));", texel, texture, coords, offsets,
info.gather_component);
return;
}
// TODO: Query sparseTexels extension support
if (offset.IsEmpty()) {
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherARB({},{},{},int({})));",
*sparse_inst, texture, coords, texel, info.gather_component);
}
if (offset2.IsEmpty()) {
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherOffsetARB({},{},{},{},int({})));",
*sparse_inst, texture, CastToIntVec(coords, info),
CastToIntVec(ctx.reg_alloc.Consume(offset), info), texel, info.gather_component);
}
// PTP
const auto offsets{PtpOffsets(offset, offset2)};
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherOffsetARB({},{},{},{},int({})));",
*sparse_inst, texture, CastToIntVec(coords, info), offsets, texel,
info.gather_component);
} }
void EmitImageGatherDref([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, void EmitImageGatherDref([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
@ -222,7 +277,39 @@ void EmitImageGatherDref([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR:
[[maybe_unused]] const IR::Value& offset, [[maybe_unused]] const IR::Value& offset,
[[maybe_unused]] const IR::Value& offset2, [[maybe_unused]] const IR::Value& offset2,
[[maybe_unused]] std::string_view dref) { [[maybe_unused]] std::string_view dref) {
throw NotImplementedException("GLSL Instruction"); const auto info{inst.Flags<IR::TextureInstInfo>()};
const auto texture{Texture(ctx, info, index)};
const auto texel{ctx.reg_alloc.Define(inst, Type::F32x4)};
const auto sparse_inst{PrepareSparse(inst)};
if (!sparse_inst) {
if (offset.IsEmpty()) {
ctx.Add("{}=textureGather({},{},{});", texel, texture, coords, dref);
return;
}
if (offset2.IsEmpty()) {
ctx.Add("{}=textureGatherOffset({},{},{},{});", texel, texture, coords, dref,
CastToIntVec(ctx.reg_alloc.Consume(offset), info));
return;
}
// PTP
const auto offsets{PtpOffsets(offset, offset2)};
ctx.Add("{}=textureGatherOffsets({},{},{},{});", texel, texture, coords, dref, offsets);
return;
}
// TODO: Query sparseTexels extension support
if (offset.IsEmpty()) {
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherARB({},{},{},{}));", *sparse_inst,
texture, coords, dref, texel);
}
if (offset2.IsEmpty()) {
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherOffsetARB({},{},{},,{},{}));",
*sparse_inst, texture, CastToIntVec(coords, info), dref,
CastToIntVec(ctx.reg_alloc.Consume(offset), info), texel);
}
// PTP
const auto offsets{PtpOffsets(offset, offset2)};
ctx.AddU1("{}=sparseTexelsResidentARB(sparseTextureGatherOffsetARB({},{},{},,{},{}));",
*sparse_inst, texture, CastToIntVec(coords, info), dref, offsets, texel);
} }
void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,