mirror of https://github.com/yuzu-emu/yuzu
377 lines
11 KiB
C++
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
|