This commit is contained in:
commit
f01be7dde7
|
@ -43,10 +43,10 @@ jobs:
|
|||
mv ${{github.workspace}}/build/shadps4 upload
|
||||
cp $(arch -x86_64 /usr/local/bin/brew --prefix)/opt/molten-vk/lib/libMoltenVK.dylib upload
|
||||
install_name_tool -add_rpath "@loader_path" upload/shadps4
|
||||
tar cf shadps4-macos.tar.gz -C upload .
|
||||
tar cf shadps4-macos-sdl.tar.gz -C upload .
|
||||
|
||||
- name: Upload executable
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: shadps4-macos
|
||||
path: shadps4-macos.tar.gz
|
||||
name: shadps4-macos-sdl
|
||||
path: shadps4-macos-sdl.tar.gz
|
||||
|
|
|
@ -29,6 +29,6 @@ jobs:
|
|||
- name: Upload executable
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: shadps4-win64
|
||||
name: shadps4-win64-sdl
|
||||
path: |
|
||||
${{github.workspace}}/build/Release/shadPS4.exe
|
||||
|
|
|
@ -15,6 +15,7 @@ Files: CMakeSettings.json
|
|||
documents/Screenshots/Undertale.png
|
||||
documents/Screenshots/We are DOOMED.png
|
||||
scripts/ps4_names.txt
|
||||
src/images/about_icon.png
|
||||
src/images/controller_icon.png
|
||||
src/images/exit_icon.png
|
||||
src/images/file_icon.png
|
||||
|
|
|
@ -73,7 +73,7 @@ find_package(glslang 14.2.0 CONFIG)
|
|||
find_package(magic_enum 0.9.6 CONFIG)
|
||||
find_package(RenderDoc 1.6.0 MODULE)
|
||||
find_package(SDL3 3.1.2 CONFIG)
|
||||
find_package(toml11 3.8.1 CONFIG)
|
||||
find_package(toml11 4.2.0 CONFIG)
|
||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||
find_package(VulkanHeaders 1.3.289 CONFIG)
|
||||
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
||||
|
@ -127,6 +127,8 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
|
|||
src/core/libraries/audio/audioout.h
|
||||
src/core/libraries/ajm/ajm.cpp
|
||||
src/core/libraries/ajm/ajm.h
|
||||
src/core/libraries/ngs2/ngs2.cpp
|
||||
src/core/libraries/ngs2/ngs2.h
|
||||
)
|
||||
|
||||
set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0dc6711e5a178e4d5643437af688c6b48f829f5c
|
||||
Subproject commit d59c84d388c805022e2bddea08aa41cbe7e43e55
|
|
@ -1 +1 @@
|
|||
Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd
|
||||
Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9
|
|
@ -1 +1 @@
|
|||
Subproject commit 54c14fe6a6654abf12d315a45a68005586cb7610
|
||||
Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d
|
|
@ -112,6 +112,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
|||
SUB(Lib, ErrorDialog) \
|
||||
SUB(Lib, ImeDialog) \
|
||||
SUB(Lib, AvPlayer) \
|
||||
SUB(Lib, Ngs2) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Vulkan) \
|
||||
|
|
|
@ -79,6 +79,7 @@ enum class Class : u8 {
|
|||
Lib_ErrorDialog, ///< The LibSceErrorDialog implementation.
|
||||
Lib_ImeDialog, ///< The LibSceImeDialog implementation.
|
||||
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
||||
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Video Core
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
|
|
|
@ -99,7 +99,7 @@ struct AddressSpace::Impl {
|
|||
backing_handle =
|
||||
CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ,
|
||||
PAGE_READWRITE, SEC_COMMIT, BackingSize, nullptr, nullptr, 0);
|
||||
ASSERT(backing_handle);
|
||||
ASSERT_MSG(backing_handle, "{}", Common::GetLastErrorMsg());
|
||||
// Allocate a virtual memory for the backing file map as placeholder
|
||||
backing_base = static_cast<u8*>(VirtualAlloc2(process, nullptr, BackingSize,
|
||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||
|
@ -107,7 +107,7 @@ struct AddressSpace::Impl {
|
|||
// Map backing placeholder. This will commit the pages
|
||||
void* const ret = MapViewOfFile3(backing_handle, process, backing_base, 0, BackingSize,
|
||||
MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
|
||||
ASSERT(ret == backing_base);
|
||||
ASSERT_MSG(ret == backing_base, "{}", Common::GetLastErrorMsg());
|
||||
}
|
||||
|
||||
~Impl() {
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2.h"
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2CalcWaveformBlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2FftInit() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2FftProcess() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2FftQuerySize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomApply() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomCalcListener() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomResetListenerParam() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GeomResetSourceParam() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2JobSchedulerResetOption() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ModuleArrayEnumItems() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ModuleEnumConfigs() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ModuleQueueEnumItems() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2PanInit() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformFile() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ParseWaveformUser() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackCreateWithAllocator() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackDestroy() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackGetVoiceHandle() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackLock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackQueryBufferSize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackRunCommands() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackSetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2RackUnlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ReportRegisterHandler() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2ReportUnregisterHandler() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemDestroy() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemEnumHandles() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemEnumRackHandles() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemGetInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemGetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemLock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemQueryBufferSize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemRender() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemResetOption() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemRunCommands() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetGrainSamples() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetLoudThreshold() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetSampleRate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemSetUserData() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2SystemUnlock() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamCreate() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamCreateWithAllocator() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamDestroy() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamQueryBufferSize() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamResetOption() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2StreamRunCommands() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceControl() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetOwner() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetPortInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetState() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceGetStateFlags() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceQueryInfo() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNgs2VoiceRunCommands() {
|
||||
LOG_ERROR(Lib_Ngs2, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("3pCNbVM11UA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2CalcWaveformBlock);
|
||||
LIB_FUNCTION("6qN1zaEZuN0", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2CustomRackGetModuleInfo);
|
||||
LIB_FUNCTION("Kg1MA5j7KFk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftInit);
|
||||
LIB_FUNCTION("D8eCqBxSojA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftProcess);
|
||||
LIB_FUNCTION("-YNfTO6KOMY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2FftQuerySize);
|
||||
LIB_FUNCTION("eF8yRCC6W64", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomApply);
|
||||
LIB_FUNCTION("1WsleK-MTkE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomCalcListener);
|
||||
LIB_FUNCTION("7Lcfo8SmpsU", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetListenerParam);
|
||||
LIB_FUNCTION("0lbbayqDNoE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GeomResetSourceParam);
|
||||
LIB_FUNCTION("ekGJmmoc8j4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2GetWaveformFrameInfo);
|
||||
LIB_FUNCTION("BcoPfWfpvVI", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2JobSchedulerResetOption);
|
||||
LIB_FUNCTION("EEemGEQCjO8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleArrayEnumItems);
|
||||
LIB_FUNCTION("TaoNtmMKkXQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleEnumConfigs);
|
||||
LIB_FUNCTION("ve6bZi+1sYQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ModuleQueueEnumItems);
|
||||
LIB_FUNCTION("gbMKV+8Enuo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanGetVolumeMatrix);
|
||||
LIB_FUNCTION("xa8oL9dmXkM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2PanInit);
|
||||
LIB_FUNCTION("hyVLT2VlOYk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformData);
|
||||
LIB_FUNCTION("iprCTXPVWMI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformFile);
|
||||
LIB_FUNCTION("t9T0QM17Kvo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ParseWaveformUser);
|
||||
LIB_FUNCTION("cLV4aiT9JpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackCreate);
|
||||
LIB_FUNCTION("U546k6orxQo", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2RackCreateWithAllocator);
|
||||
LIB_FUNCTION("lCqD7oycmIM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackDestroy);
|
||||
LIB_FUNCTION("M4LYATRhRUE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetInfo);
|
||||
LIB_FUNCTION("Mn4XNDg03XY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetUserData);
|
||||
LIB_FUNCTION("MwmHz8pAdAo", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackGetVoiceHandle);
|
||||
LIB_FUNCTION("MzTa7VLjogY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackLock);
|
||||
LIB_FUNCTION("0eFLVCfWVds", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryBufferSize);
|
||||
LIB_FUNCTION("TZqb8E-j3dY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackQueryInfo);
|
||||
LIB_FUNCTION("MI2VmBx2RbM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackRunCommands);
|
||||
LIB_FUNCTION("JNTMIaBIbV4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackSetUserData);
|
||||
LIB_FUNCTION("++YZ7P9e87U", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2RackUnlock);
|
||||
LIB_FUNCTION("uBIN24Tv2MI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2ReportRegisterHandler);
|
||||
LIB_FUNCTION("nPzb7Ly-VjE", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2ReportUnregisterHandler);
|
||||
LIB_FUNCTION("koBbCMvOKWw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemCreate);
|
||||
LIB_FUNCTION("mPYgU4oYpuY", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2SystemCreateWithAllocator);
|
||||
LIB_FUNCTION("u-WrYDaJA3k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemDestroy);
|
||||
LIB_FUNCTION("vubFP0T6MP0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumHandles);
|
||||
LIB_FUNCTION("U-+7HsswcIs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemEnumRackHandles);
|
||||
LIB_FUNCTION("vU7TQ62pItw", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetInfo);
|
||||
LIB_FUNCTION("4lFaRxd-aLs", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemGetUserData);
|
||||
LIB_FUNCTION("gThZqM5PYlQ", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemLock);
|
||||
LIB_FUNCTION("pgFAiLR5qT4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryBufferSize);
|
||||
LIB_FUNCTION("3oIK7y7O4k0", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemQueryInfo)
|
||||
LIB_FUNCTION("i0VnXM-C9fc", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRender);
|
||||
LIB_FUNCTION("AQkj7C0f3PY", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemResetOption);
|
||||
LIB_FUNCTION("gXiormHoZZ4", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemRunCommands);
|
||||
LIB_FUNCTION("l4Q2dWEH6UM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetGrainSamples);
|
||||
LIB_FUNCTION("Wdlx0ZFTV9s", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetLoudThreshold);
|
||||
LIB_FUNCTION("-tbc2SxQD60", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetSampleRate);
|
||||
LIB_FUNCTION("GZB2v0XnG0k", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemSetUserData);
|
||||
LIB_FUNCTION("JXRC5n0RQls", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2SystemUnlock);
|
||||
LIB_FUNCTION("sU2St3agdjg", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamCreate);
|
||||
LIB_FUNCTION("I+RLwaauggA", "libSceNgs2", 1, "libSceNgs2", 1, 1,
|
||||
sceNgs2StreamCreateWithAllocator);
|
||||
LIB_FUNCTION("bfoMXnTRtwE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamDestroy);
|
||||
LIB_FUNCTION("dxulc33msHM", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryBufferSize);
|
||||
LIB_FUNCTION("rfw6ufRsmow", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamQueryInfo);
|
||||
LIB_FUNCTION("q+2W8YdK0F8", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamResetOption);
|
||||
LIB_FUNCTION("qQHCi9pjDps", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2StreamRunCommands);
|
||||
LIB_FUNCTION("uu94irFOGpA", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceControl);
|
||||
LIB_FUNCTION("jjBVvPN9964", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetMatrixInfo);
|
||||
LIB_FUNCTION("W-Z8wWMBnhk", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetOwner);
|
||||
LIB_FUNCTION("WCayTgob7-o", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetPortInfo);
|
||||
LIB_FUNCTION("-TOuuAQ-buE", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetState);
|
||||
LIB_FUNCTION("rEh728kXk3w", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceGetStateFlags);
|
||||
LIB_FUNCTION("9eic4AmjGVI", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceQueryInfo);
|
||||
LIB_FUNCTION("AbYvTOZ8Pts", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceRunCommands);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
|
@ -0,0 +1,72 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2;
|
||||
|
||||
using SceNgs2Handle = Ngs2*;
|
||||
|
||||
enum SceNgs2HandleType { SCE_NGS2_HANDLE_TYPE_SYSTEM = 0 };
|
||||
|
||||
struct Ngs2Handle {
|
||||
void* selfPointer;
|
||||
void* dataPointer;
|
||||
std::atomic<u32>* atomicPtr;
|
||||
u32 handleType;
|
||||
u32 flags_unk;
|
||||
|
||||
u32 uid;
|
||||
u16 maxGrainSamples;
|
||||
u16 minGrainSamples;
|
||||
u16 currentGrainSamples;
|
||||
u16 numGrainSamples;
|
||||
u16 unknown2;
|
||||
u32 sampleRate;
|
||||
u32 unknown3;
|
||||
|
||||
void* flushMutex;
|
||||
u32 flushMutexInitialized;
|
||||
void* processMutex;
|
||||
u32 processMutexInitialized;
|
||||
|
||||
// Linked list pointers for system list
|
||||
Ngs2Handle* prev;
|
||||
Ngs2Handle* next;
|
||||
};
|
||||
|
||||
struct SystemOptions {
|
||||
char padding[6];
|
||||
s32 maxGrainSamples;
|
||||
s32 numGrainSamples;
|
||||
s32 sampleRate;
|
||||
};
|
||||
|
||||
struct SystemState {
|
||||
// TODO
|
||||
};
|
||||
|
||||
struct StackBuffer {
|
||||
void** top;
|
||||
void* base;
|
||||
void* curr;
|
||||
size_t usedSize;
|
||||
size_t totalSize;
|
||||
size_t alignment;
|
||||
char isVerifyEnabled;
|
||||
char padding[7];
|
||||
};
|
||||
|
||||
void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Ngs2
|
|
@ -0,0 +1,56 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETERS = 0x804A0001;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES = 0x804A0050;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES = 0x804A0051;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_CHANNELS = 0x804A0052;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALD_ADDRESS = 0x804A0053;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALD_SIZE = 0x804A0054;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_OPTION_SIZE = 0x804A0081;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_MATRICES = 0x804A0100;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_PORTS = 0x804A0101;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_OPTION_MAX_INPUT_DELAY_BLOCKS = 0x804A0102;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVELS = 0x804A0150;
|
||||
constexpr int ORBIS_NGS2_ERROR_SAMPLER_WAVEFORM_TERMINATED = 0x804A0151;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINTS = 0x804A0152;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_LEVEL_ADDRESS = 0x804A0153;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_BLOCK_ADDRESS = 0x804A0154;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_POINT_ADDRESS = 0x804A0155;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_HANDLE = 0x804A0200;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE = 0x804A0201;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE = 0x804A0204;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_INFO = 0x804A0206;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ADDRESS = 0x804A0207;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALIGNMENT = 0x804A0208;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_SIZE = 0x804A0209;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_BUFFER_ALLOCATOR = 0x804A020A;
|
||||
constexpr int ORBIS_NGS2_ERROR_BUFFER_VERIFY_FAILED = 0x804A020B;
|
||||
constexpr int ORBIS_NGS2_ERROR_MODULE_PLAYER_DATA_EMPTY = 0x804A020C;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE = 0x804A0230;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_ID = 0x804A0260;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE = 0x804A0261;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE = 0x804A0300;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INDEX = 0x804A0302;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_EVENT = 0x804A0303;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_PORT_INDEX = 0x804A0304;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_INPUT_OR_RACK_OCCUPIED = 0x804A0305;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_CONTROL_ID = 0x804A0308;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_VOICE_CONTROL_PARAMETER = 0x804A0309;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_PARAMETER_SIZE = 0x804A030A;
|
||||
constexpr int ORBIS_NGS2_ERROR_DETECTED_CIRCULAR_VOICE_CONTROL = 0x804A030B;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_DATA = 0x804A0400;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FORMAT = 0x804A0401;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_TYPE_NO_ATRAC9_DECODERS = 0x804A0402;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_ATRAC9_CONFIG_DATA = 0x804A0403;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_SAMPLE_RATE = 0x804A0404;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_FRAME = 0x804A0405;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_SAMPLER_WAVEFORM_ADDRESS = 0x804A0406;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_ENVELOPE_CURVE = 0x804A0500;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_INDEX = 0x804A0600;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_TYPE = 0x804A0601;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_FILTER_LOCATION = 0x804A0602;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_LFE_CUT_OFF_FREQUENCY = 0x804A0603;
|
||||
constexpr int ORBIS_NGS2_ERROR_INVALID_MATRIX_INDEX_OR_TYPE = 0x804A0700;
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ngs2_error.h"
|
||||
#include "ngs2_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/libkernel.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
s32 Ngs2::ReportInvalid(u32 handle_type) const {
|
||||
switch (handle_type) {
|
||||
case 1:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system handle {}", this);
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
case 2:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid rack handle {}", this);
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
case 4:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid voice handle {}", this);
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
case 8:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid report handle {}", this);
|
||||
return ORBIS_NGS2_ERROR_INVALID_REPORT_HANDLE;
|
||||
default:
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid handle {}", this);
|
||||
return ORBIS_NGS2_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleSetup(Ngs2Handle* handle, void* data, std::atomic<u32>* atomic, u32 type,
|
||||
u32 flags) {
|
||||
handle->dataPointer = data;
|
||||
handle->atomicPtr = atomic;
|
||||
handle->handleType = type;
|
||||
handle->flags_unk = flags;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut) {
|
||||
if (handle && handle->selfPointer == handle) {
|
||||
std::atomic<u32>* tmp_atomic = handle->atomicPtr;
|
||||
if (tmp_atomic && handle->handleType == hType) {
|
||||
while (tmp_atomic->load() != 0) {
|
||||
u32 expected = 1;
|
||||
if (tmp_atomic->compare_exchange_strong(expected, 0)) {
|
||||
if (dataOut) {
|
||||
dataOut = handle->dataPointer;
|
||||
}
|
||||
// sceNgs2MemoryClear(handle, 32);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
tmp_atomic = handle->atomicPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HandleReportInvalid(handle, hType);
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut) {
|
||||
if (!handle) {
|
||||
return HandleReportInvalid(handle, 0);
|
||||
}
|
||||
|
||||
if (handle->selfPointer != handle || !handle->atomicPtr || !handle->dataPointer ||
|
||||
(~hType & handle->handleType)) {
|
||||
return HandleReportInvalid(handle, handle->handleType);
|
||||
}
|
||||
|
||||
std::atomic<u32>* atomic = handle->atomicPtr;
|
||||
while (true) {
|
||||
u32 i = atomic->load();
|
||||
if (i == 0) {
|
||||
return HandleReportInvalid(handle, handle->handleType);
|
||||
}
|
||||
if (atomic->compare_exchange_strong(i, i + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (handleOut) {
|
||||
*handleOut = handle;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::HandleLeave(Ngs2Handle* handle) {
|
||||
std::atomic<u32>* tmp_atomic;
|
||||
u32 i;
|
||||
do {
|
||||
tmp_atomic = handle->atomicPtr;
|
||||
i = tmp_atomic->load();
|
||||
} while (!tmp_atomic->compare_exchange_strong(i, i - 1));
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop,
|
||||
bool verify) {
|
||||
buf->top = stackTop;
|
||||
buf->base = base_addr;
|
||||
buf->curr = base_addr;
|
||||
buf->usedSize = 0;
|
||||
buf->totalSize = size;
|
||||
buf->alignment = 8;
|
||||
buf->isVerifyEnabled = verify;
|
||||
|
||||
if (stackTop) {
|
||||
*stackTop = nullptr;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::StackBufferClose(StackBuffer* buf, size_t* usedSize) {
|
||||
if (usedSize) {
|
||||
*usedSize = buf->usedSize + buf->alignment;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 Ngs2::SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut) {
|
||||
u32 maxGrainSamples = 512;
|
||||
u32 numGrainSamples = 256;
|
||||
u32 sampleRate = 48000;
|
||||
|
||||
if (options) {
|
||||
maxGrainSamples = options->maxGrainSamples;
|
||||
numGrainSamples = options->numGrainSamples;
|
||||
sampleRate = options->sampleRate;
|
||||
}
|
||||
|
||||
// Validate maxGrainSamples
|
||||
if (maxGrainSamples < 64 || maxGrainSamples > 1024 || (maxGrainSamples & 0x3F) != 0) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option (maxGrainSamples={},x64)", maxGrainSamples);
|
||||
return ORBIS_NGS2_ERROR_INVALID_MAXIMUM_GRAIN_SAMPLES;
|
||||
}
|
||||
|
||||
// Validate numGrainSamples
|
||||
if (numGrainSamples < 64 || numGrainSamples > 1024 || (numGrainSamples & 0x3F) != 0) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option (numGrainSamples={},x64)", numGrainSamples);
|
||||
return ORBIS_NGS2_ERROR_INVALID_GRAIN_SAMPLES;
|
||||
}
|
||||
|
||||
// Validate sampleRate
|
||||
if (sampleRate != 11025 && sampleRate != 12000 && sampleRate != 22050 && sampleRate != 24000 &&
|
||||
sampleRate != 44100 && sampleRate != 48000 && sampleRate != 88200 && sampleRate != 96000) {
|
||||
LOG_ERROR(Lib_Ngs2, "Invalid system option(sampleRate={}:44.1/48kHz series)", sampleRate);
|
||||
return ORBIS_NGS2_ERROR_INVALID_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
int result = ORBIS_OK;
|
||||
|
||||
// TODO
|
||||
|
||||
return result; // Success
|
||||
}
|
||||
|
||||
} // namespace Libraries::Ngs2
|
|
@ -0,0 +1,25 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ngs2.h"
|
||||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
class Ngs2 {
|
||||
public:
|
||||
s32 ReportInvalid(u32 handle_type) const;
|
||||
s32 HandleSetup(Ngs2Handle* handle, void* data, std::atomic<u32>* atomic, u32 type, u32 flags);
|
||||
s32 HandleCleanup(Ngs2Handle* handle, u32 hType, void* dataOut);
|
||||
s32 HandleEnter(Ngs2Handle* handle, u32 hType, Ngs2Handle* handleOut);
|
||||
s32 HandleLeave(Ngs2Handle* handle);
|
||||
s32 StackBufferOpen(StackBuffer* buf, void* base_addr, size_t size, void** stackTop,
|
||||
bool verify);
|
||||
s32 StackBufferClose(StackBuffer* buf, size_t* usedSize);
|
||||
s32 SystemSetupCore(StackBuffer* buf, SystemOptions* options, Ngs2Handle** sysOut);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ngs2
|
|
@ -22,6 +22,7 @@
|
|||
#include "core/libraries/libc/libc.h"
|
||||
#include "core/libraries/libc_internal/libc_internal.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/ngs2/ngs2.h"
|
||||
#include "core/libraries/rtc/rtc.h"
|
||||
#include "core/libraries/videoout/video_out.h"
|
||||
#include "core/linker.h"
|
||||
|
@ -184,7 +185,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||
|
||||
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
||||
constexpr std::array<SysModules, 9> ModulesToLoad{
|
||||
{{"libSceNgs2.sprx", nullptr},
|
||||
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
||||
{"libSceFiber.sprx", nullptr},
|
||||
{"libSceUlt.sprx", nullptr},
|
||||
{"libSceJson.sprx", nullptr},
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QCoreApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QFile>
|
||||
|
@ -53,6 +54,18 @@ public:
|
|||
menu.addAction(&openSfoViewer);
|
||||
menu.addAction(&openTrophyViewer);
|
||||
|
||||
// "Copy" submenu.
|
||||
QMenu* copyMenu = new QMenu("Copy info", widget);
|
||||
QAction* copyName = new QAction("Copy Name", widget);
|
||||
QAction* copySerial = new QAction("Copy Serial", widget);
|
||||
QAction* copyNameAll = new QAction("Copy All", widget);
|
||||
|
||||
copyMenu->addAction(copyName);
|
||||
copyMenu->addAction(copySerial);
|
||||
copyMenu->addAction(copyNameAll);
|
||||
|
||||
menu.addMenu(copyMenu);
|
||||
|
||||
// Show menu.
|
||||
auto selected = menu.exec(global_pos);
|
||||
if (!selected) {
|
||||
|
@ -191,6 +204,27 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the "Copy" actions
|
||||
if (selected == copyName) {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(QString::fromStdString(m_games[itemID].name));
|
||||
}
|
||||
|
||||
if (selected == copySerial) {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(QString::fromStdString(m_games[itemID].serial));
|
||||
}
|
||||
|
||||
if (selected == copyNameAll) {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
QString combinedText = QString("Name:%1 | Serial:%2 | Version:%3 | Size:%4")
|
||||
.arg(QString::fromStdString(m_games[itemID].name))
|
||||
.arg(QString::fromStdString(m_games[itemID].serial))
|
||||
.arg(QString::fromStdString(m_games[itemID].version))
|
||||
.arg(QString::fromStdString(m_games[itemID].size));
|
||||
clipboard->setText(combinedText);
|
||||
}
|
||||
}
|
||||
|
||||
int GetRowIndex(QTreeWidget* treeWidget, QTreeWidgetItem* item) {
|
||||
|
|
|
@ -202,6 +202,11 @@ void MainWindow::CreateConnects() {
|
|||
connect(m_game_list_frame.get(), &QTableWidget::cellDoubleClicked, this,
|
||||
&MainWindow::StartGame);
|
||||
|
||||
connect(ui->configureAct, &QAction::triggered, this, [this]() {
|
||||
auto settingsDialog = new SettingsDialog(m_physical_devices, this);
|
||||
settingsDialog->exec();
|
||||
});
|
||||
|
||||
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
|
||||
auto settingsDialog = new SettingsDialog(m_physical_devices, this);
|
||||
settingsDialog->exec();
|
||||
|
@ -697,7 +702,9 @@ QIcon MainWindow::RecolorIcon(const QIcon& icon, bool isWhite) {
|
|||
|
||||
void MainWindow::SetUiIcons(bool isWhite) {
|
||||
ui->bootInstallPkgAct->setIcon(RecolorIcon(ui->bootInstallPkgAct->icon(), isWhite));
|
||||
ui->bootGameAct->setIcon(RecolorIcon(ui->bootGameAct->icon(), isWhite));
|
||||
ui->exitAct->setIcon(RecolorIcon(ui->exitAct->icon(), isWhite));
|
||||
ui->aboutAct->setIcon(RecolorIcon(ui->aboutAct->icon(), isWhite));
|
||||
ui->setlistModeListAct->setIcon(RecolorIcon(ui->setlistModeListAct->icon(), isWhite));
|
||||
ui->setlistModeGridAct->setIcon(RecolorIcon(ui->setlistModeGridAct->icon(), isWhite));
|
||||
ui->gameInstallPathAct->setIcon(RecolorIcon(ui->gameInstallPathAct->icon(), isWhite));
|
||||
|
@ -711,6 +718,8 @@ void MainWindow::SetUiIcons(bool isWhite) {
|
|||
ui->refreshGameListAct->setIcon(RecolorIcon(ui->refreshGameListAct->icon(), isWhite));
|
||||
ui->menuGame_List_Mode->setIcon(RecolorIcon(ui->menuGame_List_Mode->icon(), isWhite));
|
||||
ui->pkgViewerAct->setIcon(RecolorIcon(ui->pkgViewerAct->icon(), isWhite));
|
||||
ui->configureAct->setIcon(RecolorIcon(ui->configureAct->icon(), isWhite));
|
||||
ui->addElfFolderAct->setIcon(RecolorIcon(ui->addElfFolderAct->icon(), isWhite));
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent* event) {
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
QAction* dumpGameListAct;
|
||||
QAction* pkgViewerAct;
|
||||
QAction* aboutAct;
|
||||
QAction* configureAct;
|
||||
QAction* setThemeDark;
|
||||
QAction* setThemeLight;
|
||||
QAction* setThemeGreen;
|
||||
|
@ -97,8 +98,10 @@ public:
|
|||
bootInstallPkgAct->setIcon(QIcon(":images/file_icon.png"));
|
||||
bootGameAct = new QAction(MainWindow);
|
||||
bootGameAct->setObjectName("bootGameAct");
|
||||
bootGameAct->setIcon(QIcon(":images/play_icon.png"));
|
||||
addElfFolderAct = new QAction(MainWindow);
|
||||
addElfFolderAct->setObjectName("addElfFolderAct");
|
||||
addElfFolderAct->setIcon(QIcon(":images/folder_icon.png"));
|
||||
exitAct = new QAction(MainWindow);
|
||||
exitAct->setObjectName("exitAct");
|
||||
exitAct->setIcon(QIcon(":images/exit_icon.png"));
|
||||
|
@ -143,6 +146,10 @@ public:
|
|||
pkgViewerAct->setIcon(QIcon(":images/file_icon.png"));
|
||||
aboutAct = new QAction(MainWindow);
|
||||
aboutAct->setObjectName("aboutAct");
|
||||
aboutAct->setIcon(QIcon(":images/about_icon.png"));
|
||||
configureAct = new QAction(MainWindow);
|
||||
configureAct->setObjectName("configureAct");
|
||||
configureAct->setIcon(QIcon(":images/settings_icon.png"));
|
||||
setThemeDark = new QAction(MainWindow);
|
||||
setThemeDark->setObjectName("setThemeDark");
|
||||
setThemeDark->setCheckable(true);
|
||||
|
@ -285,6 +292,7 @@ public:
|
|||
menuGame_List_Mode->addAction(setlistModeListAct);
|
||||
menuGame_List_Mode->addAction(setlistModeGridAct);
|
||||
menuGame_List_Mode->addAction(setlistElfAct);
|
||||
menuSettings->addAction(configureAct);
|
||||
menuSettings->addAction(gameInstallPathAct);
|
||||
menuSettings->addAction(menuUtils->menuAction());
|
||||
menuUtils->addAction(dumpGameListAct);
|
||||
|
@ -303,7 +311,8 @@ public:
|
|||
bootInstallPkgAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Install Packages (PKG)", nullptr));
|
||||
bootGameAct->setText(QCoreApplication::translate("MainWindow", "Boot Game", nullptr));
|
||||
aboutAct->setText(QCoreApplication::translate("MainWindow", "About", nullptr));
|
||||
aboutAct->setText(QCoreApplication::translate("MainWindow", "About shadPS4", nullptr));
|
||||
configureAct->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
|
||||
#if QT_CONFIG(tooltip)
|
||||
bootInstallPkgAct->setToolTip(QCoreApplication::translate(
|
||||
"MainWindow", "Install application from a .pkg file", nullptr));
|
||||
|
|
|
@ -1,9 +1,44 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QCompleter>
|
||||
#include "settings_dialog.h"
|
||||
#include "ui_settings_dialog.h"
|
||||
|
||||
QStringList languageNames = {"Arabic",
|
||||
"Czech",
|
||||
"Danish",
|
||||
"Dutch",
|
||||
"English (United Kingdom)",
|
||||
"English (United States)",
|
||||
"Finnish",
|
||||
"French (Canada)",
|
||||
"French (France)",
|
||||
"German",
|
||||
"Greek",
|
||||
"Hungarian",
|
||||
"Indonesian",
|
||||
"Italian",
|
||||
"Japanese",
|
||||
"Korean",
|
||||
"Norwegian",
|
||||
"Polish",
|
||||
"Portuguese (Brazil)",
|
||||
"Portuguese (Portugal)",
|
||||
"Romanian",
|
||||
"Russian",
|
||||
"Simplified Chinese",
|
||||
"Spanish (Latin America)",
|
||||
"Spanish (Spain)",
|
||||
"Swedish",
|
||||
"Thai",
|
||||
"Traditional Chinese",
|
||||
"Turkish",
|
||||
"Vietnamese"};
|
||||
|
||||
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0,
|
||||
9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28};
|
||||
|
||||
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
||||
ui->setupUi(this);
|
||||
|
@ -18,6 +53,12 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||
ui->graphicsAdapterBox->addItem(device);
|
||||
}
|
||||
|
||||
ui->consoleLanguageComboBox->addItems(languageNames);
|
||||
|
||||
QCompleter* completer = new QCompleter(languageNames, this);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
ui->consoleLanguageComboBox->setCompleter(completer);
|
||||
|
||||
LoadValuesFromConfig();
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close);
|
||||
|
@ -44,8 +85,13 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||
connect(ui->userNameLineEdit, &QLineEdit::textChanged, this,
|
||||
[](const QString& text) { Config::setUserName(text.toStdString()); });
|
||||
|
||||
connect(ui->consoleLanguageComboBox, &QComboBox::currentIndexChanged, this,
|
||||
[](int index) { Config::setLanguage(index); });
|
||||
connect(ui->consoleLanguageComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, [this](int index) {
|
||||
if (index >= 0 && index < languageIndexes.size()) {
|
||||
int languageCode = languageIndexes[index];
|
||||
Config::setLanguage(languageCode);
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->fullscreenCheckBox, &QCheckBox::stateChanged, this,
|
||||
[](int val) { Config::setFullscreenMode(val); });
|
||||
|
@ -106,8 +152,11 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||
}
|
||||
|
||||
void SettingsDialog::LoadValuesFromConfig() {
|
||||
ui->consoleLanguageComboBox->setCurrentIndex(Config::GetLanguage());
|
||||
|
||||
ui->consoleLanguageComboBox->setCurrentIndex(
|
||||
std::distance(
|
||||
languageIndexes.begin(),
|
||||
std::find(languageIndexes.begin(), languageIndexes.end(), Config::GetLanguage())) %
|
||||
languageIndexes.size());
|
||||
ui->graphicsAdapterBox->setCurrentIndex(Config::getGpuId() + 1);
|
||||
ui->widthSpinBox->setValue(Config::getScreenWidth());
|
||||
ui->heightSpinBox->setValue(Config::getScreenHeight());
|
||||
|
|
|
@ -113,156 +113,6 @@
|
|||
<layout class="QVBoxLayout" name="settingsLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="consoleLanguageComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Japanese</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>English (United States)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>French (France)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Spanish (Spain)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>German</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Italian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Dutch</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Portuguese (Portugal)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Russian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Korean</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Traditional Chinese</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Simplified Chinese</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Finnish</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Swedish</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Danish</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Norwegian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Polish</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Portuguese (Brazil)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>English (United Kingdom)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Turkish</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Spanish (Latin America)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Arabic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>French (Canada)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Czech</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hungarian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Greek</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Romanian</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Thai</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Vietnamese</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Indonesian</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -12,6 +12,25 @@ std::pair<Id, Id> AtomicArgs(EmitContext& ctx) {
|
|||
return {scope, semantics};
|
||||
}
|
||||
|
||||
Id SharedAtomicU32(EmitContext& ctx, Id offset, Id value,
|
||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
|
||||
const Id shift_id{ctx.ConstU32(2U)};
|
||||
const Id index{ctx.OpShiftRightArithmetic(ctx.U32[1], offset, shift_id)};
|
||||
const Id pointer{ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, index)};
|
||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value);
|
||||
}
|
||||
|
||||
Id BufferAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
|
||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
|
||||
auto& buffer = ctx.buffers[handle];
|
||||
address = ctx.OpIAdd(ctx.U32[1], address, buffer.offset);
|
||||
const Id index = ctx.OpShiftRightLogical(ctx.U32[1], address, ctx.ConstU32(2u));
|
||||
const Id ptr = ctx.OpAccessChain(buffer.pointer_type, buffer.id, ctx.u32_zero_value, index);
|
||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||
return (ctx.*atomic_func)(ctx.U32[1], ptr, scope, semantics, value);
|
||||
}
|
||||
|
||||
Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value,
|
||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
|
||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||
|
@ -21,6 +40,72 @@ Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id va
|
|||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicIAdd);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMax);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMax);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicUMin);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMin);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMin);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMin);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicSMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicUMax);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicInc32(EmitContext&, IR::Inst*, u32, Id, Id) {
|
||||
// TODO
|
||||
UNREACHABLE_MSG("Unsupported BUFFER_ATOMIC opcode: ", IR::Opcode::BufferAtomicInc32);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicDec32(EmitContext&, IR::Inst*, u32, Id, Id) {
|
||||
// TODO
|
||||
UNREACHABLE_MSG("Unsupported BUFFER_ATOMIC opcode: ", IR::Opcode::BufferAtomicDec32);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicAnd);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicOr);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicXor);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicExchange);
|
||||
}
|
||||
|
||||
Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) {
|
||||
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd);
|
||||
}
|
||||
|
|
|
@ -495,6 +495,7 @@ static void EmitStoreBufferFormatF32xN(EmitContext& ctx, u32 handle, Id address,
|
|||
case AmdGpu::DataFormat::Format8_8_8_8:
|
||||
case AmdGpu::DataFormat::Format16:
|
||||
case AmdGpu::DataFormat::Format32:
|
||||
case AmdGpu::DataFormat::Format32_32:
|
||||
case AmdGpu::DataFormat::Format32_32_32_32: {
|
||||
ASSERT(N == AmdGpu::NumComponents(format));
|
||||
|
||||
|
|
|
@ -81,6 +81,17 @@ void EmitStoreBufferFormatF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id
|
|||
void EmitStoreBufferFormatF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
void EmitStoreBufferFormatF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
void EmitStoreBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicSMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicUMin32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicSMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicUMax32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicInc32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicDec32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicAnd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicOr32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitBufferAtomicExchange32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
|
||||
Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp);
|
||||
Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp);
|
||||
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp);
|
||||
|
@ -103,6 +114,11 @@ Id EmitLoadSharedU128(EmitContext& ctx, Id offset);
|
|||
void EmitWriteSharedU32(EmitContext& ctx, Id offset, Id value);
|
||||
void EmitWriteSharedU64(EmitContext& ctx, Id offset, Id value);
|
||||
void EmitWriteSharedU128(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicIAdd32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2);
|
||||
Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3);
|
||||
Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4);
|
||||
|
|
|
@ -25,6 +25,18 @@ void Translator::EmitDataShare(const GcnInst& inst) {
|
|||
return DS_WRITE(32, false, true, inst);
|
||||
case Opcode::DS_WRITE2_B64:
|
||||
return DS_WRITE(64, false, true, inst);
|
||||
case Opcode::DS_ADD_U32:
|
||||
return DS_ADD_U32(inst, false);
|
||||
case Opcode::DS_MIN_U32:
|
||||
return DS_MIN_U32(inst, false);
|
||||
case Opcode::DS_MAX_U32:
|
||||
return DS_MAX_U32(inst, false);
|
||||
case Opcode::DS_ADD_RTN_U32:
|
||||
return DS_ADD_U32(inst, true);
|
||||
case Opcode::DS_MIN_RTN_U32:
|
||||
return DS_MIN_U32(inst, true);
|
||||
case Opcode::DS_MAX_RTN_U32:
|
||||
return DS_MAX_U32(inst, true);
|
||||
default:
|
||||
LogMissingOpcode(inst);
|
||||
}
|
||||
|
@ -110,6 +122,42 @@ void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnI
|
|||
}
|
||||
}
|
||||
|
||||
void Translator::DS_ADD_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
const IR::Value original_val = ir.SharedAtomicIAdd(addr_offset, data);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_MIN_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
const IR::Value original_val = ir.SharedAtomicIMin(addr_offset, data, false);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_MAX_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
const IR::Value original_val = ir.SharedAtomicIMax(addr_offset, data, false);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::S_BARRIER() {
|
||||
ir.Barrier();
|
||||
}
|
||||
|
|
|
@ -187,6 +187,7 @@ public:
|
|||
// Vector Memory
|
||||
void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst);
|
||||
void BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst);
|
||||
void BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst);
|
||||
|
||||
// Vector interpolation
|
||||
void V_INTERP_P2_F32(const GcnInst& inst);
|
||||
|
@ -196,6 +197,9 @@ public:
|
|||
void DS_SWIZZLE_B32(const GcnInst& inst);
|
||||
void DS_READ(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
||||
void DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
||||
void DS_ADD_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_MIN_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_MAX_U32(const GcnInst& inst, bool rtn);
|
||||
void V_READFIRSTLANE_B32(const GcnInst& inst);
|
||||
void V_READLANE_B32(const GcnInst& inst);
|
||||
void V_WRITELANE_B32(const GcnInst& inst);
|
||||
|
|
|
@ -104,6 +104,10 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
|
|||
return BUFFER_STORE_FORMAT(3, false, false, inst);
|
||||
case Opcode::BUFFER_STORE_DWORDX4:
|
||||
return BUFFER_STORE_FORMAT(4, false, false, inst);
|
||||
|
||||
// Buffer atomic operations
|
||||
case Opcode::BUFFER_ATOMIC_ADD:
|
||||
return BUFFER_ATOMIC(AtomicOp::Add, inst);
|
||||
default:
|
||||
LogMissingOpcode(inst);
|
||||
}
|
||||
|
@ -435,6 +439,60 @@ void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_form
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: U64
|
||||
void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
const auto& mubuf = inst.control.mubuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
const IR::VectorReg vdata{inst.src[1].code};
|
||||
const IR::ScalarReg srsrc{inst.src[2].code * 4};
|
||||
const IR::U32 soffset{GetSrc(inst.src[3])};
|
||||
ASSERT_MSG(soffset.IsImmediate() && soffset.U32() == 0, "Non immediate offset not supported");
|
||||
|
||||
IR::BufferInstInfo info{};
|
||||
info.index_enable.Assign(mubuf.idxen);
|
||||
info.inst_offset.Assign(mubuf.offset);
|
||||
info.offset_enable.Assign(mubuf.offen);
|
||||
|
||||
IR::Value vdata_val = ir.GetVectorReg<Shader::IR::U32>(vdata);
|
||||
const IR::U32 address = ir.GetVectorReg(vaddr);
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(srsrc), ir.GetScalarReg(srsrc + 1),
|
||||
ir.GetScalarReg(srsrc + 2), ir.GetScalarReg(srsrc + 3));
|
||||
|
||||
const IR::Value original_val = [&] {
|
||||
switch (op) {
|
||||
case AtomicOp::Swap:
|
||||
return ir.BufferAtomicExchange(handle, address, vdata_val, info);
|
||||
case AtomicOp::Add:
|
||||
return ir.BufferAtomicIAdd(handle, address, vdata_val, info);
|
||||
case AtomicOp::Smin:
|
||||
return ir.BufferAtomicIMin(handle, address, vdata_val, true, info);
|
||||
case AtomicOp::Umin:
|
||||
return ir.BufferAtomicIMin(handle, address, vdata_val, false, info);
|
||||
case AtomicOp::Smax:
|
||||
return ir.BufferAtomicIMax(handle, address, vdata_val, true, info);
|
||||
case AtomicOp::Umax:
|
||||
return ir.BufferAtomicIMax(handle, address, vdata_val, false, info);
|
||||
case AtomicOp::And:
|
||||
return ir.BufferAtomicAnd(handle, address, vdata_val, info);
|
||||
case AtomicOp::Or:
|
||||
return ir.BufferAtomicOr(handle, address, vdata_val, info);
|
||||
case AtomicOp::Xor:
|
||||
return ir.BufferAtomicXor(handle, address, vdata_val, info);
|
||||
case AtomicOp::Inc:
|
||||
return ir.BufferAtomicInc(handle, address, vdata_val, info);
|
||||
case AtomicOp::Dec:
|
||||
return ir.BufferAtomicDec(handle, address, vdata_val, info);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}();
|
||||
|
||||
if (mubuf.glc) {
|
||||
ir.SetVectorReg(vdata, IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::IMAGE_GET_LOD(const GcnInst& inst) {
|
||||
const auto& mimg = inst.control.mimg;
|
||||
IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
|
|
|
@ -286,6 +286,25 @@ void IREmitter::WriteShared(int bit_size, const Value& value, const U32& offset)
|
|||
}
|
||||
}
|
||||
|
||||
U32F32 IREmitter::SharedAtomicIAdd(const U32& address, const U32F32& data) {
|
||||
switch (data.Type()) {
|
||||
case Type::U32:
|
||||
return Inst<U32>(Opcode::SharedAtomicIAdd32, address, data);
|
||||
default:
|
||||
ThrowInvalidType(data.Type());
|
||||
}
|
||||
}
|
||||
|
||||
U32 IREmitter::SharedAtomicIMin(const U32& address, const U32& data, bool is_signed) {
|
||||
return is_signed ? Inst<U32>(Opcode::SharedAtomicSMin32, address, data)
|
||||
: Inst<U32>(Opcode::SharedAtomicUMin32, address, data);
|
||||
}
|
||||
|
||||
U32 IREmitter::SharedAtomicIMax(const U32& address, const U32& data, bool is_signed) {
|
||||
return is_signed ? Inst<U32>(Opcode::SharedAtomicSMax32, address, data)
|
||||
: Inst<U32>(Opcode::SharedAtomicUMax32, address, data);
|
||||
}
|
||||
|
||||
U32 IREmitter::ReadConst(const Value& base, const U32& offset) {
|
||||
return Inst<U32>(Opcode::ReadConst, base, offset);
|
||||
}
|
||||
|
@ -347,6 +366,53 @@ void IREmitter::StoreBuffer(int num_dwords, const Value& handle, const Value& ad
|
|||
}
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicIAdd(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicIAdd32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicIMin(const Value& handle, const Value& address, const Value& value,
|
||||
bool is_signed, BufferInstInfo info) {
|
||||
return is_signed ? Inst(Opcode::BufferAtomicSMin32, Flags{info}, handle, address, value)
|
||||
: Inst(Opcode::BufferAtomicUMin32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicIMax(const Value& handle, const Value& address, const Value& value,
|
||||
bool is_signed, BufferInstInfo info) {
|
||||
return is_signed ? Inst(Opcode::BufferAtomicSMax32, Flags{info}, handle, address, value)
|
||||
: Inst(Opcode::BufferAtomicUMax32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicInc(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicInc32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicDec(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicDec32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicAnd(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicAnd32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicOr(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicOr32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicXor(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicXor32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
Value IREmitter::BufferAtomicExchange(const Value& handle, const Value& address, const Value& value,
|
||||
BufferInstInfo info) {
|
||||
return Inst(Opcode::BufferAtomicExchange32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
void IREmitter::StoreBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
const Value& data, BufferInstInfo info) {
|
||||
switch (num_dwords) {
|
||||
|
|
|
@ -84,6 +84,10 @@ public:
|
|||
[[nodiscard]] Value LoadShared(int bit_size, bool is_signed, const U32& offset);
|
||||
void WriteShared(int bit_size, const Value& value, const U32& offset);
|
||||
|
||||
[[nodiscard]] U32F32 SharedAtomicIAdd(const U32& address, const U32F32& data);
|
||||
[[nodiscard]] U32 SharedAtomicIMin(const U32& address, const U32& data, bool is_signed);
|
||||
[[nodiscard]] U32 SharedAtomicIMax(const U32& address, const U32& data, bool is_signed);
|
||||
|
||||
[[nodiscard]] U32 ReadConst(const Value& base, const U32& offset);
|
||||
[[nodiscard]] F32 ReadConstBuffer(const Value& handle, const U32& index);
|
||||
|
||||
|
@ -96,6 +100,25 @@ public:
|
|||
void StoreBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
const Value& data, BufferInstInfo info);
|
||||
|
||||
[[nodiscard]] Value BufferAtomicIAdd(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicIMin(const Value& handle, const Value& address,
|
||||
const Value& value, bool is_signed, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicIMax(const Value& handle, const Value& address,
|
||||
const Value& value, bool is_signed, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicInc(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicDec(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicAnd(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicOr(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicXor(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
[[nodiscard]] Value BufferAtomicExchange(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
|
||||
[[nodiscard]] U32 LaneId();
|
||||
[[nodiscard]] U32 WarpId();
|
||||
[[nodiscard]] U32 QuadShuffle(const U32& value, const U32& index);
|
||||
|
|
|
@ -60,9 +60,25 @@ bool Inst::MayHaveSideEffects() const noexcept {
|
|||
case Opcode::StoreBufferFormatF32x3:
|
||||
case Opcode::StoreBufferFormatF32x4:
|
||||
case Opcode::StoreBufferU32:
|
||||
case Opcode::BufferAtomicIAdd32:
|
||||
case Opcode::BufferAtomicSMin32:
|
||||
case Opcode::BufferAtomicUMin32:
|
||||
case Opcode::BufferAtomicSMax32:
|
||||
case Opcode::BufferAtomicUMax32:
|
||||
case Opcode::BufferAtomicInc32:
|
||||
case Opcode::BufferAtomicDec32:
|
||||
case Opcode::BufferAtomicAnd32:
|
||||
case Opcode::BufferAtomicOr32:
|
||||
case Opcode::BufferAtomicXor32:
|
||||
case Opcode::BufferAtomicExchange32:
|
||||
case Opcode::WriteSharedU128:
|
||||
case Opcode::WriteSharedU64:
|
||||
case Opcode::WriteSharedU32:
|
||||
case Opcode::SharedAtomicIAdd32:
|
||||
case Opcode::SharedAtomicSMin32:
|
||||
case Opcode::SharedAtomicUMin32:
|
||||
case Opcode::SharedAtomicSMax32:
|
||||
case Opcode::SharedAtomicUMax32:
|
||||
case Opcode::ImageWrite:
|
||||
case Opcode::ImageAtomicIAdd32:
|
||||
case Opcode::ImageAtomicSMin32:
|
||||
|
|
|
@ -33,6 +33,13 @@ OPCODE(WriteSharedU32, Void, U32,
|
|||
OPCODE(WriteSharedU64, Void, U32, U32x2, )
|
||||
OPCODE(WriteSharedU128, Void, U32, U32x4, )
|
||||
|
||||
// Shared atomic operations
|
||||
OPCODE(SharedAtomicIAdd32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicSMin32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicUMin32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicSMax32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicUMax32, U32, U32, U32, )
|
||||
|
||||
// Context getters/setters
|
||||
OPCODE(GetUserData, U32, ScalarReg, )
|
||||
OPCODE(GetThreadBitScalarReg, U1, ScalarReg, )
|
||||
|
@ -88,6 +95,19 @@ OPCODE(StoreBufferFormatF32x3, Void, Opaq
|
|||
OPCODE(StoreBufferFormatF32x4, Void, Opaque, Opaque, F32x4, )
|
||||
OPCODE(StoreBufferU32, Void, Opaque, Opaque, U32, )
|
||||
|
||||
// Buffer atomic operations
|
||||
OPCODE(BufferAtomicIAdd32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicSMin32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicUMin32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicSMax32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicUMax32, U32, Opaque, Opaque, U32 )
|
||||
OPCODE(BufferAtomicInc32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(BufferAtomicDec32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(BufferAtomicAnd32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(BufferAtomicOr32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, )
|
||||
OPCODE(BufferAtomicExchange32, U32, Opaque, Opaque, U32, )
|
||||
|
||||
// Vector utility
|
||||
OPCODE(CompositeConstructU32x2, U32x2, U32, U32, )
|
||||
OPCODE(CompositeConstructU32x3, U32x3, U32, U32, U32, )
|
||||
|
|
|
@ -20,6 +20,42 @@ struct SharpLocation {
|
|||
auto operator<=>(const SharpLocation&) const = default;
|
||||
};
|
||||
|
||||
bool IsBufferAtomic(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::BufferAtomicIAdd32:
|
||||
case IR::Opcode::BufferAtomicSMin32:
|
||||
case IR::Opcode::BufferAtomicUMin32:
|
||||
case IR::Opcode::BufferAtomicSMax32:
|
||||
case IR::Opcode::BufferAtomicUMax32:
|
||||
case IR::Opcode::BufferAtomicInc32:
|
||||
case IR::Opcode::BufferAtomicDec32:
|
||||
case IR::Opcode::BufferAtomicAnd32:
|
||||
case IR::Opcode::BufferAtomicOr32:
|
||||
case IR::Opcode::BufferAtomicXor32:
|
||||
case IR::Opcode::BufferAtomicExchange32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBufferStore(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::StoreBufferF32:
|
||||
case IR::Opcode::StoreBufferF32x2:
|
||||
case IR::Opcode::StoreBufferF32x3:
|
||||
case IR::Opcode::StoreBufferF32x4:
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
case IR::Opcode::StoreBufferFormatF32x2:
|
||||
case IR::Opcode::StoreBufferFormatF32x3:
|
||||
case IR::Opcode::StoreBufferFormatF32x4:
|
||||
case IR::Opcode::StoreBufferU32:
|
||||
return true;
|
||||
default:
|
||||
return IsBufferAtomic(inst);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBufferInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::LoadBufferF32:
|
||||
|
@ -33,18 +69,9 @@ bool IsBufferInstruction(const IR::Inst& inst) {
|
|||
case IR::Opcode::LoadBufferU32:
|
||||
case IR::Opcode::ReadConstBuffer:
|
||||
case IR::Opcode::ReadConstBufferU32:
|
||||
case IR::Opcode::StoreBufferF32:
|
||||
case IR::Opcode::StoreBufferF32x2:
|
||||
case IR::Opcode::StoreBufferF32x3:
|
||||
case IR::Opcode::StoreBufferF32x4:
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
case IR::Opcode::StoreBufferFormatF32x2:
|
||||
case IR::Opcode::StoreBufferFormatF32x3:
|
||||
case IR::Opcode::StoreBufferFormatF32x4:
|
||||
case IR::Opcode::StoreBufferU32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return IsBufferStore(inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,29 +135,13 @@ IR::Type BufferDataType(const IR::Inst& inst, AmdGpu::NumberFormat num_format) {
|
|||
case IR::Opcode::LoadBufferU32:
|
||||
case IR::Opcode::ReadConstBufferU32:
|
||||
case IR::Opcode::StoreBufferU32:
|
||||
case IR::Opcode::BufferAtomicIAdd32:
|
||||
return IR::Type::U32;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBufferStore(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::StoreBufferF32:
|
||||
case IR::Opcode::StoreBufferF32x2:
|
||||
case IR::Opcode::StoreBufferF32x3:
|
||||
case IR::Opcode::StoreBufferF32x4:
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
case IR::Opcode::StoreBufferFormatF32x2:
|
||||
case IR::Opcode::StoreBufferFormatF32x3:
|
||||
case IR::Opcode::StoreBufferFormatF32x4:
|
||||
case IR::Opcode::StoreBufferU32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsImageInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageSampleExplicitLod:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>images/shadps4.ico</file>
|
||||
<file>images/about_icon.png</file>
|
||||
<file>images/play_icon.png</file>
|
||||
<file>images/pause_icon.png</file>
|
||||
<file>images/stop_icon.png</file>
|
||||
|
|
|
@ -452,7 +452,7 @@ struct Liverpool {
|
|||
BitField<11, 1, u32> enable_polygon_offset_front;
|
||||
BitField<12, 1, u32> enable_polygon_offset_back;
|
||||
BitField<13, 1, u32> enable_polygon_offset_para;
|
||||
BitField<13, 1, u32> enable_window_offset;
|
||||
BitField<16, 1, u32> enable_window_offset;
|
||||
BitField<19, 1, ProvokingVtxLast> provoking_vtx_last;
|
||||
|
||||
PolygonMode PolyMode() const {
|
||||
|
|
|
@ -172,10 +172,18 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
|||
.reference = key.stencil_ref_front.stencil_test_val,
|
||||
},
|
||||
.back{
|
||||
.failOp = LiverpoolToVK::StencilOp(key.stencil.stencil_fail_back),
|
||||
.passOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zpass_back),
|
||||
.depthFailOp = LiverpoolToVK::StencilOp(key.stencil.stencil_zfail_back),
|
||||
.compareOp = LiverpoolToVK::CompareOp(key.depth.stencil_bf_func),
|
||||
.failOp = LiverpoolToVK::StencilOp(key.depth.backface_enable
|
||||
? key.stencil.stencil_fail_back.Value()
|
||||
: key.stencil.stencil_fail_front.Value()),
|
||||
.passOp = LiverpoolToVK::StencilOp(key.depth.backface_enable
|
||||
? key.stencil.stencil_zpass_back.Value()
|
||||
: key.stencil.stencil_zpass_front.Value()),
|
||||
.depthFailOp = LiverpoolToVK::StencilOp(key.depth.backface_enable
|
||||
? key.stencil.stencil_zfail_back.Value()
|
||||
: key.stencil.stencil_zfail_front.Value()),
|
||||
.compareOp = LiverpoolToVK::CompareOp(key.depth.backface_enable
|
||||
? key.depth.stencil_bf_func.Value()
|
||||
: key.depth.stencil_ref_func.Value()),
|
||||
.compareMask = key.stencil_ref_back.stencil_mask,
|
||||
.writeMask = key.stencil_ref_back.stencil_write_mask,
|
||||
.reference = key.stencil_ref_back.stencil_test_val,
|
||||
|
@ -207,7 +215,8 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
|||
.colorAttachmentCount = num_color_formats,
|
||||
.pColorAttachmentFormats = key.color_formats.data(),
|
||||
.depthAttachmentFormat = key.depth_format,
|
||||
.stencilAttachmentFormat = vk::Format::eUndefined,
|
||||
.stencilAttachmentFormat =
|
||||
key.depth.stencil_enable ? key.depth_format : vk::Format::eUndefined,
|
||||
};
|
||||
|
||||
std::array<vk::PipelineColorBlendAttachmentState, Liverpool::NumColorBuffers> attachments;
|
||||
|
|
|
@ -39,6 +39,7 @@ void Scheduler::BeginRendering(const RenderState& new_state) {
|
|||
.colorAttachmentCount = render_state.num_color_attachments,
|
||||
.pColorAttachments = render_state.color_attachments.data(),
|
||||
.pDepthAttachment = render_state.has_depth ? &render_state.depth_attachment : nullptr,
|
||||
.pStencilAttachment = render_state.has_stencil ? &render_state.depth_attachment : nullptr,
|
||||
};
|
||||
|
||||
current_cmdbuf.beginRendering(rendering_info);
|
||||
|
|
Loading…
Reference in New Issue