yuzu/src/audio_core/renderer/behavior/behavior_info.h

377 lines
11 KiB
C++

// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <span>
#include "audio_core/common/common.h"
#include "common/common_types.h"
#include "core/hle/service/audio/errors.h"
namespace AudioCore::AudioRenderer {
/**
* Holds host and user revisions, checks whether render features can be enabled, and reports errors.
*/
class BehaviorInfo {
static constexpr u32 MaxErrors = 10;
public:
struct ErrorInfo {
/* 0x00 */ Result error_code{0};
/* 0x04 */ u32 unk_04;
/* 0x08 */ CpuAddr address;
};
static_assert(sizeof(ErrorInfo) == 0x10, "BehaviorInfo::ErrorInfo has the wrong size!");
struct Flags {
u64 IsMemoryForceMappingEnabled : 1;
};
struct InParameter {
/* 0x00 */ u32 revision;
/* 0x08 */ Flags flags;
};
static_assert(sizeof(InParameter) == 0x10, "BehaviorInfo::InParameter has the wrong size!");
struct OutStatus {
/* 0x00 */ std::array<ErrorInfo, MaxErrors> errors;
/* 0xA0 */ u32 error_count;
/* 0xA4 */ char unkA4[0xC];
};
static_assert(sizeof(OutStatus) == 0xB0, "BehaviorInfo::OutStatus has the wrong size!");
BehaviorInfo();
/**
* Get the host revision as a number.
*
* @return The host revision.
*/
u32 GetProcessRevisionNum() const;
/**
* Get the host revision in chars, e.g REV8.
* Rev 10 and higher use the ascii characters above 9.
* E.g:
* Rev 10 = REV:
* Rev 11 = REV;
*
* @return The host revision.
*/
u32 GetProcessRevision() const;
/**
* Get the user revision as a number.
*
* @return The user revision.
*/
u32 GetUserRevisionNum() const;
/**
* Get the user revision in chars, e.g REV8.
* Rev 10 and higher use the ascii characters above 9. REV: REV; etc.
*
* @return The user revision.
*/
u32 GetUserRevision() const;
/**
* Set the user revision.
*
* @param user_revision - The user's revision.
*/
void SetUserLibRevision(u32 user_revision);
/**
* Clear the current error count.
*/
void ClearError();
/**
* Append an error to the error list.
*
* @param error - The new error.
*/
void AppendError(const ErrorInfo& error);
/**
* Copy errors to the given output container.
*
* @param out_errors - Output container to receive the errors.
* @param out_count - The number of errors written.
*/
void CopyErrorInfo(std::span<ErrorInfo> out_errors, u32& out_count) const;
/**
* Update the behaviour flags.
*
* @param flags - New flags to use.
*/
void UpdateFlags(Flags flags);
/**
* Check if memory pools can be forcibly mapped.
*
* @return True if enabled, otherwise false.
*/
bool IsMemoryForceMappingEnabled() const;
/**
* Check if the ADPCM context bug is fixed.
* The ADPCM context was not being sent to the AudioRenderer, leading to incorrect scaling being
* used.
*
* @return True if fixed, otherwise false.
*/
bool IsAdpcmLoopContextBugFixed() const;
/**
* Check if the splitter is supported.
*
* @return True if supported, otherwise false.
*/
bool IsSplitterSupported() const;
/**
* Check if the splitter bug is fixed.
* Update is given the wrong number of splitter destinations, leading to invalid data
* being processed.
*
* @return True if supported, otherwise false.
*/
bool IsSplitterBugFixed() const;
/**
* Check if effects version 2 are supported.
* This gives support for returning effect states from the AudioRenderer, currently only used
* for Limiter statistics.
*
* @return True if supported, otherwise false.
*/
bool IsEffectInfoVersion2Supported() const;
/**
* Check if a variadic command buffer is supported.
* As of Rev 5 with the added optional performance metric logging, the command
* buffer can be a variable size, so take that into account for calculating its size.
*
* @return True if supported, otherwise false.
*/
bool IsVariadicCommandBufferSizeSupported() const;
/**
* Check if wave buffers version 2 are supported.
* See WaveBufferVersion1 and WaveBufferVersion2.
*
* @return True if supported, otherwise false.
*/
bool IsWaveBufferVer2Supported() const;
/**
* Check if long size pre delay is supported.
* This allows a longer initial delay time for the Reverb command.
*
* @return True if supported, otherwise false.
*/
bool IsLongSizePreDelaySupported() const;
/**
* Check if the command time estimator version 2 is supported.
*
* @return True if supported, otherwise false.
*/
bool IsCommandProcessingTimeEstimatorVersion2Supported() const;
/**
* Check if the command time estimator version 3 is supported.
*
* @return True if supported, otherwise false.
*/
bool IsCommandProcessingTimeEstimatorVersion3Supported() const;
/**
* Check if the command time estimator version 4 is supported.
*
* @return True if supported, otherwise false.
*/
bool IsCommandProcessingTimeEstimatorVersion4Supported() const;
/**
* Check if the command time estimator version 5 is supported.
*
* @return True if supported, otherwise false.
*/
bool IsCommandProcessingTimeEstimatorVersion5Supported() const;
/**
* Check if the AudioRenderer can use up to 70% of the allocated processing timeslice.
*
* @return True if supported, otherwise false.
*/
bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;
/**
* Check if the AudioRenderer can use up to 75% of the allocated processing timeslice.
*
* @return True if supported, otherwise false.
*/
bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;
/**
* Check if the AudioRenderer can use up to 80% of the allocated processing timeslice.
*
* @return True if supported, otherwise false.
*/
bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;
/**
* Check if voice flushing is supported
* This allowws low-priority voices to be dropped if the AudioRenderer is running behind.
*
* @return True if supported, otherwise false.
*/
bool IsFlushVoiceWaveBuffersSupported() const;
/**
* Check if counting the number of elapsed frames is supported.
* This adds extra output to RequestUpdate, returning the number of times the AudioRenderer
* processed a command list.
*
* @return True if supported, otherwise false.
*/
bool IsElapsedFrameCountSupported() const;
/**
* Check if performance metrics version 2 are supported.
* This adds extra output to RequestUpdate, returning the number of times the AudioRenderer
* (Unused?).
*
* @return True if supported, otherwise false.
*/
bool IsPerformanceMetricsDataFormatVersion2Supported() const;
/**
* Get the supported performance metrics version.
* Version 2 logs some extra fields in output, such as number of voices dropped,
* processing start time, if the AudioRenderer exceeded its time, etc.
*
* @return Version supported, either 1 or 2.
*/
size_t GetPerformanceMetricsDataFormat() const;
/**
* Check if skipping voice pitch and sample rate conversion is supported.
* This speeds up the data source commands by skipping resampling if unwanted.
* See AudioCore::AudioRenderer::DecodeFromWaveBuffers
*
* @return True if supported, otherwise false.
*/
bool IsVoicePitchAndSrcSkippedSupported() const;
/**
* Check if resetting played sample count at loop points is supported.
* This resets the number of samples played in a voice state when a loop point is reached.
* See AudioCore::AudioRenderer::DecodeFromWaveBuffers
*
* @return True if supported, otherwise false.
*/
bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const;
/**
* Check if the clear state bug for biquad filters is fixed.
* The biquad state was not marked as needing re-initialisation when the effect was updated, it
* was only initialized once with a new effect.
*
* @return True if fixed, otherwise false.
*/
bool IsBiquadFilterEffectStateClearBugFixed() const;
/**
* Check if Q23 precision is supported for fixed point.
*
* @return True if supported, otherwise false.
*/
bool IsVolumeMixParameterPrecisionQ23Supported() const;
/**
* Check if float processing for biuad filters is supported.
*
* @return True if supported, otherwise false.
*/
bool UseBiquadFilterFloatProcessing() const;
/**
* Check if dirty-only mix updates are supported.
* This saves a lot of buffer size as mixes can be large and not change much.
*
* @return True if supported, otherwise false.
*/
bool IsMixInParameterDirtyOnlyUpdateSupported() const;
/**
* Check if multi-tap biquad filters are supported.
*
* @return True if supported, otherwise false.
*/
bool UseMultiTapBiquadFilterProcessing() const;
/**
* Check if device api version 2 is supported.
* In the SDK but not in any sysmodule? Not sure, left here for completeness anyway.
*
* @return True if supported, otherwise false.
*/
bool IsDeviceApiVersion2Supported() const;
/**
* Check if new channel mappings are used for Delay commands.
* Older commands used:
* front left/front right/back left/back right/center/lfe
* Whereas everywhere else in the code uses:
* front left/front right/center/lfe/back left/back right
* This corrects that and makes everything standardised.
*
* @return True if supported, otherwise false.
*/
bool IsDelayChannelMappingChanged() const;
/**
* Check if new channel mappings are used for Reverb commands.
* Older commands used:
* front left/front right/back left/back right/center/lfe
* Whereas everywhere else in the code uses:
* front left/front right/center/lfe/back left/back right
* This corrects that and makes everything standardised.
*
* @return True if supported, otherwise false.
*/
bool IsReverbChannelMappingChanged() const;
/**
* Check if new channel mappings are used for I3dl2Reverb commands.
* Older commands used:
* front left/front right/back left/back right/center/lfe
* Whereas everywhere else in the code uses:
* front left/front right/center/lfe/back left/back right
* This corrects that and makes everything standardised.
*
* @return True if supported, otherwise false.
*/
bool IsI3dl2ReverbChannelMappingChanged() const;
/// Host version
u32 process_revision;
/// User version
u32 user_revision{};
/// Behaviour flags
Flags flags{};
/// Errors generated and reported during Update
std::array<ErrorInfo, MaxErrors> errors{};
/// Error count
u32 error_count{};
};
} // namespace AudioCore::AudioRenderer