diff options
| author | 2018-05-25 19:30:02 -0700 | |
|---|---|---|
| committer | 2018-05-25 22:30:02 -0400 | |
| commit | e6df4b37dbceff098e3292bb7bf604c57374a805 (patch) | |
| tree | 999aaa55a8a9161b314c6ff9409708ede1af178e /src | |
| parent | Merge pull request #468 from Subv/compound_preds (diff) | |
| download | yuzu-e6df4b37dbceff098e3292bb7bf604c57374a805.tar.gz yuzu-e6df4b37dbceff098e3292bb7bf604c57374a805.tar.xz yuzu-e6df4b37dbceff098e3292bb7bf604c57374a805.zip | |
GetAudioRendererWorkBufferSize impl (#465)
* GetAudioRendererWorkBufferSize impl
Impl of GetAudioRendererWorkBufferSize based on RE, if this can be cleaned up, please contribute!
* Naming conventions
* Removed unneeded placeholder
* lioncache changes
* fixed const
* switched to Common::AlignUp
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 65 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.h | 25 |
2 files changed, 88 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 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/alignment.h" | ||
| 5 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 6 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 7 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| @@ -256,12 +257,62 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | |||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { | 259 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { |
| 260 | IPC::RequestParser rp{ctx}; | ||
| 261 | auto params = rp.PopRaw<WorkerBufferParameters>(); | ||
| 262 | |||
| 263 | u64 buffer_sz = Common::AlignUp(4 * params.unknown8, 0x40); | ||
| 264 | buffer_sz += params.unknownC * 1024; | ||
| 265 | buffer_sz += 0x940 * (params.unknownC + 1); | ||
| 266 | buffer_sz += 0x3F0 * params.voice_count; | ||
| 267 | buffer_sz += Common::AlignUp(8 * (params.unknownC + 1), 0x10); | ||
| 268 | buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10); | ||
| 269 | buffer_sz += | ||
| 270 | Common::AlignUp((0x3C0 * (params.sink_count + params.unknownC) + 4 * params.sample_count) * | ||
| 271 | (params.unknown8 + 6), | ||
| 272 | 0x40); | ||
| 273 | |||
| 274 | if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { | ||
| 275 | u32 count = params.unknownC + 1; | ||
| 276 | u64 node_count = Common::AlignUp(count, 0x40); | ||
| 277 | u64 node_state_buffer_sz = | ||
| 278 | 4 * (node_count * node_count) + 0xC * node_count + 2 * (node_count / 8); | ||
| 279 | u64 edge_matrix_buffer_sz = 0; | ||
| 280 | node_count = Common::AlignUp(count * count, 0x40); | ||
| 281 | if (node_count >> 31 != 0) { | ||
| 282 | edge_matrix_buffer_sz = (node_count | 7) / 8; | ||
| 283 | } else { | ||
| 284 | edge_matrix_buffer_sz = node_count / 8; | ||
| 285 | } | ||
| 286 | buffer_sz += Common::AlignUp(node_state_buffer_sz + edge_matrix_buffer_sz, 0x10); | ||
| 287 | } | ||
| 288 | |||
| 289 | buffer_sz += 0x20 * (params.effect_count + 4 * params.voice_count) + 0x50; | ||
| 290 | if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { | ||
| 291 | buffer_sz += 0xE0 * params.unknown2c; | ||
| 292 | buffer_sz += 0x20 * params.splitter_count; | ||
| 293 | buffer_sz += Common::AlignUp(4 * params.unknown2c, 0x10); | ||
| 294 | } | ||
| 295 | buffer_sz = Common::AlignUp(buffer_sz, 0x40) + 0x170 * params.sink_count; | ||
| 296 | u64 output_sz = buffer_sz + 0x280 * params.sink_count + 0x4B0 * params.effect_count + | ||
| 297 | ((params.voice_count * 256) | 0x40); | ||
| 298 | |||
| 299 | if (params.unknown1c >= 1) { | ||
| 300 | output_sz = Common::AlignUp(((16 * params.sink_count + 16 * params.effect_count + | ||
| 301 | 16 * params.voice_count + 16) + | ||
| 302 | 0x658) * | ||
| 303 | (params.unknown1c + 1) + | ||
| 304 | 0xc0, | ||
| 305 | 0x40) + | ||
| 306 | output_sz; | ||
| 307 | } | ||
| 308 | output_sz = Common::AlignUp(output_sz + 0x1807e, 0x1000); | ||
| 309 | |||
| 259 | IPC::ResponseBuilder rb{ctx, 4}; | 310 | IPC::ResponseBuilder rb{ctx, 4}; |
| 260 | 311 | ||
| 261 | rb.Push(RESULT_SUCCESS); | 312 | rb.Push(RESULT_SUCCESS); |
| 262 | rb.Push<u64>(0x4000); | 313 | rb.Push<u64>(output_sz); |
| 263 | 314 | ||
| 264 | NGLOG_WARNING(Service_Audio, "(STUBBED) called"); | 315 | NGLOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz); |
| 265 | } | 316 | } |
| 266 | 317 | ||
| 267 | void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { | 318 | void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { |
| @@ -273,4 +324,14 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) { | |||
| 273 | NGLOG_DEBUG(Service_Audio, "called"); | 324 | NGLOG_DEBUG(Service_Audio, "called"); |
| 274 | } | 325 | } |
| 275 | 326 | ||
| 327 | bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const { | ||
| 328 | u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap | ||
| 329 | switch (feature) { | ||
| 330 | case AudioFeatures::Splitter: | ||
| 331 | return version_num >= 2; | ||
| 332 | default: | ||
| 333 | return false; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 276 | } // namespace Service::Audio | 337 | } // 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: | |||
| 21 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); | 21 | void OpenAudioRenderer(Kernel::HLERequestContext& ctx); |
| 22 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); | 22 | void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx); |
| 23 | void GetAudioDevice(Kernel::HLERequestContext& ctx); | 23 | void GetAudioDevice(Kernel::HLERequestContext& ctx); |
| 24 | |||
| 25 | struct WorkerBufferParameters { | ||
| 26 | u32_le sample_rate; | ||
| 27 | u32_le sample_count; | ||
| 28 | u32_le unknown8; | ||
| 29 | u32_le unknownC; | ||
| 30 | u32_le voice_count; | ||
| 31 | u32_le sink_count; | ||
| 32 | u32_le effect_count; | ||
| 33 | u32_le unknown1c; | ||
| 34 | u8 unknown20; | ||
| 35 | u8 padding1[3]; | ||
| 36 | u32_le splitter_count; | ||
| 37 | u32_le unknown2c; | ||
| 38 | u8 padding2[4]; | ||
| 39 | u32_le magic; | ||
| 40 | }; | ||
| 41 | static_assert(sizeof(WorkerBufferParameters) == 52, | ||
| 42 | "WorkerBufferParameters is an invalid size"); | ||
| 43 | |||
| 44 | enum class AudioFeatures : u32 { | ||
| 45 | Splitter, | ||
| 46 | }; | ||
| 47 | |||
| 48 | bool IsFeatureSupported(AudioFeatures feature, u32_le revision) const; | ||
| 24 | }; | 49 | }; |
| 25 | 50 | ||
| 26 | } // namespace Service::Audio | 51 | } // namespace Service::Audio |