Fix IR Debug Print. Add StringLiteral op

This commit is contained in:
Frodo Baggins 2024-09-19 19:39:48 -07:00
parent 060cbe5391
commit 69b3eff9c9
8 changed files with 49 additions and 28 deletions

View file

@ -50,7 +50,8 @@ void EmitEpilogue(EmitContext& ctx);
void EmitDiscard(EmitContext& ctx);
void EmitDiscardCond(EmitContext& ctx, Id condition);
void EmitVaArg(EmitContext& ctx, IR::Inst* inst, Id arg, Id next);
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst);
Id EmitStringLiteral(EmitContext& ctx, IR::Inst* inst);
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt);
void EmitBarrier(EmitContext& ctx);
void EmitWorkgroupMemoryBarrier(EmitContext& ctx);
void EmitDeviceMemoryBarrier(EmitContext& ctx);

View file

@ -2,11 +2,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <iterator>
#include <boost/container/small_vector.hpp>
#include "common/assert.h"
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
#include "shader_recompiler/backend/spirv/spirv_emit_context.h"
#include "shader_recompiler/ir/debug_print.h"
#include "shader_recompiler/ir/opcodes.h"
namespace Shader::Backend::SPIRV {
@ -53,10 +55,17 @@ void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) {
throw NotImplementedException("Geometry streams");
}
static bool isEmptyInst(IR::Value val) {
if (auto* inst = val.TryInstRecursive()) {
return inst->GetOpcode() == IR::Opcode::Void;
}
return false;
}
void EmitVaArg(EmitContext& ctx, IR::Inst* inst, Id arg, Id next) {
IR::Value next_val = inst->Arg(1);
u32 va_arglist_idx;
if (next_val.IsEmpty()) {
if (isEmptyInst(next_val)) {
va_arglist_idx = ctx.va_arg_lists.size();
ctx.va_arg_lists.emplace_back();
} else {
@ -64,26 +73,27 @@ void EmitVaArg(EmitContext& ctx, IR::Inst* inst, Id arg, Id next) {
}
ctx.va_arg_lists[va_arglist_idx].push_back(arg);
VariadicArgInfo va_info;
auto va_info = inst->Flags<VariadicArgInfo>();
va_info.va_arg_idx.Assign(va_arglist_idx);
inst->SetFlags(va_info);
}
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst) {
const std::string& fmt =
ctx.info.debug_print_strings.at(inst->Flags<DebugPrintInfo>().string_idx);
Id fmt_id = ctx.String(fmt);
Id EmitStringLiteral(EmitContext& ctx, IR::Inst* inst) {
// ctx.
return ctx.String(inst->StringLiteral());
}
IR::Value va_arg_list_val = inst->Arg(0);
void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt) {
IR::Value arglist = inst->Arg(1);
boost::container::small_vector<Id, 4> fmt_arg_operands;
if (!va_arg_list_val.IsEmpty()) {
u32 va_arglist_idx = va_arg_list_val.Inst()->Flags<VariadicArgInfo>().va_arg_idx;
if (!isEmptyInst(arglist)) {
u32 va_arglist_idx = arglist.Inst()->Flags<VariadicArgInfo>().va_arg_idx;
const auto& va_arglist = ctx.va_arg_lists[va_arglist_idx];
// reverse the order
std::copy(va_arglist.rbegin(), va_arglist.rend(), fmt_arg_operands.end());
std::copy(va_arglist.rbegin(), va_arglist.rend(), std::back_inserter(fmt_arg_operands));
}
ASSERT(fmt_arg_operands.size() == inst->Flags<DebugPrintInfo>().num_args);
ctx.OpDebugPrintf(fmt_id, fmt_arg_operands);
ctx.OpDebugPrintf(fmt, fmt_arg_operands);
}
} // namespace Shader::Backend::SPIRV

View file

@ -179,8 +179,6 @@ struct Info {
std::span<const u32> user_data;
Stage stage;
boost::container::small_vector<std::string, 4> debug_print_strings;
u64 pgm_hash{};
VAddr pgm_base;
bool has_storage_images{};

View file

@ -7,10 +7,4 @@ union VariadicArgInfo {
u32 raw;
BitField<0, 12, u32> va_arg_idx;
};
union DebugPrintInfo {
u32 raw;
BitField<0, 16, u32> string_idx;
BitField<16, 16, u32> num_args;
};

View file

@ -1562,6 +1562,12 @@ Value IREmitter::VaArg(Value arg, Value next) {
return Inst(Opcode::VaArg, arg, next);
}
Value IREmitter::StringLiteral(std::string_view s) {
Value val = Inst(Opcode::StringLiteral);
val.Inst()->SetStringLiteral(s);
return val;
}
void IREmitter::DebugPrint(std::string_view format, boost::container::small_vector<Value, 4> args,
bool infer_specifiers) {
auto infer_specifier = [&](IR::Value arg) -> const char* {
@ -1611,16 +1617,13 @@ void IREmitter::DebugPrint(std::string_view format, boost::container::small_vect
// could use param pack for this function, but less flexible
}
DebugPrintInfo info{};
info.string_idx.Assign(debug_print_strings.size());
info.num_args.Assign(args.size());
Value arg_list = Inst(Opcode::Void);
for (Value arg : args) {
arg_list = VaArg(arg, arg_list);
}
Inst(Opcode::DebugPrint, Flags{info}, arg_list);
Value string_val = StringLiteral(format);
Inst(Opcode::DebugPrint, string_val, arg_list);
}
} // namespace Shader::IR

View file

@ -47,6 +47,7 @@ public:
void Discard(const U1& cond);
Value VaArg(Value arg, Value next);
Value StringLiteral(std::string_view s);
void DebugPrint(std::string_view format, boost::container::small_vector<Value, 4> args,
bool infer_specifiers = false);
@ -319,7 +320,6 @@ public:
private:
IR::Block::iterator insertion_point;
boost::container::small_vector<std::string, 4> debug_print_strings;
template <typename T = Value, typename... Args>
T Inst(Opcode op, Args... args) {

View file

@ -14,8 +14,9 @@ OPCODE(Prologue, Void,
OPCODE(Epilogue, Void, )
OPCODE(Discard, Void, )
OPCODE(DiscardCond, Void, U1, )
OPCODE(DebugPrint, Void, Opaque, )
OPCODE(DebugPrint, Void, Opaque, Opaque, )
OPCODE(VaArg, Opaque, Opaque, Opaque )
OPCODE(StringLiteral, Opaque, )
// Constant memory operations
OPCODE(ReadConst, U32, U32x2, U32, )

View file

@ -6,9 +6,11 @@
#include <array>
#include <bit>
#include <cstring>
#include <string_view>
#include <type_traits>
#include <utility>
#include <boost/container/small_vector.hpp>
#include <boost/container/string.hpp>
#include <boost/intrusive/list.hpp>
#include "common/assert.h"
@ -146,6 +148,7 @@ public:
if (op == IR::Opcode::Phi) {
return phi_args[index].second;
} else {
ASSERT(op != IR::Opcode::StringLiteral);
return args[index];
}
}
@ -158,6 +161,16 @@ public:
/// Add phi operand to a phi instruction.
void AddPhiOperand(Block* predecessor, const Value& value);
[[nodiscard]] std::string_view StringLiteral() const {
ASSERT(op == IR::Opcode::StringLiteral);
return string_literal;
}
void SetStringLiteral(std::string_view s) noexcept {
ASSERT(op == IR::Opcode::StringLiteral);
string_literal = s;
}
void Invalidate();
void ClearArgs();
@ -207,6 +220,7 @@ private:
NonTriviallyDummy dummy{};
boost::container::small_vector<std::pair<Block*, Value>, 2> phi_args;
std::array<Value, 5> args;
boost::container::string string_literal;
};
};
static_assert(sizeof(Inst) <= 128, "Inst size unintentionally increased");