DebugPrintf in shaders (#1252)

* Add shader debug print opcode that uses NonSemantic DebugPrintf extension

* small correction for flags in Inst

* Fix IR Debug Print. Add StringLiteral op

* add missing microinstruction changes for debugprint

* cleanup. delete vaarg stuff. Smuggle format string in Info and flags

* more cleanup

* more

* (dont merge??) update sirit submodule

* fix num args 4 -> 5

* add notes about DebugPrint IR op

* use NumArgsOf again

* copyright

* update sirit submodule

* fix clangformat

* add new Value variant for string literal. Use arg0 for fmt string

* remove string pool changes

* Update src/shader_recompiler/ir/value.cpp

Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com>

---------

Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com>
This commit is contained in:
baggins183 2024-10-06 12:34:40 -07:00 committed by GitHub
parent 310814ac71
commit 3c0255b953
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 99 additions and 6 deletions

View file

@ -1,10 +1,15 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <array>
#include <bit>
#include <source_location>
#include <boost/container/small_vector.hpp>
#include "common/assert.h"
#include "shader_recompiler/exception.h"
#include "shader_recompiler/ir/debug_print.h"
#include "shader_recompiler/ir/ir_emitter.h"
#include "shader_recompiler/ir/opcodes.h"
#include "shader_recompiler/ir/value.h"
namespace Shader::IR {
@ -1553,6 +1558,38 @@ void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value
Inst(Opcode::ImageWrite, Flags{info}, handle, coords, color);
}
// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction
// Renderdoc will hook in its own implementation of the SPIRV instruction
// Renderdoc accepts format specifiers, e.g. %u, listed here:
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md
//
// fmt must be a string literal (pointer is shallow copied into a Value)
// Example usage:
// ir.DebugPrint("invocation xyz: (%u, %u, %u)",
// {ir.GetVectorReg(IR::VectorReg::V0),
// ir.GetVectorReg(IR::VectorReg::V1),
// ir.GetVectorReg(IR::VectorReg::V2)});
void IREmitter::DebugPrint(const char* fmt, boost::container::small_vector<Value, 5> format_args) {
std::array<Value, DEBUGPRINT_NUM_FORMAT_ARGS> args;
ASSERT_MSG(format_args.size() < DEBUGPRINT_NUM_FORMAT_ARGS,
"DebugPrint only supports up to {} format args", DEBUGPRINT_NUM_FORMAT_ARGS);
for (int i = 0; i < format_args.size(); i++) {
args[i] = format_args[i];
}
for (int i = format_args.size(); i < DEBUGPRINT_NUM_FORMAT_ARGS; i++) {
args[i] = Inst(Opcode::Void);
}
IR::Value fmt_val{fmt};
DebugPrintFlags flags;
flags.num_args.Assign(format_args.size());
Inst(Opcode::DebugPrint, Flags{flags}, fmt_val, args[0], args[1], args[2], args[3]);
}
void IREmitter::EmitVertex() {
Inst(Opcode::EmitVertex);
}