mirror of
https://github.com/sal063/AC6_recomp
synced 2026-08-30 17:49:29 -04:00
Removed a whole lot of Dead legacy code. Add a performence that is enabled by Default.
This commit is contained in:
@@ -1,359 +1,15 @@
|
||||
#include "ac6_native_graphics_overlay.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <rex/graphics/pipeline/texture/info.h>
|
||||
#include <rex/graphics/xenos.h>
|
||||
#include <rex/memory.h>
|
||||
#include <rex/cvar.h>
|
||||
|
||||
#include "ac6_native_graphics.h"
|
||||
|
||||
REXCVAR_DECLARE(bool, ac6_performance_mode);
|
||||
|
||||
extern void ApplyAc6PerformanceModeOverridesPublic();
|
||||
|
||||
namespace ac6::graphics {
|
||||
namespace {
|
||||
|
||||
struct DecodedTextureFetch {
|
||||
bool valid = false;
|
||||
uint32_t header_offset = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t depth = 0;
|
||||
uint32_t base_address = 0;
|
||||
const char* format_name = nullptr;
|
||||
rex::graphics::xenos::DataDimension dimension =
|
||||
rex::graphics::xenos::DataDimension::k2DOrStacked;
|
||||
bool tiled = false;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
struct DecodedSampleSet {
|
||||
uint32_t count = 0;
|
||||
std::array<DecodedTextureFetch, N> entries{};
|
||||
};
|
||||
|
||||
bool IsReadableGuestRange(rex::memory::Memory* memory, uint32_t guest_ptr, uint32_t size) {
|
||||
if (memory == nullptr || guest_ptr == 0 || size == 0) {
|
||||
return false;
|
||||
}
|
||||
const uint32_t guest_end = guest_ptr + size - 1;
|
||||
if (guest_end < guest_ptr) {
|
||||
return false;
|
||||
}
|
||||
auto* start_heap = memory->LookupHeap(guest_ptr);
|
||||
if (start_heap == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto* end_heap = memory->LookupHeap(guest_end);
|
||||
if (end_heap != start_heap) {
|
||||
return false;
|
||||
}
|
||||
const auto access = start_heap->QueryRangeAccess(guest_ptr, guest_end);
|
||||
return access == rex::memory::PageAccess::kReadOnly ||
|
||||
access == rex::memory::PageAccess::kReadWrite ||
|
||||
access == rex::memory::PageAccess::kExecuteReadOnly ||
|
||||
access == rex::memory::PageAccess::kExecuteReadWrite;
|
||||
}
|
||||
|
||||
bool LoadTextureFetchAt(rex::memory::Memory* memory, uint32_t guest_ptr,
|
||||
rex::graphics::xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
if (!IsReadableGuestRange(memory, guest_ptr, sizeof(fetch))) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t* fetch_base = memory->TranslateVirtual<const uint8_t*>(guest_ptr);
|
||||
if (fetch_base == nullptr) {
|
||||
return false;
|
||||
}
|
||||
fetch.dword_0 = rex::memory::load_and_swap<uint32_t>(fetch_base + 0);
|
||||
fetch.dword_1 = rex::memory::load_and_swap<uint32_t>(fetch_base + 4);
|
||||
fetch.dword_2 = rex::memory::load_and_swap<uint32_t>(fetch_base + 8);
|
||||
fetch.dword_3 = rex::memory::load_and_swap<uint32_t>(fetch_base + 12);
|
||||
fetch.dword_4 = rex::memory::load_and_swap<uint32_t>(fetch_base + 16);
|
||||
fetch.dword_5 = rex::memory::load_and_swap<uint32_t>(fetch_base + 20);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsPlausibleTextureFetchHeader(const rex::graphics::xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
using rex::graphics::xenos::DataDimension;
|
||||
|
||||
if (static_cast<uint32_t>(fetch.format) >= 64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (fetch.dimension) {
|
||||
case DataDimension::k1D:
|
||||
case DataDimension::k3D:
|
||||
return !fetch.stacked;
|
||||
case DataDimension::k2DOrStacked:
|
||||
return true;
|
||||
case DataDimension::kCube:
|
||||
return !fetch.stacked && fetch.size_2d.stack_depth == 5;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPlausibleTextureInfo(const rex::graphics::TextureInfo& info) {
|
||||
const uint32_t width = info.width + 1;
|
||||
const uint32_t height = info.height + 1;
|
||||
const uint32_t depth = info.depth + 1;
|
||||
return width >= 1 && width <= 8192 && height >= 1 && height <= 8192 && depth >= 1 &&
|
||||
depth <= 2048 && info.memory.base_address != 0 && info.format_info() != nullptr;
|
||||
}
|
||||
|
||||
bool DecodeTextureFetch(uint32_t guest_ptr, DecodedTextureFetch& out) {
|
||||
rex::memory::Memory* memory = GetCapturedMemory();
|
||||
if (!IsReadableGuestRange(memory, guest_ptr, sizeof(rex::graphics::xenos::xe_gpu_texture_fetch_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr uint32_t kProbeLimit = 0x80;
|
||||
for (uint32_t offset = 0; offset + sizeof(rex::graphics::xenos::xe_gpu_texture_fetch_t) <=
|
||||
kProbeLimit;
|
||||
offset += 4) {
|
||||
if (!IsReadableGuestRange(memory, guest_ptr + offset,
|
||||
sizeof(rex::graphics::xenos::xe_gpu_texture_fetch_t))) {
|
||||
continue;
|
||||
}
|
||||
rex::graphics::xenos::xe_gpu_texture_fetch_t fetch{};
|
||||
if (!LoadTextureFetchAt(memory, guest_ptr + offset, fetch)) {
|
||||
continue;
|
||||
}
|
||||
if (fetch.type != rex::graphics::xenos::FetchConstantType::kTexture) {
|
||||
continue;
|
||||
}
|
||||
if (!IsPlausibleTextureFetchHeader(fetch)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rex::graphics::TextureInfo texture_info;
|
||||
if (!rex::graphics::TextureInfo::Prepare(fetch, &texture_info) ||
|
||||
!IsPlausibleTextureInfo(texture_info)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out.valid = true;
|
||||
out.header_offset = offset;
|
||||
out.dimension = texture_info.dimension;
|
||||
out.tiled = texture_info.is_tiled;
|
||||
out.width = texture_info.width + 1;
|
||||
out.height = texture_info.height + 1;
|
||||
out.depth = texture_info.depth + 1;
|
||||
out.base_address = texture_info.memory.base_address;
|
||||
out.format_name = texture_info.format_info()->name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string FormatDecodedTextureObject(uint32_t guest_ptr) {
|
||||
if (guest_ptr == 0) {
|
||||
return "none";
|
||||
}
|
||||
DecodedTextureFetch decoded;
|
||||
if (!DecodeTextureFetch(guest_ptr, decoded) || !decoded.valid) {
|
||||
char buffer[32];
|
||||
std::snprintf(buffer, sizeof(buffer), "%08X", guest_ptr);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
const char* tiled_tag = decoded.tiled ? "t" : "l";
|
||||
if (decoded.dimension == rex::graphics::xenos::DataDimension::k3D || decoded.depth > 1) {
|
||||
std::snprintf(buffer, sizeof(buffer), "%08X+%02X[%ux%ux%u %s @%08X %s]", guest_ptr,
|
||||
decoded.header_offset, decoded.width, decoded.height, decoded.depth, tiled_tag,
|
||||
decoded.base_address, decoded.format_name ? decoded.format_name : "?");
|
||||
} else {
|
||||
std::snprintf(buffer, sizeof(buffer), "%08X+%02X[%ux%u %s @%08X %s]", guest_ptr,
|
||||
decoded.header_offset, decoded.width, decoded.height, tiled_tag,
|
||||
decoded.base_address, decoded.format_name ? decoded.format_name : "?");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <typename Sample>
|
||||
DecodedSampleSet<4> DecodeSampleSet(const Sample& sample) {
|
||||
DecodedSampleSet<4> decoded_set;
|
||||
const uint32_t shown =
|
||||
std::min<uint32_t>(sample.count, static_cast<uint32_t>(sample.values.size()));
|
||||
for (uint32_t i = 0; i < shown; ++i) {
|
||||
DecodedTextureFetch decoded;
|
||||
if (!DecodeTextureFetch(sample.values[i], decoded) || !decoded.valid) {
|
||||
continue;
|
||||
}
|
||||
decoded_set.entries[decoded_set.count++] = decoded;
|
||||
}
|
||||
return decoded_set;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
bool SampleUsesBaseAddress(const DecodedSampleSet<N>& sample_set, uint32_t base_address) {
|
||||
if (base_address == 0) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < sample_set.count; ++i) {
|
||||
if (sample_set.entries[i].base_address == base_address) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string FormatResolveArgCandidates(
|
||||
const NativeGraphicsRuntimeStatus::ResolveDiagnosticsEntry& resolve) {
|
||||
std::string formatted;
|
||||
for (uint32_t i = 0; i < resolve.args.size(); ++i) {
|
||||
if (resolve.args[i] == 0) {
|
||||
continue;
|
||||
}
|
||||
DecodedTextureFetch decoded;
|
||||
if (!DecodeTextureFetch(resolve.args[i], decoded) || !decoded.valid) {
|
||||
continue;
|
||||
}
|
||||
char buffer[96];
|
||||
std::snprintf(buffer, sizeof(buffer), "r%u=%08X+%02X[%ux%u @%08X %s]", 4u + i,
|
||||
resolve.args[i], decoded.header_offset, decoded.width, decoded.height,
|
||||
decoded.base_address, decoded.format_name ? decoded.format_name : "?");
|
||||
if (!formatted.empty()) {
|
||||
formatted.append(", ");
|
||||
}
|
||||
formatted.append(buffer);
|
||||
}
|
||||
return formatted.empty() ? "none" : formatted;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
std::string FormatPassSources(const DecodedSampleSet<N>& first_fetch,
|
||||
const DecodedSampleSet<N>& last_fetch,
|
||||
const NativeGraphicsRuntimeStatus& status, uint32_t self_index) {
|
||||
std::string formatted;
|
||||
for (uint32_t other_index = 0; other_index < status.pass_diagnostics_count; ++other_index) {
|
||||
if (other_index == self_index) {
|
||||
continue;
|
||||
}
|
||||
const auto& other_pass = status.pass_diagnostics[other_index];
|
||||
if (!other_pass.valid || other_pass.render_target_0 == 0) {
|
||||
continue;
|
||||
}
|
||||
DecodedTextureFetch decoded_rt0;
|
||||
if (!DecodeTextureFetch(other_pass.render_target_0, decoded_rt0) || !decoded_rt0.valid ||
|
||||
decoded_rt0.base_address == 0) {
|
||||
continue;
|
||||
}
|
||||
if (!SampleUsesBaseAddress(first_fetch, decoded_rt0.base_address) &&
|
||||
!SampleUsesBaseAddress(last_fetch, decoded_rt0.base_address)) {
|
||||
continue;
|
||||
}
|
||||
char buffer[48];
|
||||
std::snprintf(buffer, sizeof(buffer), "#%u(rt0 #%u %ux%u @%08X)", other_index,
|
||||
other_pass.pass_index, decoded_rt0.width, decoded_rt0.height,
|
||||
decoded_rt0.base_address);
|
||||
if (!formatted.empty()) {
|
||||
formatted.append(", ");
|
||||
}
|
||||
formatted.append(buffer);
|
||||
}
|
||||
return formatted.empty() ? "none" : formatted;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
std::string FormatResolveSources(const DecodedSampleSet<N>& first_fetch,
|
||||
const DecodedSampleSet<N>& last_fetch,
|
||||
const NativeGraphicsRuntimeStatus& status) {
|
||||
std::string formatted;
|
||||
for (uint32_t resolve_index = 0; resolve_index < status.resolve_diagnostics_count;
|
||||
++resolve_index) {
|
||||
const auto& resolve = status.resolve_diagnostics[resolve_index];
|
||||
if (!resolve.valid) {
|
||||
continue;
|
||||
}
|
||||
for (uint32_t arg_index = 0; arg_index < resolve.args.size(); ++arg_index) {
|
||||
if (resolve.args[arg_index] == 0) {
|
||||
continue;
|
||||
}
|
||||
DecodedTextureFetch decoded;
|
||||
if (!DecodeTextureFetch(resolve.args[arg_index], decoded) || !decoded.valid ||
|
||||
decoded.base_address == 0) {
|
||||
continue;
|
||||
}
|
||||
if (!SampleUsesBaseAddress(first_fetch, decoded.base_address) &&
|
||||
!SampleUsesBaseAddress(last_fetch, decoded.base_address)) {
|
||||
continue;
|
||||
}
|
||||
char buffer[72];
|
||||
std::snprintf(buffer, sizeof(buffer), "#%u:r%u[%ux%u @%08X]", resolve_index, 4u + arg_index,
|
||||
decoded.width, decoded.height, decoded.base_address);
|
||||
if (!formatted.empty()) {
|
||||
formatted.append(", ");
|
||||
}
|
||||
formatted.append(buffer);
|
||||
}
|
||||
}
|
||||
return formatted.empty() ? "none" : formatted;
|
||||
}
|
||||
|
||||
template <typename Sample>
|
||||
std::string FormatBoundResourceSample(const Sample& sample) {
|
||||
if (sample.count == 0) {
|
||||
return "none";
|
||||
}
|
||||
std::string formatted;
|
||||
const uint32_t shown = std::min<uint32_t>(sample.count, static_cast<uint32_t>(sample.values.size()));
|
||||
for (uint32_t i = 0; i < shown; ++i) {
|
||||
if (!formatted.empty()) {
|
||||
formatted.append(", ");
|
||||
}
|
||||
char buffer[32];
|
||||
std::snprintf(buffer, sizeof(buffer), "%u:%08X", sample.slots[i], sample.values[i]);
|
||||
formatted.append(buffer);
|
||||
}
|
||||
if (sample.count > shown) {
|
||||
formatted.append(", ...");
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
template <typename Sample>
|
||||
std::string FormatFetchConstantSample(const Sample& sample) {
|
||||
if (sample.count == 0) {
|
||||
return "none";
|
||||
}
|
||||
std::string formatted;
|
||||
const uint32_t shown = std::min<uint32_t>(sample.count, static_cast<uint32_t>(sample.values.size()));
|
||||
for (uint32_t i = 0; i < shown; ++i) {
|
||||
if (!formatted.empty()) {
|
||||
formatted.append(", ");
|
||||
}
|
||||
char buffer[96];
|
||||
DecodedTextureFetch decoded;
|
||||
if (DecodeTextureFetch(sample.values[i], decoded) && decoded.valid) {
|
||||
const char* tiled_tag = decoded.tiled ? "t" : "l";
|
||||
if (decoded.dimension == rex::graphics::xenos::DataDimension::k3D ||
|
||||
decoded.depth > 1) {
|
||||
std::snprintf(buffer, sizeof(buffer),
|
||||
"%u:%08X+%02X[%ux%ux%u %s @%08X %s]", sample.slots[i], sample.values[i],
|
||||
decoded.header_offset, decoded.width, decoded.height, decoded.depth,
|
||||
tiled_tag, decoded.base_address,
|
||||
decoded.format_name ? decoded.format_name : "?");
|
||||
} else {
|
||||
std::snprintf(buffer, sizeof(buffer), "%u:%08X+%02X[%ux%u %s @%08X %s]",
|
||||
sample.slots[i], sample.values[i], decoded.header_offset, decoded.width,
|
||||
decoded.height, tiled_tag, decoded.base_address,
|
||||
decoded.format_name ? decoded.format_name : "?");
|
||||
}
|
||||
} else {
|
||||
std::snprintf(buffer, sizeof(buffer), "%u:%08X", sample.slots[i], sample.values[i]);
|
||||
}
|
||||
formatted.append(buffer);
|
||||
}
|
||||
if (sample.count > shown) {
|
||||
formatted.append(", ...");
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeGraphicsStatusDialog::NativeGraphicsStatusDialog(rex::ui::ImGuiDrawer* imgui_drawer)
|
||||
: ImGuiDialog(imgui_drawer) {}
|
||||
@@ -362,7 +18,10 @@ NativeGraphicsStatusDialog::~NativeGraphicsStatusDialog() = default;
|
||||
|
||||
void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
|
||||
(void)io;
|
||||
if (!visible_) {
|
||||
|
||||
ApplyAc6PerformanceModeOverridesPublic();
|
||||
|
||||
if (REXCVAR_GET(ac6_performance_mode) || !visible_) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -387,11 +46,8 @@ void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
|
||||
ImGui::Text("scaled tex offsets / direct host resolve: %s / %s",
|
||||
status.draw_resolution_scaled_texture_offsets ? "on" : "off",
|
||||
status.direct_host_resolve ? "on" : "off");
|
||||
ImGui::Text("experimental replay present override: %s",
|
||||
status.experimental_replay_present ? "enabled" : "disabled");
|
||||
ImGui::Text("analysis frames / replay frames: %llu / %llu",
|
||||
static_cast<unsigned long long>(status.analysis_frames_observed),
|
||||
static_cast<unsigned long long>(status.replay_frames_built));
|
||||
ImGui::Text("analysis frames: %llu",
|
||||
static_cast<unsigned long long>(status.analysis_frames_observed));
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("capture frame: %llu",
|
||||
@@ -409,109 +65,6 @@ void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
|
||||
ImGui::Text("frame-end viewport: %ux%u",
|
||||
status.capture_summary.frame_end_viewport_width,
|
||||
status.capture_summary.frame_end_viewport_height);
|
||||
ImGui::Text("frontend passes scene/post/ui: %u / %u / %u / %u",
|
||||
status.frontend_summary.pass_count, status.frontend_summary.scene_pass_count,
|
||||
status.frontend_summary.post_process_pass_count,
|
||||
status.frontend_summary.ui_pass_count);
|
||||
if (status.frame_plan.present_stage.valid) {
|
||||
ImGui::Text(
|
||||
"present stage: #%u %s vp=%ux%u rt0=%08X depth=%08X draws/resolves=%u/%u",
|
||||
status.frame_plan.present_stage.pass_index,
|
||||
ac6::renderer::ToString(status.frame_plan.present_stage.kind),
|
||||
status.frame_plan.present_stage.viewport_width,
|
||||
status.frame_plan.present_stage.viewport_height,
|
||||
status.frame_plan.present_stage.render_target_0,
|
||||
status.frame_plan.present_stage.depth_stencil,
|
||||
status.frame_plan.present_stage.draw_count,
|
||||
status.frame_plan.present_stage.resolve_count);
|
||||
}
|
||||
if (status.frame_plan.scene_stage.valid) {
|
||||
ImGui::Text(
|
||||
"scene stage: #%u %s vp=%ux%u rt0=%08X depth=%08X draws/resolves=%u/%u",
|
||||
status.frame_plan.scene_stage.pass_index,
|
||||
ac6::renderer::ToString(status.frame_plan.scene_stage.kind),
|
||||
status.frame_plan.scene_stage.viewport_width,
|
||||
status.frame_plan.scene_stage.viewport_height,
|
||||
status.frame_plan.scene_stage.render_target_0,
|
||||
status.frame_plan.scene_stage.depth_stencil,
|
||||
status.frame_plan.scene_stage.draw_count,
|
||||
status.frame_plan.scene_stage.resolve_count);
|
||||
}
|
||||
if (status.frame_plan.post_process_stage.valid) {
|
||||
ImGui::Text(
|
||||
"post stage: #%u %s vp=%ux%u rt0=%08X depth=%08X draws/resolves=%u/%u",
|
||||
status.frame_plan.post_process_stage.pass_index,
|
||||
ac6::renderer::ToString(status.frame_plan.post_process_stage.kind),
|
||||
status.frame_plan.post_process_stage.viewport_width,
|
||||
status.frame_plan.post_process_stage.viewport_height,
|
||||
status.frame_plan.post_process_stage.render_target_0,
|
||||
status.frame_plan.post_process_stage.depth_stencil,
|
||||
status.frame_plan.post_process_stage.draw_count,
|
||||
status.frame_plan.post_process_stage.resolve_count);
|
||||
}
|
||||
if (status.frame_plan.ui_stage.valid) {
|
||||
ImGui::Text(
|
||||
"ui stage: #%u %s vp=%ux%u rt0=%08X depth=%08X draws/resolves=%u/%u",
|
||||
status.frame_plan.ui_stage.pass_index,
|
||||
ac6::renderer::ToString(status.frame_plan.ui_stage.kind),
|
||||
status.frame_plan.ui_stage.viewport_width,
|
||||
status.frame_plan.ui_stage.viewport_height,
|
||||
status.frame_plan.ui_stage.render_target_0,
|
||||
status.frame_plan.ui_stage.depth_stencil,
|
||||
status.frame_plan.ui_stage.draw_count,
|
||||
status.frame_plan.ui_stage.resolve_count);
|
||||
}
|
||||
for (uint32_t i = 0; i < status.pass_diagnostics_count; ++i) {
|
||||
const auto& pass = status.pass_diagnostics[i];
|
||||
if (!pass.valid) {
|
||||
continue;
|
||||
}
|
||||
ImGui::Text(
|
||||
"pass[%u]: #%u %s score=%u vp=%ux%u+%u+%u rt0=%08X depth=%08X d/c/r=%u/%u/%u tex/str/samp/fetch=%u/%u/%u/%u gpr=%u %s%s",
|
||||
i, pass.pass_index, ac6::renderer::ToString(pass.kind), pass.score,
|
||||
pass.viewport_width, pass.viewport_height, pass.viewport_x, pass.viewport_y,
|
||||
pass.render_target_0, pass.depth_stencil, pass.draw_count, pass.clear_count,
|
||||
pass.resolve_count, pass.max_texture_count, pass.max_stream_count,
|
||||
pass.max_sampler_count, pass.max_fetch_constant_count, pass.max_shader_gpr_alloc,
|
||||
pass.selected_for_present ? "present " : "",
|
||||
pass.matches_frame_end_viewport ? "frame_end" : "");
|
||||
ImGui::Text(
|
||||
" sig=%016llX tfetch=%016llX->%016llX bind=%016llX->%016llX",
|
||||
static_cast<unsigned long long>(pass.pass_signature),
|
||||
static_cast<unsigned long long>(pass.first_texture_fetch_layout_signature),
|
||||
static_cast<unsigned long long>(pass.last_texture_fetch_layout_signature),
|
||||
static_cast<unsigned long long>(pass.first_resource_binding_signature),
|
||||
static_cast<unsigned long long>(pass.last_resource_binding_signature));
|
||||
const std::string first_textures = FormatBoundResourceSample(pass.first_textures);
|
||||
const std::string last_textures = FormatBoundResourceSample(pass.last_textures);
|
||||
const std::string first_fetch = FormatFetchConstantSample(pass.first_fetch_constants);
|
||||
const std::string last_fetch = FormatFetchConstantSample(pass.last_fetch_constants);
|
||||
const std::string rt0_object = FormatDecodedTextureObject(pass.render_target_0);
|
||||
const std::string depth_object = FormatDecodedTextureObject(pass.depth_stencil);
|
||||
const DecodedSampleSet<4> decoded_first_fetch = DecodeSampleSet(pass.first_fetch_constants);
|
||||
const DecodedSampleSet<4> decoded_last_fetch = DecodeSampleSet(pass.last_fetch_constants);
|
||||
const std::string source_passes =
|
||||
FormatPassSources(decoded_first_fetch, decoded_last_fetch, status, i);
|
||||
const std::string resolve_sources =
|
||||
FormatResolveSources(decoded_first_fetch, decoded_last_fetch, status);
|
||||
ImGui::Text(" tex %s -> %s", first_textures.c_str(), last_textures.c_str());
|
||||
ImGui::Text(" fet %s -> %s", first_fetch.c_str(), last_fetch.c_str());
|
||||
ImGui::Text(" rt0 %s depth %s", rt0_object.c_str(), depth_object.c_str());
|
||||
ImGui::Text(" src %s", source_passes.c_str());
|
||||
ImGui::Text(" rslv %s", resolve_sources.c_str());
|
||||
}
|
||||
for (uint32_t i = 0; i < status.resolve_diagnostics_count; ++i) {
|
||||
const auto& resolve = status.resolve_diagnostics[i];
|
||||
if (!resolve.valid) {
|
||||
continue;
|
||||
}
|
||||
ImGui::Text(
|
||||
"resolve[%u]: seq=%u vp=%ux%u rt0=%08X depth=%08X f1=%.3f", i, resolve.sequence,
|
||||
resolve.viewport_width, resolve.viewport_height, resolve.render_target_0,
|
||||
resolve.depth_stencil, resolve.depth_or_scale);
|
||||
const std::string candidates = FormatResolveArgCandidates(resolve);
|
||||
ImGui::Text(" %s", candidates.c_str());
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("swap source: %s", ac6::backend::ToString(diagnostics.swap_source));
|
||||
@@ -560,8 +113,6 @@ void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
|
||||
: diagnostics.latest_signature_tags.c_str());
|
||||
const bool draw_scale_is_native =
|
||||
status.draw_resolution_scale_x <= 1 && status.draw_resolution_scale_y <= 1;
|
||||
const bool draw_scale_is_scaled =
|
||||
status.draw_resolution_scale_x > 1 || status.draw_resolution_scale_y > 1;
|
||||
const bool likely_point_filtered =
|
||||
diagnostics.latest_signature.point_min_sampler_count != 0 ||
|
||||
diagnostics.latest_signature.point_mip_sampler_count != 0;
|
||||
@@ -613,26 +164,6 @@ void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
|
||||
diagnostics.audio_callback_dispatch_count,
|
||||
diagnostics.audio_callback_throttle_count);
|
||||
|
||||
if (status.mode == GraphicsRuntimeMode::kLegacyReplayExperimental) {
|
||||
ImGui::Separator();
|
||||
ImGui::TextUnformatted("legacy replay diagnostics (experimental):");
|
||||
ImGui::Text("initialized: %s", status.initialized ? "true" : "false");
|
||||
ImGui::Text("init failures seen: %s", status.had_init_failure ? "true" : "false");
|
||||
ImGui::Text("replay backend: %s",
|
||||
ac6::renderer::ToString(status.active_backend).data());
|
||||
ImGui::Text("replay feature level: %s",
|
||||
ac6::renderer::ToString(status.feature_level).data());
|
||||
ImGui::Text("frontend / replay / execution commands: %u / %u / %u",
|
||||
status.frontend_summary.total_command_count,
|
||||
status.replay_summary.command_count,
|
||||
status.execution_summary.command_count);
|
||||
ImGui::Text("backend draw attempts / success: %u / %u",
|
||||
status.backend_executor_status.draw_attempt_count,
|
||||
status.backend_executor_status.draw_success_count);
|
||||
ImGui::Text("planned output: %ux%u", status.frame_plan.output_width,
|
||||
status.frame_plan.output_height);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user