mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[App] Refactor title bar display and add cpu backend
This commit is contained in:
@@ -104,6 +104,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "xenia/apu/audio_system.h"
|
||||
#include "xenia/cpu/backend/backend.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/emulator.h"
|
||||
#include "xenia/gpu/command_processor.h"
|
||||
@@ -1960,16 +1962,44 @@ void EmulatorWindow::UpdateTitle() {
|
||||
}
|
||||
}
|
||||
|
||||
// Graphics system name, if available
|
||||
std::string graphics_name;
|
||||
std::string graphics_suffix;
|
||||
auto graphics_system = emulator()->graphics_system();
|
||||
if (graphics_system) {
|
||||
auto graphics_name = graphics_system->name();
|
||||
if (!graphics_name.empty()) {
|
||||
sb.Append(" <");
|
||||
sb.Append(graphics_name);
|
||||
sb.Append(">");
|
||||
graphics_name = graphics_system->name();
|
||||
auto command_processor = graphics_system->command_processor();
|
||||
if (command_processor) {
|
||||
graphics_suffix = command_processor->GetTitleStateSuffix();
|
||||
}
|
||||
}
|
||||
std::string audio_name;
|
||||
auto audio_system = emulator()->audio_system();
|
||||
if (audio_system) {
|
||||
audio_name = audio_system->name();
|
||||
}
|
||||
std::string cpu_name;
|
||||
auto processor = emulator()->processor();
|
||||
if (processor && processor->backend()) {
|
||||
cpu_name = processor->backend()->name();
|
||||
}
|
||||
if (!graphics_name.empty() || !cpu_name.empty()) {
|
||||
sb.Append(" <");
|
||||
if (!graphics_name.empty()) {
|
||||
sb.Append(graphics_name);
|
||||
sb.Append(graphics_suffix);
|
||||
if (!audio_name.empty()) {
|
||||
sb.Append(" - ");
|
||||
sb.Append(audio_name);
|
||||
}
|
||||
}
|
||||
if (!cpu_name.empty()) {
|
||||
if (!graphics_name.empty()) {
|
||||
sb.Append(" - ");
|
||||
}
|
||||
sb.Append(cpu_name);
|
||||
}
|
||||
sb.Append(">");
|
||||
}
|
||||
|
||||
if (Clock::guest_time_scalar() != 1.0) {
|
||||
sb.AppendFormat(" (@{:.2f}x)", Clock::guest_time_scalar());
|
||||
|
||||
@@ -101,6 +101,8 @@ class A64Backend : public Backend {
|
||||
A64CodeCache* code_cache() const { return code_cache_.get(); }
|
||||
uintptr_t emitter_data() const { return emitter_data_; }
|
||||
|
||||
std::string name() const override { return "a64"; }
|
||||
|
||||
HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; }
|
||||
GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; }
|
||||
ResolveFunctionThunk resolve_function_thunk() const {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define XENIA_CPU_BACKEND_BACKEND_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/cpu/backend/machine_info.h"
|
||||
#include "xenia/cpu/thread_debug_info.h"
|
||||
@@ -50,6 +51,8 @@ class Backend {
|
||||
const MachineInfo* machine_info() const { return &machine_info_; }
|
||||
CodeCache* code_cache() const { return code_cache_; }
|
||||
|
||||
virtual std::string name() const { return "unknown"; }
|
||||
|
||||
virtual bool Initialize(Processor* processor);
|
||||
|
||||
virtual void* AllocThreadData();
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace backend {
|
||||
|
||||
class NullBackend : public Backend {
|
||||
public:
|
||||
std::string name() const override { return "null"; }
|
||||
|
||||
void CommitExecutableRange(uint32_t guest_low, uint32_t guest_high) override;
|
||||
|
||||
std::unique_ptr<Assembler> CreateAssembler() override;
|
||||
|
||||
@@ -128,6 +128,8 @@ class X64Backend : public Backend {
|
||||
X64CodeCache* code_cache() const { return code_cache_.get(); }
|
||||
uintptr_t emitter_data() const { return emitter_data_; }
|
||||
|
||||
std::string name() const override { return "x64"; }
|
||||
|
||||
// Call a generated function, saving all stack parameters.
|
||||
HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; }
|
||||
// Function that guest code can call to transition into host code.
|
||||
|
||||
@@ -144,6 +144,8 @@ class CommandProcessor {
|
||||
virtual bool Initialize();
|
||||
virtual void Shutdown();
|
||||
|
||||
virtual std::string GetTitleStateSuffix() const { return {}; }
|
||||
|
||||
void CallInThread(std::function<void()> fn);
|
||||
|
||||
virtual void ClearCaches();
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
|
||||
#include "xenia/apu/audio_system.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/cvar.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/emulator.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_shader.h"
|
||||
#include "xenia/gpu/d3d12/d3d12_zpd_query_pool.h"
|
||||
@@ -798,40 +796,36 @@ void D3D12CommandProcessor::SetPrimitiveTopology(
|
||||
}
|
||||
}
|
||||
|
||||
std::string D3D12CommandProcessor::GetWindowTitleText() const {
|
||||
std::ostringstream title;
|
||||
title << "Direct3D 12";
|
||||
if (render_target_cache_) {
|
||||
// Rasterizer-ordered views are a feature very rarely used as of 2020 and
|
||||
// that faces adoption complications (outside of Direct3D - on Vulkan - at
|
||||
// least), but crucial to Xenia - raise awareness of its usage.
|
||||
// https://github.com/KhronosGroup/Vulkan-Ecosystem/issues/27#issuecomment-455712319
|
||||
// "In Xenia's title bar "D3D12 ROV" can be seen, which was a surprise, as I
|
||||
// wasn't aware that Xenia D3D12 backend was using Raster Order Views
|
||||
// feature" - oscarbg in that issue.
|
||||
switch (render_target_cache_->GetPath()) {
|
||||
case RenderTargetCache::Path::kHostRenderTargets:
|
||||
title << " - RTV/DSV";
|
||||
break;
|
||||
case RenderTargetCache::Path::kPixelShaderInterlock:
|
||||
title << " - ROV";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint32_t draw_resolution_scale_x =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1;
|
||||
uint32_t draw_resolution_scale_y =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1;
|
||||
if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) {
|
||||
title << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y;
|
||||
}
|
||||
std::string D3D12CommandProcessor::GetTitleStateSuffix() const {
|
||||
if (!render_target_cache_) {
|
||||
return {};
|
||||
}
|
||||
auto* audio_system = kernel_state_->emulator()->audio_system();
|
||||
if (audio_system) {
|
||||
title << " - " << audio_system->name();
|
||||
std::ostringstream suffix;
|
||||
// Rasterizer-ordered views are a feature very rarely used as of 2020 and
|
||||
// that faces adoption complications (outside of Direct3D - on Vulkan - at
|
||||
// least), but crucial to Xenia - raise awareness of its usage.
|
||||
// https://github.com/KhronosGroup/Vulkan-Ecosystem/issues/27#issuecomment-455712319
|
||||
// "In Xenia's title bar "D3D12 ROV" can be seen, which was a surprise, as I
|
||||
// wasn't aware that Xenia D3D12 backend was using Raster Order Views
|
||||
// feature" - oscarbg in that issue.
|
||||
switch (render_target_cache_->GetPath()) {
|
||||
case RenderTargetCache::Path::kHostRenderTargets:
|
||||
suffix << " - RTV/DSV";
|
||||
break;
|
||||
case RenderTargetCache::Path::kPixelShaderInterlock:
|
||||
suffix << " - ROV";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return title.str();
|
||||
uint32_t draw_resolution_scale_x =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1;
|
||||
uint32_t draw_resolution_scale_y =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1;
|
||||
if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) {
|
||||
suffix << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y;
|
||||
}
|
||||
return suffix.str();
|
||||
}
|
||||
|
||||
bool D3D12CommandProcessor::SetupContext() {
|
||||
|
||||
@@ -229,8 +229,7 @@ class D3D12CommandProcessor final : public CommandProcessor {
|
||||
void SetStencilReference(uint32_t stencil_ref);
|
||||
void SetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology);
|
||||
|
||||
// Returns the text to display in the GPU backend name in the window title.
|
||||
std::string GetWindowTitleText() const;
|
||||
std::string GetTitleStateSuffix() const override;
|
||||
|
||||
protected:
|
||||
bool SetupContext() override;
|
||||
|
||||
@@ -28,14 +28,7 @@ bool D3D12GraphicsSystem::IsAvailable() {
|
||||
return xe::ui::d3d12::D3D12Provider::IsD3D12APIAvailable();
|
||||
}
|
||||
|
||||
std::string D3D12GraphicsSystem::name() const {
|
||||
auto d3d12_command_processor =
|
||||
static_cast<D3D12CommandProcessor*>(command_processor());
|
||||
if (d3d12_command_processor != nullptr) {
|
||||
return d3d12_command_processor->GetWindowTitleText();
|
||||
}
|
||||
return "Direct3D 12";
|
||||
}
|
||||
std::string D3D12GraphicsSystem::name() const { return "D3D12"; }
|
||||
|
||||
X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor,
|
||||
kernel::KernelState* kernel_state,
|
||||
|
||||
@@ -471,6 +471,22 @@ MetalCommandProcessor::MetalCommandProcessor(
|
||||
MetalGraphicsSystem* graphics_system, kernel::KernelState* kernel_state)
|
||||
: CommandProcessor(graphics_system, kernel_state) {}
|
||||
|
||||
std::string MetalCommandProcessor::GetTitleStateSuffix() const {
|
||||
if (!render_target_cache_) {
|
||||
return {};
|
||||
}
|
||||
std::ostringstream suffix;
|
||||
suffix << " - SPIRV-Cross";
|
||||
uint32_t draw_resolution_scale_x =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1;
|
||||
uint32_t draw_resolution_scale_y =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1;
|
||||
if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) {
|
||||
suffix << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y;
|
||||
}
|
||||
return suffix.str();
|
||||
}
|
||||
|
||||
MetalCommandProcessor::~MetalCommandProcessor() {
|
||||
// End any active render encoder before releasing
|
||||
// Note: Only call endEncoding if the encoder is still active
|
||||
|
||||
@@ -67,6 +67,8 @@ class MetalCommandProcessor : public CommandProcessor {
|
||||
void InvalidateGpuMemory() override;
|
||||
void ClearReadbackBuffers() override;
|
||||
|
||||
std::string GetTitleStateSuffix() const override;
|
||||
|
||||
// Track memory regions written by IssueCopy (resolve) so trace playback
|
||||
// can skip overwriting them with stale data from the trace file.
|
||||
void MarkResolvedMemory(uint32_t base_ptr, uint32_t length);
|
||||
|
||||
@@ -26,7 +26,7 @@ bool MetalGraphicsSystem::IsAvailable() {
|
||||
return xe::ui::metal::MetalProvider::IsMetalAPIAvailable();
|
||||
}
|
||||
|
||||
std::string MetalGraphicsSystem::name() const { return "MetalGraphicsSystem"; }
|
||||
std::string MetalGraphicsSystem::name() const { return "Metal"; }
|
||||
|
||||
X_STATUS MetalGraphicsSystem::Setup(cpu::Processor* processor,
|
||||
kernel::KernelState* kernel_state,
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "xenia/apu/audio_system.h"
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/emulator.h"
|
||||
#include "xenia/gpu/draw_util.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
#include "xenia/gpu/packet_disassembler.h"
|
||||
@@ -190,33 +188,29 @@ void VulkanCommandProcessor::ReturnFromWait() {
|
||||
CommandProcessor::ReturnFromWait();
|
||||
}
|
||||
|
||||
std::string VulkanCommandProcessor::GetWindowTitleText() const {
|
||||
std::ostringstream title;
|
||||
title << "Vulkan";
|
||||
if (render_target_cache_) {
|
||||
switch (render_target_cache_->GetPath()) {
|
||||
case RenderTargetCache::Path::kHostRenderTargets:
|
||||
title << " - FBO";
|
||||
break;
|
||||
case RenderTargetCache::Path::kPixelShaderInterlock:
|
||||
title << " - FSI";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
uint32_t draw_resolution_scale_x =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1;
|
||||
uint32_t draw_resolution_scale_y =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1;
|
||||
if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) {
|
||||
title << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y;
|
||||
}
|
||||
std::string VulkanCommandProcessor::GetTitleStateSuffix() const {
|
||||
if (!render_target_cache_) {
|
||||
return {};
|
||||
}
|
||||
auto* audio_system = kernel_state_->emulator()->audio_system();
|
||||
if (audio_system) {
|
||||
title << " - " << audio_system->name();
|
||||
std::ostringstream suffix;
|
||||
switch (render_target_cache_->GetPath()) {
|
||||
case RenderTargetCache::Path::kHostRenderTargets:
|
||||
suffix << " - FBO";
|
||||
break;
|
||||
case RenderTargetCache::Path::kPixelShaderInterlock:
|
||||
suffix << " - FSI";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return title.str();
|
||||
uint32_t draw_resolution_scale_x =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_x() : 1;
|
||||
uint32_t draw_resolution_scale_y =
|
||||
texture_cache_ ? texture_cache_->draw_resolution_scale_y() : 1;
|
||||
if (draw_resolution_scale_x > 1 || draw_resolution_scale_y > 1) {
|
||||
suffix << ' ' << draw_resolution_scale_x << 'x' << draw_resolution_scale_y;
|
||||
}
|
||||
return suffix.str();
|
||||
}
|
||||
|
||||
bool VulkanCommandProcessor::SetupContext() {
|
||||
|
||||
@@ -271,8 +271,7 @@ class VulkanCommandProcessor final : public CommandProcessor {
|
||||
void SetViewport(const VkViewport& viewport);
|
||||
void SetScissor(const VkRect2D& scissor);
|
||||
|
||||
// Returns the text to display in the GPU backend name in the window title.
|
||||
std::string GetWindowTitleText() const;
|
||||
std::string GetTitleStateSuffix() const override;
|
||||
|
||||
// Debug marker methods - public so subsystems can annotate their operations.
|
||||
void PushDebugMarker(const char* format, ...);
|
||||
|
||||
@@ -21,14 +21,7 @@ VulkanGraphicsSystem::VulkanGraphicsSystem() {}
|
||||
|
||||
VulkanGraphicsSystem::~VulkanGraphicsSystem() {}
|
||||
|
||||
std::string VulkanGraphicsSystem::name() const {
|
||||
auto vulkan_command_processor =
|
||||
static_cast<VulkanCommandProcessor*>(command_processor());
|
||||
if (vulkan_command_processor != nullptr) {
|
||||
return vulkan_command_processor->GetWindowTitleText();
|
||||
}
|
||||
return "Vulkan";
|
||||
}
|
||||
std::string VulkanGraphicsSystem::name() const { return "Vulkan"; }
|
||||
|
||||
X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
|
||||
kernel::KernelState* kernel_state,
|
||||
|
||||
Reference in New Issue
Block a user