diff options
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 65 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.h | 25 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | 11 |
4 files changed, 110 insertions, 2 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 38bc65d95..6e8002bc9 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/alignment.h" #include "common/logging/log.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" @@ -256,12 +257,62 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { } void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto params = rp.PopRaw<WorkerBufferParameters>(); + + u64 buffer_sz = Common::AlignUp(4 * params.unknown8, 0x40); + buffer_sz += params.unknownC * 1024; + buffer_sz += 0x940 * (params.unknownC + 1); + buffer_sz += 0x3F0 * params.voice_count; + buffer_sz += Common::AlignUp(8 * (params.unknownC + 1), 0x10); + buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10); + buffer_sz += + Common::AlignUp((0x3C0 * (params.sink_count + params.unknownC) + 4 * params.sample_count) * + (params.unknown8 + 6), + 0x40); + + if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { + u32 count = params.unknownC + 1; + u64 node_count = Common::AlignUp(count, 0x40); + u64 node_state_buffer_sz = + 4 * (node_count * node_count) + 0xC * node_count + 2 * (node_count / 8); + u64 edge_matrix_buffer_sz = 0; + node_count = Common::AlignUp(count * count, 0x40); + if (node_count >> 31 != 0) { + edge_matrix_buffer_sz = (node_count | 7) / 8; + } else { + edge_matrix_buffer_sz = node_count / 8; + } + buffer_sz += Common::AlignUp(node_state_buffer_sz + edge_matrix_buffer_sz, 0x10); + } + + buffer_sz += 0x20 * (params.effect_count + 4 * params.voice_count) + 0x50; + if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { + buffer_sz += 0xE0 * params.unknown2c; + buffer_sz += 0x20 * params.splitter_count; + buffer_sz += Common::AlignUp(4 * params.unknown2c, 0x10); + } + buffer_sz = Common::AlignUp(buffer_sz, 0x40) + 0x170 * params.sink_count; + u64 output_sz = buffer_sz + 0x280 * params.sink_count + 0x4B0 * params.effect_count + + ((params.voice_count * 256) | 0x40); + + if (params.unknown1c >= 1) { + output_sz = Common::AlignUp(((16 * params.sink_count + 16 * params.effect_count + + 16 * params.voice_count + 16) + + 0x658) * + (params.unknown1c + 1) + + 0xc0, + 0x40) + + output_sz; + } + output_sz = Common::AlignUp(output_sz + 0x1807e, 0x1000); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push<u64>(0x4000); + rb.Push<u64>(output_sz); - NGLOG_WARNING(Service_Audio, "(STUBBED) called"); + NGLOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz); } void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { @@ -273,4 +324,14 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { NGLOG_DEBUG(Service_Audio, "called"); } +bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { + u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap + switch (feature) { + case AudioFeatures::Splitter: + return version_num >= 2; + default: + return false; + } +} + } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index 71b632e80..fe53de4ce 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -21,6 +21,31 @@ private: void OpenAudioRenderer(Kernel::HLERequestContext& ctx); void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); void GetAudioDevice(Kernel::HLERequestContext& ctx); + + struct WorkerBufferParameters { + u32_le sample_rate; + u32_le sample_count; + u32_le unknown8; + u32_le unknownC; + u32_le voice_count; + u32_le sink_count; + u32_le effect_count; + u32_le unknown1c; + u8 unknown20; + u8 padding1[3]; + u32_le splitter_count; + u32_le unknown2c; + u8 padding2[4]; + u32_le magic; + }; + static_assert(sizeof(WorkerBufferParameters) == 52, + "WorkerBufferParameters is an invalid size"); + + enum class AudioFeatures : u32 { + Splitter, + }; + + bool IsFeatureSupported(AudioFeatures feature, u32_le revision) const; }; } // namespace Service::Audio diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index be6b88f98..a9538ff43 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -24,6 +24,8 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec return ZCullGetCtxSize(input, output); case IoctlCommand::IocZcullGetInfo: return ZCullGetInfo(input, output); + case IoctlCommand::IocZbcSetTable: + return ZBCSetTable(input, output); } UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; @@ -125,4 +127,13 @@ u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& return 0; } +u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output) { + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); + IoctlZbcSetTable params{}; + std::memcpy(¶ms, input.data(), input.size()); + // TODO(ogniK): What does this even actually do? + std::memcpy(output.data(), ¶ms, output.size()); + return 0; +} + } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index 2d43598b1..1d5ba2e67 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -25,6 +25,7 @@ private: IocGetActiveSlotMaskCommand = 0x80084714, IocZcullGetCtxSizeCommand = 0x80044701, IocZcullGetInfo = 0x80284702, + IocZbcSetTable = 0x402C4703, }; struct IoctlGpuCharacteristics { @@ -117,11 +118,21 @@ private: static_assert(sizeof(IoctlNvgpuGpuZcullGetInfoArgs) == 40, "IoctlNvgpuGpuZcullGetInfoArgs is incorrect size"); + struct IoctlZbcSetTable { + u32_le color_ds[4]; + u32_le color_l2[4]; + u32_le depth; + u32_le format; + u32_le type; + }; + static_assert(sizeof(IoctlZbcSetTable) == 44, "IoctlZbcSetTable is incorrect size"); + u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output); u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output); u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output); u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output); u32 ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output); + u32 ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output); }; } // namespace Service::Nvidia::Devices |