diff --git a/src/audio_core/renderer/command/command_buffer.cpp b/src/audio_core/renderer/command/command_buffer.cpp index 09d28003e..d0442bada 100644 --- a/src/audio_core/renderer/command/command_buffer.cpp +++ b/src/audio_core/renderer/command/command_buffer.cpp @@ -254,6 +254,51 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas const s16 buffer_offset, const s8 channel, const bool needs_init, const bool use_float_processing) { + + if (behavior->IsEffectInfoVersion2Supported()) { + const auto& parameter_v2{ + *reinterpret_cast(effect_info.GetParameter())}; + + if (!IsChannelCountValid(static_cast(parameter_v2.channel_count)) || channel < 0 || + channel >= parameter_v2.channel_count) { + return; + } + + if (!parameter_v2.enable) { + GenerateCopyMixBufferCommand(node_id, effect_info, buffer_offset, channel); + return; + } + + const s16 input_index = buffer_offset + parameter_v2.inputs[channel]; + const s16 output_index = buffer_offset + parameter_v2.outputs[channel]; + + if (input_index < 0) { + return; + } + + s16 effective_output = output_index; + if (output_index < 0) { + effective_output = input_index; + } + + auto& cmd{GenerateStart(node_id)}; + + const auto state{reinterpret_cast( + effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))}; + + cmd.input = input_index; + cmd.output = effective_output; + cmd.biquad_float.numerator = parameter_v2.b; + cmd.biquad_float.denominator = parameter_v2.a; + cmd.use_float_coefficients = true; + cmd.state = memory_pool->Translate(CpuAddr(state), sizeof(VoiceState::BiquadFilterState)); + cmd.needs_init = needs_init; + cmd.use_float_processing = use_float_processing; + + GenerateEnd(cmd); + return; + } + auto& cmd{GenerateStart(node_id)}; const auto& parameter{ @@ -590,6 +635,17 @@ void CommandBuffer::GenerateClearMixCommand(const s32 node_id) { void CommandBuffer::GenerateCopyMixBufferCommand(const s32 node_id, EffectInfoBase& effect_info, const s16 buffer_offset, const s8 channel) { + + if (behavior->IsEffectInfoVersion2Supported()) { + auto& cmd{GenerateStart(node_id)}; + const auto& parameter_v2{ + *reinterpret_cast(effect_info.GetParameter())}; + cmd.input_index = buffer_offset + parameter_v2.inputs[channel]; + cmd.output_index = buffer_offset + parameter_v2.outputs[channel]; + GenerateEnd(cmd); + return; + } + auto& cmd{GenerateStart(node_id)}; const auto& parameter{ diff --git a/src/audio_core/renderer/command/command_generator.cpp b/src/audio_core/renderer/command/command_generator.cpp index f97db5899..ff3b6828d 100644 --- a/src/audio_core/renderer/command/command_generator.cpp +++ b/src/audio_core/renderer/command/command_generator.cpp @@ -361,6 +361,27 @@ void CommandGenerator::GenerateAuxCommand(const s16 buffer_offset, EffectInfoBas void CommandGenerator::GenerateBiquadFilterEffectCommand(const s16 buffer_offset, EffectInfoBase& effect_info, const s32 node_id) { + + if (render_context.behavior->IsEffectInfoVersion2Supported()) { + const auto& parameter_v2{ + *reinterpret_cast(effect_info.GetParameter())}; + const bool needs_init = false; + const bool use_float_processing = render_context.behavior->UseBiquadFilterFloatProcessing(); + const s8 channels = parameter_v2.channel_count > 0 ? parameter_v2.channel_count : 2; + if (effect_info.IsEnabled()) { + for (s8 channel = 0; channel < channels; channel++) { + command_buffer.GenerateBiquadFilterCommand( + node_id, effect_info, buffer_offset, channel, needs_init, use_float_processing); + } + } else { + for (s8 channel = 0; channel < channels; channel++) { + command_buffer.GenerateCopyMixBufferCommand(node_id, effect_info, buffer_offset, + channel); + } + } + return; + } + const auto& parameter{ *reinterpret_cast(effect_info.GetParameter())}; if (effect_info.IsEnabled()) { diff --git a/src/audio_core/renderer/effect/biquad_filter.h b/src/audio_core/renderer/effect/biquad_filter.h index 5a22899ab..382c0c766 100644 --- a/src/audio_core/renderer/effect/biquad_filter.h +++ b/src/audio_core/renderer/effect/biquad_filter.h @@ -25,12 +25,12 @@ public: "BiquadFilterInfo::ParameterVersion1 has the wrong size!"); struct ParameterVersion2 { - /* 0x00 */ std::array inputs; - /* 0x06 */ std::array outputs; - /* 0x0C */ std::array b; - /* 0x12 */ std::array a; - /* 0x16 */ s8 channel_count; - /* 0x17 */ ParameterState state; + bool enable; + s8 channel_count; + s8 inputs[MaxChannels]; + s8 outputs[MaxChannels]; + std::array b; + std::array a; }; static_assert(sizeof(ParameterVersion2) <= sizeof(EffectInfoBase::InParameterVersion2), "BiquadFilterInfo::ParameterVersion2 has the wrong size!"); 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 0f9bb5490..e0b17b0bd 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -44,6 +44,8 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span return WrapFixed(this, &nvhost_ctrl_gpu::GetTPCMasks1, input, output); case 0x7: return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output); + case 0x13: + return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuLoad, input, output); case 0x14: return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output); case 0x1c: @@ -74,6 +76,8 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span case 0x6: return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output, inline_output); + case 0x13: + return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuLoad, input, output); default: break; } @@ -247,6 +251,13 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) { return NvResult::Success; } +NvResult nvhost_ctrl_gpu::GetGpuLoad(IoctlGetGpuLoad& params) { + LOG_DEBUG(Service_NVDRV, "called"); + params.load = 0; + params.padding = 0; + return NvResult::Success; +} + Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) { switch (event_id) { case 1: 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 d2ab05b21..f3de6fedf 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -151,6 +151,12 @@ private: }; static_assert(sizeof(IoctlGetGpuTime) == 0x10, "IoctlGetGpuTime is incorrect size"); + struct IoctlGetGpuLoad { + u32_le load; + u32_le padding; + }; + static_assert(sizeof(IoctlGetGpuLoad) == 8, "IoctlGetGpuLoad is incorrect size"); + NvResult GetCharacteristics1(IoctlCharacteristics& params); NvResult GetCharacteristics3(IoctlCharacteristics& params, std::span gpu_characteristics); @@ -165,6 +171,7 @@ private: NvResult ZBCQueryTable(IoctlZbcQueryTable& params); NvResult FlushL2(IoctlFlushL2& params); NvResult GetGpuTime(IoctlGetGpuTime& params); + NvResult GetGpuLoad(IoctlGetGpuLoad& params); EventInterface& events_interface;