Compare commits
7 Commits
73d4b7cec5
...
06d9516f2f
Author | SHA1 | Date |
---|---|---|
The-Little-Wolf | 06d9516f2f | |
The-Little-Wolf | 5de1f23228 | |
The-Little-Wolf | 4d19245c4a | |
The-Little-Wolf | 247d16ffe7 | |
Gliniak | 6ac53cb982 | |
Gliniak | 0474053931 | |
Gliniak | 85695692a7 |
|
@ -31,7 +31,6 @@
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/gpu/command_processor.h"
|
#include "xenia/gpu/command_processor.h"
|
||||||
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
#include "xenia/hid/input_system.h"
|
#include "xenia/hid/input_system.h"
|
||||||
#include "xenia/kernel/xam/profile_manager.h"
|
#include "xenia/kernel/xam/profile_manager.h"
|
||||||
|
@ -58,7 +57,9 @@ DECLARE_bool(guide_button);
|
||||||
|
|
||||||
DECLARE_bool(clear_memory_page_state);
|
DECLARE_bool(clear_memory_page_state);
|
||||||
|
|
||||||
DECLARE_bool(d3d12_readback_resolve);
|
DECLARE_bool(readback_resolve);
|
||||||
|
|
||||||
|
DECLARE_bool(readback_memexport);
|
||||||
|
|
||||||
DEFINE_bool(fullscreen, false, "Whether to launch the emulator in fullscreen.",
|
DEFINE_bool(fullscreen, false, "Whether to launch the emulator in fullscreen.",
|
||||||
"Display");
|
"Display");
|
||||||
|
@ -1674,7 +1675,7 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case ButtonFunctions::ClearMemoryPageState:
|
case ButtonFunctions::ClearMemoryPageState:
|
||||||
ToggleGPUSetting(gpu_cvar::ClearMemoryPageState);
|
ToggleGPUSetting(GPUSetting::ClearMemoryPageState);
|
||||||
|
|
||||||
// Assume the user wants ClearCaches as well
|
// Assume the user wants ClearCaches as well
|
||||||
if (cvars::clear_memory_page_state) {
|
if (cvars::clear_memory_page_state) {
|
||||||
|
@ -1689,10 +1690,10 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
|
||||||
xe::threading::Sleep(delay);
|
xe::threading::Sleep(delay);
|
||||||
break;
|
break;
|
||||||
case ButtonFunctions::ReadbackResolve:
|
case ButtonFunctions::ReadbackResolve:
|
||||||
ToggleGPUSetting(gpu_cvar::ReadbackResolve);
|
ToggleGPUSetting(GPUSetting::ReadbackResolve);
|
||||||
|
|
||||||
notificationTitle = "Toggle Readback Resolve";
|
notificationTitle = "Toggle Readback Resolve";
|
||||||
notificationDesc = cvars::d3d12_readback_resolve ? "Enabled" : "Disabled";
|
notificationDesc = cvars::readback_resolve ? "Enabled" : "Disabled";
|
||||||
|
|
||||||
// Extra Sleep
|
// Extra Sleep
|
||||||
xe::threading::Sleep(delay);
|
xe::threading::Sleep(delay);
|
||||||
|
@ -1862,15 +1863,17 @@ void EmulatorWindow::GamepadHotKeys() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatorWindow::ToggleGPUSetting(gpu_cvar value) {
|
void EmulatorWindow::ToggleGPUSetting(gpu::GPUSetting setting) {
|
||||||
switch (value) {
|
switch (setting) {
|
||||||
case gpu_cvar::ClearMemoryPageState:
|
case GPUSetting::ClearMemoryPageState:
|
||||||
CommonSaveGPUSetting(CommonGPUSetting::ClearMemoryPageState,
|
SaveGPUSetting(GPUSetting::ClearMemoryPageState,
|
||||||
!cvars::clear_memory_page_state);
|
!cvars::clear_memory_page_state);
|
||||||
break;
|
break;
|
||||||
case gpu_cvar::ReadbackResolve:
|
case GPUSetting::ReadbackResolve:
|
||||||
D3D12SaveGPUSetting(D3D12GPUSetting::ReadbackResolve,
|
SaveGPUSetting(GPUSetting::ReadbackResolve, !cvars::readback_resolve);
|
||||||
!cvars::d3d12_readback_resolve);
|
break;
|
||||||
|
case GPUSetting::ReadbackMemexport:
|
||||||
|
SaveGPUSetting(GPUSetting::ReadbackMemexport, !cvars::readback_memexport);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1915,7 +1918,7 @@ void EmulatorWindow::DisplayHotKeysConfig() {
|
||||||
msg += "\n";
|
msg += "\n";
|
||||||
|
|
||||||
msg += "Readback Resolve: " +
|
msg += "Readback Resolve: " +
|
||||||
xe::string_util::BoolToString(cvars::d3d12_readback_resolve);
|
xe::string_util::BoolToString(cvars::readback_resolve);
|
||||||
msg += "\n";
|
msg += "\n";
|
||||||
|
|
||||||
msg += "Clear Memory Page State: " +
|
msg += "Clear Memory Page State: " +
|
||||||
|
|
|
@ -112,11 +112,6 @@ class EmulatorWindow {
|
||||||
Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class gpu_cvar {
|
|
||||||
ClearMemoryPageState,
|
|
||||||
ReadbackResolve,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ControllerHotKey {
|
class ControllerHotKey {
|
||||||
public:
|
public:
|
||||||
// If true the hotkey can be activated while a title is running, otherwise
|
// If true the hotkey can be activated while a title is running, otherwise
|
||||||
|
@ -235,7 +230,7 @@ class EmulatorWindow {
|
||||||
void VibrateController(xe::hid::InputSystem* input_sys, uint32_t user_index,
|
void VibrateController(xe::hid::InputSystem* input_sys, uint32_t user_index,
|
||||||
bool vibrate = true);
|
bool vibrate = true);
|
||||||
void GamepadHotKeys();
|
void GamepadHotKeys();
|
||||||
void ToggleGPUSetting(gpu_cvar index);
|
void ToggleGPUSetting(gpu::GPUSetting setting);
|
||||||
void DisplayHotKeysConfig();
|
void DisplayHotKeysConfig();
|
||||||
|
|
||||||
static std::string CanonicalizeFileExtension(
|
static std::string CanonicalizeFileExtension(
|
||||||
|
|
|
@ -402,7 +402,7 @@ class Timer : public WaitHandle {
|
||||||
virtual bool Cancel() = 0;
|
virtual bool Cancel() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if XE_PLATFORM_WINDOWS
|
#if XE_PLATFORM_WIN32
|
||||||
struct ThreadPriority {
|
struct ThreadPriority {
|
||||||
static const int32_t kLowest = -2;
|
static const int32_t kLowest = -2;
|
||||||
static const int32_t kBelowNormal = -1;
|
static const int32_t kBelowNormal = -1;
|
||||||
|
|
|
@ -505,6 +505,7 @@ Emulator::FileSignatureType Emulator::GetFileSignature(
|
||||||
return FileSignatureType::XISO;
|
return FileSignatureType::XISO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XELOGE("{}: {} ({:08X})", __func__, path.extension(), magic_value);
|
XELOGE("{}: {} ({:08X})", __func__, path.extension(), magic_value);
|
||||||
return FileSignatureType::Unknown;
|
return FileSignatureType::Unknown;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,17 +50,52 @@ DEFINE_bool(clear_memory_page_state, false,
|
||||||
"for 'Team Ninja' Games to fix missing character models)",
|
"for 'Team Ninja' Games to fix missing character models)",
|
||||||
"GPU");
|
"GPU");
|
||||||
|
|
||||||
|
DEFINE_bool(
|
||||||
|
readback_resolve, false,
|
||||||
|
"[D3D12 Only] Read render-to-texture results on the CPU. This may be "
|
||||||
|
"needed in some games, for instance, for screenshots in saved games, but "
|
||||||
|
"causes mid-frame synchronization, so it has a huge performance impact.",
|
||||||
|
"GPU");
|
||||||
|
|
||||||
|
DEFINE_bool(
|
||||||
|
readback_memexport, false,
|
||||||
|
"[D3D12 Only] Read data written by memory export in shaders on the CPU. "
|
||||||
|
"This may be needed in some games (but many only access exported data on "
|
||||||
|
"the GPU, and this flag isn't needed to handle such behavior), but causes "
|
||||||
|
"mid-frame synchronization, so it has a huge performance impact.",
|
||||||
|
"GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
void CommonSaveGPUSetting(CommonGPUSetting setting, uint64_t value) {
|
// This should be written completely differently with support for different
|
||||||
|
// types.
|
||||||
|
void SaveGPUSetting(GPUSetting setting, uint64_t value) {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case CommonGPUSetting::ClearMemoryPageState:
|
case GPUSetting::ClearMemoryPageState:
|
||||||
OVERRIDE_bool(clear_memory_page_state, (bool)value);
|
OVERRIDE_bool(clear_memory_page_state, static_cast<bool>(value));
|
||||||
|
break;
|
||||||
|
case GPUSetting::ReadbackResolve:
|
||||||
|
OVERRIDE_bool(readback_resolve, static_cast<bool>(value));
|
||||||
|
break;
|
||||||
|
case GPUSetting::ReadbackMemexport:
|
||||||
|
OVERRIDE_bool(readback_memexport, static_cast<bool>(value));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetGPUSetting(GPUSetting setting) {
|
||||||
|
switch (setting) {
|
||||||
|
case GPUSetting::ClearMemoryPageState:
|
||||||
|
return cvars::clear_memory_page_state;
|
||||||
|
case GPUSetting::ReadbackResolve:
|
||||||
|
return cvars::readback_resolve;
|
||||||
|
case GPUSetting::ReadbackMemexport:
|
||||||
|
return cvars::readback_memexport;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
using namespace xe::gpu::xenos;
|
using namespace xe::gpu::xenos;
|
||||||
|
|
||||||
CommandProcessor::CommandProcessor(GraphicsSystem* graphics_system,
|
CommandProcessor::CommandProcessor(GraphicsSystem* graphics_system,
|
||||||
|
|
|
@ -33,11 +33,14 @@ class ByteStream;
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
enum class CommonGPUSetting {
|
enum class GPUSetting {
|
||||||
ClearMemoryPageState,
|
ClearMemoryPageState,
|
||||||
|
ReadbackResolve,
|
||||||
|
ReadbackMemexport
|
||||||
};
|
};
|
||||||
|
|
||||||
void CommonSaveGPUSetting(CommonGPUSetting setting, uint64_t value);
|
void SaveGPUSetting(GPUSetting setting, uint64_t value);
|
||||||
|
bool GetGPUSetting(GPUSetting setting);
|
||||||
|
|
||||||
class GraphicsSystem;
|
class GraphicsSystem;
|
||||||
class Shader;
|
class Shader;
|
||||||
|
|
|
@ -32,19 +32,7 @@ DEFINE_bool(d3d12_bindless, true,
|
||||||
"Use bindless resources where available - may improve performance, "
|
"Use bindless resources where available - may improve performance, "
|
||||||
"but may make debugging more complicated.",
|
"but may make debugging more complicated.",
|
||||||
"D3D12");
|
"D3D12");
|
||||||
DEFINE_bool(d3d12_readback_memexport, false,
|
|
||||||
"Read data written by memory export in shaders on the CPU. This "
|
|
||||||
"may be needed in some games (but many only access exported data "
|
|
||||||
"on the GPU, and this flag isn't needed to handle such behavior), "
|
|
||||||
"but causes mid-frame synchronization, so it has a huge "
|
|
||||||
"performance impact.",
|
|
||||||
"D3D12");
|
|
||||||
DEFINE_bool(d3d12_readback_resolve, false,
|
|
||||||
"Read render-to-texture results on the CPU. This may be needed in "
|
|
||||||
"some games, for instance, for screenshots in saved games, but "
|
|
||||||
"causes mid-frame synchronization, so it has a huge performance "
|
|
||||||
"impact.",
|
|
||||||
"D3D12");
|
|
||||||
DEFINE_bool(d3d12_submit_on_primary_buffer_end, true,
|
DEFINE_bool(d3d12_submit_on_primary_buffer_end, true,
|
||||||
"Submit the command list when a PM4 primary buffer ends if it's "
|
"Submit the command list when a PM4 primary buffer ends if it's "
|
||||||
"possible to submit immediately to try to reduce frame latency.",
|
"possible to submit immediately to try to reduce frame latency.",
|
||||||
|
@ -54,15 +42,6 @@ DECLARE_bool(clear_memory_page_state);
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
void D3D12SaveGPUSetting(D3D12GPUSetting setting, uint64_t value) {
|
|
||||||
switch (setting) {
|
|
||||||
case D3D12GPUSetting::ReadbackResolve:
|
|
||||||
OVERRIDE_bool(d3d12_readback_resolve, (bool)value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
// Generated with `xb buildshaders`.
|
// Generated with `xb buildshaders`.
|
||||||
|
@ -3011,7 +2990,7 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||||
memexport_range.base_address_dwords << 2, memexport_range.size_bytes,
|
memexport_range.base_address_dwords << 2, memexport_range.size_bytes,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
if (cvars::d3d12_readback_memexport) {
|
if (GetGPUSetting(GPUSetting::ReadbackResolve)) {
|
||||||
// Read the exported data on the CPU.
|
// Read the exported data on the CPU.
|
||||||
uint32_t memexport_total_size = 0;
|
uint32_t memexport_total_size = 0;
|
||||||
for (const draw_util::MemExportRange& memexport_range :
|
for (const draw_util::MemExportRange& memexport_range :
|
||||||
|
@ -3091,7 +3070,7 @@ bool D3D12CommandProcessor::IssueCopy() {
|
||||||
if (!BeginSubmission(true)) {
|
if (!BeginSubmission(true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!cvars::d3d12_readback_resolve) {
|
if (!GetGPUSetting(GPUSetting::ReadbackResolve)) {
|
||||||
uint32_t written_address, written_length;
|
uint32_t written_address, written_length;
|
||||||
return render_target_cache_->Resolve(*memory_, *shared_memory_,
|
return render_target_cache_->Resolve(*memory_, *shared_memory_,
|
||||||
*texture_cache_, written_address,
|
*texture_cache_, written_address,
|
||||||
|
|
|
@ -44,6 +44,7 @@ DEFINE_int32(avpack, 8,
|
||||||
"Video");
|
"Video");
|
||||||
DECLARE_int32(user_country);
|
DECLARE_int32(user_country);
|
||||||
DECLARE_int32(user_language);
|
DECLARE_int32(user_language);
|
||||||
|
DECLARE_uint32(audio_flag);
|
||||||
|
|
||||||
DEFINE_bool(staging_mode, 0,
|
DEFINE_bool(staging_mode, 0,
|
||||||
"Enables preview mode in dashboards to render debug information.",
|
"Enables preview mode in dashboards to render debug information.",
|
||||||
|
@ -648,7 +649,7 @@ dword_result_t lstrlenW_entry(lpu16string_t string) {
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(lstrlenW, kNone, kImplemented);
|
DECLARE_XAM_EXPORT1(lstrlenW, kNone, kImplemented);
|
||||||
|
|
||||||
dword_result_t XGetAudioFlags_entry() { return 65537; }
|
dword_result_t XGetAudioFlags_entry() { return cvars::audio_flag; }
|
||||||
DECLARE_XAM_EXPORT1(XGetAudioFlags, kNone, kStub);
|
DECLARE_XAM_EXPORT1(XGetAudioFlags, kNone, kStub);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
|
DECLARE_uint32(audio_flag);
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
dword_result_t XAudioGetSpeakerConfig_entry(lpdword_t config_ptr) {
|
dword_result_t XAudioGetSpeakerConfig_entry(lpdword_t config_ptr) {
|
||||||
*config_ptr = 0x00010001;
|
*config_ptr = cvars::audio_flag;
|
||||||
return X_ERROR_SUCCESS;
|
return X_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT1(XAudioGetSpeakerConfig, kAudio, kImplemented);
|
DECLARE_XBOXKRNL_EXPORT1(XAudioGetSpeakerConfig, kAudio, kImplemented);
|
||||||
|
|
|
@ -37,6 +37,23 @@ DEFINE_int32(user_country, 103,
|
||||||
" 102=UA 103=US 104=UY 105=UZ 106=VE 107=VN 108=YE 109=ZA\n",
|
" 102=UA 103=US 104=UY 105=UZ 106=VE 107=VN 108=YE 109=ZA\n",
|
||||||
"XConfig");
|
"XConfig");
|
||||||
|
|
||||||
|
DEFINE_uint32(
|
||||||
|
audio_flag, 0x00010001,
|
||||||
|
"Audio Mode Analog.\n"
|
||||||
|
" 0x00000001 = Dolby Pro Logic\n"
|
||||||
|
" 0x00000002 = Analog Mono\n"
|
||||||
|
"Audio Mode Digital.\n"
|
||||||
|
" 0x00000000 = Digital Stereo (choose one of the above by itself)\n"
|
||||||
|
" 0x00010000 = Dolby Digital\n"
|
||||||
|
" 0x00030000 = Dolby Digital with WMA PRO\n"
|
||||||
|
"Special Flags.\n"
|
||||||
|
" 0x00000003 = Stereo Bypass\n"
|
||||||
|
" 0x80000000 = Low Latency\n"
|
||||||
|
" This Config requires you to pair an analog and digitial flag together\n"
|
||||||
|
" while digital stereo only requires an analog flag. Bonus flags are\n"
|
||||||
|
" optional. Ex) 0x00010001\n",
|
||||||
|
"XConfig");
|
||||||
|
|
||||||
DECLARE_bool(widescreen);
|
DECLARE_bool(widescreen);
|
||||||
DECLARE_bool(use_50Hz_mode);
|
DECLARE_bool(use_50Hz_mode);
|
||||||
DECLARE_int32(video_standard);
|
DECLARE_int32(video_standard);
|
||||||
|
@ -109,6 +126,10 @@ X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting,
|
||||||
xe::store_and_swap<uint32_t>(
|
xe::store_and_swap<uint32_t>(
|
||||||
value, cvars::widescreen ? 0x00050000 : 0x00040000);
|
value, cvars::widescreen ? 0x00050000 : 0x00040000);
|
||||||
break;
|
break;
|
||||||
|
case 0x000B: // XCONFIG_USER_AUDIO_FLAGS
|
||||||
|
setting_size = 4;
|
||||||
|
xe::store_and_swap<uint32_t>(value, cvars::audio_flag);
|
||||||
|
break;
|
||||||
case 0x000C: // XCONFIG_USER_RETAIL_FLAGS
|
case 0x000C: // XCONFIG_USER_RETAIL_FLAGS
|
||||||
setting_size = 4;
|
setting_size = 4;
|
||||||
// TODO(benvanik): get this value.
|
// TODO(benvanik): get this value.
|
||||||
|
|
Loading…
Reference in New Issue