mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
feat(agc): trace shader addresses for each draw
This commit is contained in:
1 parent
153d5d469d
commit
fffa0f3865
6 files changed
+148
No files matched your search
@@ -145,6 +145,7 @@ set(agcDriverSources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Dispatch/IndirectDispatch.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Dispatch/VariantValidation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Draw/Draw.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Draw/DrawProgramTrace.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Draw/DrawCache.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Draw/DrawCacheStatistics.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Execution/src/Driver/Draw/DrawCapture.cpp
|
||||
@@ -290,6 +291,21 @@ if(APS5_ENABLE_TRACY)
|
||||
target_link_libraries(libSceAgcDriver PUBLIC TracyClient)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(agc_driver_draw_program_trace_tests
|
||||
tests/DrawProgramTrace.cpp
|
||||
Execution/src/Driver/Draw/DrawProgramTrace.cpp
|
||||
)
|
||||
target_include_directories(agc_driver_draw_program_trace_tests PRIVATE
|
||||
${LIBS_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/core/shader/recompiler
|
||||
)
|
||||
set_target_properties(agc_driver_draw_program_trace_tests PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(agc_driver_draw_program_trace_tests)
|
||||
add_test(NAME agc_driver_draw_program_trace COMMAND agc_driver_draw_program_trace_tests)
|
||||
set_tests_properties(agc_driver_draw_program_trace PROPERTIES TIMEOUT 20)
|
||||
endif()
|
||||
|
||||
set_target_properties(libSceAgcDriver PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(libSceAgcDriver)
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_DRIVER_DRAW_DRAWPROGRAMTRACE_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_DRIVER_DRAW_DRAWPROGRAMTRACE_HPP
|
||||
|
||||
#include "Recompiler.hpp"
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
struct DrawProgramTraceEntry {
|
||||
ShaderRecompiler::ShaderStage stage;
|
||||
ShaderRecompiler::ProgramRole role;
|
||||
std::uint64_t codeAddress;
|
||||
std::uint64_t entryAddress;
|
||||
};
|
||||
|
||||
std::string FormatDrawProgramTrace(std::uint64_t submission, std::uint32_t queue, std::span<const DrawProgramTraceEntry> programs);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Diagnostics.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawProgramTrace.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/GuestMemory.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/Pm4.hpp"
|
||||
#include "Optimization/ResourceProgram.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
@@ -147,6 +149,16 @@ DrawVerdict Driver::draw(QueueState& queue, std::span<const std::uint32_t> packe
|
||||
if (!drawParameters.indirect) setMeshIndexBuffer(drawParameters);
|
||||
else if (graphics.stages.mesh) setMeshIndexBuffer(Pm4::DrawParameters{drawParameters.indexAddress, std::max(drawParameters.indexCount, 1u), drawParameters.indexSize, 1, 0, drawParameters.indexed});
|
||||
const std::vector<Role>& roles = decode->roles;
|
||||
static const bool tracePrograms = std::getenv("APS5_TRACE_DRAW_PROGRAMS") != nullptr;
|
||||
if (tracePrograms) {
|
||||
std::vector<DrawProgramTraceEntry> identities;
|
||||
identities.reserve(programs.size());
|
||||
for (std::size_t i = 0; i < programs.size(); ++i) {
|
||||
identities.push_back({programs[i].binary.stage, roles[i], programs[i].snapshot->codeAddress, programs[i].binary.codeAddress});
|
||||
}
|
||||
const auto line = FormatDrawProgramTrace(submission.serial, submission.queue, identities);
|
||||
std::fprintf(stderr, "%s\n", line.c_str());
|
||||
}
|
||||
phaseTiming.Phase(DrawRowDecode);
|
||||
|
||||
const auto locate = [&](std::uint32_t location) -> std::optional<std::pair<std::size_t, std::size_t>> {
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawProgramTrace.hpp"
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
namespace {
|
||||
|
||||
const char* StageName(ShaderRecompiler::ShaderStage stage) {
|
||||
using ShaderRecompiler::ShaderStage;
|
||||
switch (stage) {
|
||||
case ShaderStage::Compute: return "compute";
|
||||
case ShaderStage::Vertex: return "vertex";
|
||||
case ShaderStage::TessellationControl: return "tess-control";
|
||||
case ShaderStage::TessellationEvaluation: return "tess-evaluation";
|
||||
case ShaderStage::Geometry: return "geometry";
|
||||
case ShaderStage::Fragment: return "fragment";
|
||||
case ShaderStage::Local: return "local";
|
||||
case ShaderStage::Mesh: return "mesh";
|
||||
}
|
||||
throw std::invalid_argument("unknown shader stage in draw trace");
|
||||
}
|
||||
|
||||
const char* RoleName(ShaderRecompiler::ProgramRole role) {
|
||||
using ShaderRecompiler::ProgramRole;
|
||||
switch (role) {
|
||||
case ProgramRole::Main: return "main";
|
||||
case ProgramRole::GeometryBack: return "geometry-back";
|
||||
case ProgramRole::Local: return "local";
|
||||
case ProgramRole::Hull: return "hull";
|
||||
case ProgramRole::Domain: return "domain";
|
||||
case ProgramRole::Fragment: return "fragment";
|
||||
}
|
||||
throw std::invalid_argument("unknown program role in draw trace");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::string FormatDrawProgramTrace(std::uint64_t submission, std::uint32_t queue, std::span<const DrawProgramTraceEntry> programs) {
|
||||
char prefix[128];
|
||||
const auto size = std::snprintf(prefix, sizeof(prefix), "[draw-programs] submission=%llu queue=0x%x count=%zu",
|
||||
static_cast<unsigned long long>(submission), queue, programs.size());
|
||||
if (size < 0 || static_cast<std::size_t>(size) >= sizeof(prefix)) throw std::runtime_error("draw program trace prefix overflow");
|
||||
std::string result(prefix, static_cast<std::size_t>(size));
|
||||
char item[160];
|
||||
for (const auto& program : programs) {
|
||||
const auto itemSize = std::snprintf(item, sizeof(item), " %s/%s=0x%llx(entry=0x%llx)",
|
||||
StageName(program.stage), RoleName(program.role),
|
||||
static_cast<unsigned long long>(program.codeAddress), static_cast<unsigned long long>(program.entryAddress));
|
||||
if (itemSize < 0 || static_cast<std::size_t>(itemSize) >= sizeof(item)) throw std::runtime_error("draw program trace entry overflow");
|
||||
result.append(item, static_cast<std::size_t>(itemSize));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawProgramTrace.hpp"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
void Check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
void EmptyTrace() {
|
||||
const auto trace = AgcDriver::DriverDetail::FormatDrawProgramTrace(12, 3, {});
|
||||
Check(trace == "[draw-programs] submission=12 queue=0x3 count=0", "empty draw trace changed shape");
|
||||
}
|
||||
|
||||
void ProgramAddresses() {
|
||||
using namespace AgcDriver::DriverDetail;
|
||||
using ShaderRecompiler::ProgramRole;
|
||||
using ShaderRecompiler::ShaderStage;
|
||||
const DrawProgramTraceEntry entries[]{
|
||||
{ShaderStage::Vertex, ProgramRole::Main, 0x100000, 0x100040},
|
||||
{ShaderStage::Fragment, ProgramRole::Fragment, 0x200000, 0x200020},
|
||||
};
|
||||
const auto trace = FormatDrawProgramTrace(42, 0x9, entries);
|
||||
Check(trace == "[draw-programs] submission=42 queue=0x9 count=2 vertex/main=0x100000(entry=0x100040) fragment/fragment=0x200000(entry=0x200020)",
|
||||
"draw trace omitted the selected shader code or entry address");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
EmptyTrace();
|
||||
ProgramAddresses();
|
||||
} catch (const std::exception& error) {
|
||||
std::cerr << error.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -252,11 +252,13 @@ function(add_shader_recompiler target runtimeTarget)
|
||||
SampledTextureNumericClass
|
||||
SetDebugProbeActive
|
||||
ShaderCacheDirectory
|
||||
ShaderStage
|
||||
SrgbDecodeBit
|
||||
SrgbUnormFormat
|
||||
FindUserDataTail
|
||||
LinkUserDataTail
|
||||
ThreadOwned
|
||||
ProgramRole
|
||||
UnresolvableSwappcTarget
|
||||
ValidateAndOptimizeSpirv
|
||||
FindUserDataCalls
|
||||
|
||||
Reference in new issue
Block a user