mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-02 10:14:48 +12:00
Merge branch 'master' into shader-decomp
This commit is contained in:
commit
cf31f7b7e0
11 changed files with 946 additions and 5 deletions
src
|
@ -71,6 +71,7 @@ void EmulatorConfig::load() {
|
|||
|
||||
forceShadergenForLights = toml::find_or<toml::boolean>(gpu, "ForceShadergenForLighting", true);
|
||||
lightShadergenThreshold = toml::find_or<toml::integer>(gpu, "ShadergenLightThreshold", 1);
|
||||
enableRenderdoc = toml::find_or<toml::boolean>(gpu, "EnableRenderdoc", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +143,7 @@ void EmulatorConfig::save() {
|
|||
data["GPU"]["ForceShadergenForLighting"] = forceShadergenForLights;
|
||||
data["GPU"]["ShadergenLightThreshold"] = lightShadergenThreshold;
|
||||
data["GPU"]["AccelerateShaders"] = accelerateShaders;
|
||||
data["GPU"]["EnableRenderdoc"] = enableRenderdoc;
|
||||
|
||||
data["Audio"]["DSPEmulation"] = std::string(Audio::DSPCore::typeToString(dspType));
|
||||
data["Audio"]["EnableAudio"] = audioEnabled;
|
||||
|
|
|
@ -194,7 +194,10 @@ void GPU::drawArrays() {
|
|||
// Configures the type of primitive and the number of vertex shader outputs
|
||||
const u32 primConfig = regs[PICA::InternalRegs::PrimitiveConfig];
|
||||
const PICA::PrimType primType = static_cast<PICA::PrimType>(Helpers::getBits<8, 2>(primConfig));
|
||||
if (vertexCount > Renderer::vertexBufferSize) Helpers::panic("[PICA] vertexCount > vertexBufferSize");
|
||||
if (vertexCount > Renderer::vertexBufferSize) [[unlikely]] {
|
||||
Helpers::warn("[PICA] vertexCount > vertexBufferSize");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((primType == PICA::PrimType::TriangleList && vertexCount % 3) || (primType == PICA::PrimType::TriangleStrip && vertexCount < 3) ||
|
||||
(primType == PICA::PrimType::TriangleFan && vertexCount < 3)) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
#include "renderdoc.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -32,6 +34,10 @@ Emulator::Emulator()
|
|||
audioDevice.init(dsp->getSamples());
|
||||
setAudioEnabled(config.audioEnabled);
|
||||
|
||||
if (Renderdoc::isSupported() && config.enableRenderdoc) {
|
||||
loadRenderdoc();
|
||||
}
|
||||
|
||||
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
|
||||
if (config.discordRpcEnabled) {
|
||||
discordRpc.init();
|
||||
|
@ -431,3 +437,9 @@ void Emulator::setAudioEnabled(bool enable) {
|
|||
|
||||
dsp->setAudioEnabled(enable);
|
||||
}
|
||||
|
||||
void Emulator::loadRenderdoc() {
|
||||
std::string capturePath = (std::filesystem::current_path() / "RenderdocCaptures").generic_string();
|
||||
Renderdoc::loadRenderdoc();
|
||||
Renderdoc::setOutputDir(capturePath, "");
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
#include "panda_sdl/frontend_sdl.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include "renderdoc.hpp"
|
||||
#include "sdl_sensors.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
FrontendSDL::FrontendSDL() : keyboardMappings(InputMappings::defaultKeyboardMappings()) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) {
|
||||
|
@ -140,6 +141,14 @@ void FrontendSDL::run() {
|
|||
emu.reset(Emulator::ReloadOption::Reload);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_F11: {
|
||||
if constexpr (Renderdoc::isSupported()) {
|
||||
Renderdoc::triggerCapture();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
119
src/renderdoc.cpp
Normal file
119
src/renderdoc.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifdef PANDA3DS_ENABLE_RENDERDOC
|
||||
#include "renderdoc.hpp"
|
||||
|
||||
#include <renderdoc_app.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
|
||||
namespace Renderdoc {
|
||||
enum class CaptureState {
|
||||
Idle,
|
||||
Triggered,
|
||||
InProgress,
|
||||
};
|
||||
|
||||
static CaptureState captureState{CaptureState::Idle};
|
||||
RENDERDOC_API_1_6_0* rdocAPI{};
|
||||
|
||||
void loadRenderdoc() {
|
||||
#ifdef WIN32
|
||||
// Check if we are running in Renderdoc GUI
|
||||
HMODULE mod = GetModuleHandleA("renderdoc.dll");
|
||||
if (!mod) {
|
||||
// If enabled in config, try to load RDoc runtime in offline mode
|
||||
HKEY h_reg_key;
|
||||
LONG result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\RenderDoc.RDCCapture.1\\DefaultIcon\\", 0, KEY_READ, &h_reg_key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
std::array<wchar_t, MAX_PATH> keyString{};
|
||||
DWORD stringSize{keyString.size()};
|
||||
result = RegQueryValueExW(h_reg_key, L"", 0, NULL, (LPBYTE)keyString.data(), &stringSize);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::filesystem::path path{keyString.cbegin(), keyString.cend()};
|
||||
path = path.parent_path().append("renderdoc.dll");
|
||||
const auto path_to_lib = path.generic_string();
|
||||
mod = LoadLibraryA(path_to_lib.c_str());
|
||||
}
|
||||
|
||||
if (mod) {
|
||||
const auto RENDERDOC_GetAPI = reinterpret_cast<pRENDERDOC_GetAPI>(GetProcAddress(mod, "RENDERDOC_GetAPI"));
|
||||
const s32 ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, (void**)&rdocAPI);
|
||||
|
||||
if (ret != 1) {
|
||||
Helpers::panic("Invalid return value from RENDERDOC_GetAPI");
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef ANDROID
|
||||
static constexpr const char RENDERDOC_LIB[] = "libVkLayer_GLES_RenderDoc.so";
|
||||
#else
|
||||
static constexpr const char RENDERDOC_LIB[] = "librenderdoc.so";
|
||||
#endif
|
||||
if (void* mod = dlopen(RENDERDOC_LIB, RTLD_NOW | RTLD_NOLOAD)) {
|
||||
const auto RENDERDOC_GetAPI = reinterpret_cast<pRENDERDOC_GetAPI>(dlsym(mod, "RENDERDOC_GetAPI"));
|
||||
const s32 ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_6_0, (void**)&rdocAPI);
|
||||
|
||||
if (ret != 1) {
|
||||
Helpers::panic("Invalid return value from RENDERDOC_GetAPI");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (rdocAPI) {
|
||||
// Disable default capture keys as they suppose to trigger present-to-present capturing
|
||||
// and it is not what we want
|
||||
rdocAPI->SetCaptureKeys(nullptr, 0);
|
||||
|
||||
// Also remove rdoc crash handler
|
||||
rdocAPI->UnloadCrashHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void startCapture() {
|
||||
if (!rdocAPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (captureState == CaptureState::Triggered) {
|
||||
rdocAPI->StartFrameCapture(nullptr, nullptr);
|
||||
captureState = CaptureState::InProgress;
|
||||
}
|
||||
}
|
||||
|
||||
void endCapture() {
|
||||
if (!rdocAPI) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (captureState == CaptureState::InProgress) {
|
||||
rdocAPI->EndFrameCapture(nullptr, nullptr);
|
||||
captureState = CaptureState::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
void triggerCapture() {
|
||||
if (captureState == CaptureState::Idle) {
|
||||
captureState = CaptureState::Triggered;
|
||||
}
|
||||
}
|
||||
|
||||
void setOutputDir(const std::string& path, const std::string& prefix) {
|
||||
if (rdocAPI) {
|
||||
rdocAPI->SetCaptureFilePathTemplate((path + '\\' + prefix).c_str());
|
||||
}
|
||||
}
|
||||
} // namespace Renderdoc
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue