diff options
author | Chris Robinson <[email protected]> | 2023-04-29 19:18:06 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-04-29 19:18:06 -0700 |
commit | a35211e2c1dc53e47c4a300366d22a27fb046a8c (patch) | |
tree | a0313f8d37a2193f1cdf07d37f8be4ba53ece8a1 /alc | |
parent | 234174c62123c5d2f57d649722b5ca53b0de9d2d (diff) |
Start a debug API extension
Diffstat (limited to 'alc')
-rw-r--r-- | alc/alc.cpp | 4 | ||||
-rw-r--r-- | alc/context.cpp | 78 | ||||
-rw-r--r-- | alc/context.h | 41 | ||||
-rw-r--r-- | alc/inprogext.h | 31 |
4 files changed, 153 insertions, 1 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp index af8ff55d..0ed0ae58 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -459,6 +459,8 @@ const struct { DECL(alBufferSubDataSOFT), DECL(alBufferDataStatic), + + DECL(alDebugMessageCallbackSOFT), #ifdef ALSOFT_EAX }, eaxFunctions[] = { DECL(EAXGet), @@ -915,6 +917,8 @@ constexpr struct { DECL(AL_FORMAT_UHJ4CHN_MULAW_SOFT), DECL(AL_FORMAT_UHJ4CHN_ALAW_SOFT), + DECL(AL_DEBUG_OUTPUT_SOFT), + DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT), #ifdef ALSOFT_EAX diff --git a/alc/context.cpp b/alc/context.cpp index 008c2bf4..e2a2e2d2 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -113,7 +113,7 @@ void ALCcontext::setThreadContext(ALCcontext *context) noexcept #endif ALCcontext::ALCcontext(al::intrusive_ptr<ALCdevice> device) - : ContextBase{device.get()}, mALDevice{std::move(device)} + : ContextBase{device.get()}, mALDevice{std::move(device)} { } @@ -295,6 +295,82 @@ void ALCcontext::applyAllUpdates() mHoldUpdates.store(false, std::memory_order_release); } +void ALCcontext::sendDebugMessage(DebugSource source, DebugType type, ALuint id, + DebugSeverity severity, ALsizei length, const char *message) +{ + std::lock_guard<std::mutex> _{mDebugCbLock}; + if(!mDebugEnabled.load()) + return; + + if(mDebugCb) + mDebugCb(al::to_underlying(source), al::to_underlying(type), id, + al::to_underlying(severity), length, message, mDebugParam); + else + { + /* TODO: Store in a log. */ + } +} + +FORCE_ALIGN void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + std::lock_guard<std::mutex> _{context->mDebugCbLock}; + context->mDebugCb = callback; + context->mDebugParam = userParam; +} + +FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type, ALuint id, + ALenum severity, ALsizei length, const ALchar *message) noexcept +{ + ContextRef context{GetContextRef()}; + if(!context) UNLIKELY return; + + if(!message) + return context->setError(AL_INVALID_VALUE, "Null message pointer"); + + DebugSource dsource{}; + switch(source) + { + case AL_DEBUG_SOURCE_THIRD_PARTY_SOFT: dsource = DebugSource::ThirdParty; break; + case AL_DEBUG_SOURCE_APPLICATION_SOFT: dsource = DebugSource::Application; break; + case AL_DEBUG_SOURCE_API_SOFT: + case AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT: + case AL_DEBUG_SOURCE_OTHER_SOFT: + return context->setError(AL_INVALID_ENUM, "Debug source enum 0x%04x not allowed", source); + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug source enum 0x%04x", source); + } + + DebugType dtype{}; + switch(type) + { + case AL_DEBUG_TYPE_ERROR_SOFT: dtype = DebugType::Error; break; + case AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT: dtype = DebugType::DeprecatedBehavior; break; + case AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT: dtype = DebugType::UndefinedBehavior; break; + case AL_DEBUG_TYPE_PORTABILITY_SOFT: dtype = DebugType::Portability; break; + case AL_DEBUG_TYPE_PERFORMANCE_SOFT: dtype = DebugType::Performance; break; + case AL_DEBUG_TYPE_MARKER_SOFT: dtype = DebugType::Marker; break; + case AL_DEBUG_TYPE_OTHER_SOFT: dtype = DebugType::Other; break; + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug type 0x%04x", type); + } + + DebugSeverity dseverity{}; + switch(severity) + { + case AL_DEBUG_SEVERITY_HIGH_SOFT: dseverity = DebugSeverity::High; break; + case AL_DEBUG_SEVERITY_MEDIUM_SOFT: dseverity = DebugSeverity::Medium; break; + case AL_DEBUG_SEVERITY_LOW_SOFT: dseverity = DebugSeverity::Low; break; + case AL_DEBUG_SEVERITY_NOTIFICATION_SOFT: dseverity = DebugSeverity::Notification; break; + default: + return context->setError(AL_INVALID_ENUM, "Invalid debug severity 0x%04x", severity); + } + + context->debugMessage(dsource, dtype, id, dseverity, length, message); +} + #ifdef ALSOFT_EAX namespace { diff --git a/alc/context.h b/alc/context.h index e8efdbf1..697ecfe9 100644 --- a/alc/context.h +++ b/alc/context.h @@ -34,6 +34,30 @@ struct ALsource; using uint = unsigned int; +enum class DebugSource : ALenum { + API = AL_DEBUG_SOURCE_API_SOFT, + System = AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT, + ThirdParty = AL_DEBUG_SOURCE_THIRD_PARTY_SOFT, + Application = AL_DEBUG_SOURCE_APPLICATION_SOFT, + Other = AL_DEBUG_SOURCE_OTHER_SOFT, +}; +enum class DebugType : ALenum { + Error = AL_DEBUG_TYPE_ERROR_SOFT, + DeprecatedBehavior = AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT, + UndefinedBehavior = AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT, + Portability = AL_DEBUG_TYPE_PORTABILITY_SOFT, + Performance = AL_DEBUG_TYPE_PERFORMANCE_SOFT, + Marker = AL_DEBUG_TYPE_MARKER_SOFT, + Other = AL_DEBUG_TYPE_OTHER_SOFT, +}; +enum class DebugSeverity : ALenum { + High = AL_DEBUG_SEVERITY_HIGH_SOFT, + Medium = AL_DEBUG_SEVERITY_MEDIUM_SOFT, + Low = AL_DEBUG_SEVERITY_LOW_SOFT, + Notification = AL_DEBUG_SEVERITY_NOTIFICATION_SOFT, +}; + + struct SourceSubList { uint64_t FreeMask{~0_u64}; ALsource *Sources{nullptr}; /* 64 */ @@ -76,6 +100,8 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase { std::atomic<ALenum> mLastError{AL_NO_ERROR}; + std::atomic<bool> mDebugEnabled{false}; + DistanceModel mDistanceModel{DistanceModel::Default}; bool mSourceDistanceModel{false}; @@ -88,6 +114,10 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase { ALEVENTPROCSOFT mEventCb{}; void *mEventParam{nullptr}; + std::mutex mDebugCbLock; + ALDEBUGPROCSOFT mDebugCb{}; + void *mDebugParam{nullptr}; + ALlistener mListener{}; al::vector<SourceSubList> mSourceList; @@ -149,6 +179,17 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase { #endif void setError(ALenum errorCode, const char *msg, ...); + void sendDebugMessage(DebugSource source, DebugType type, ALuint id, DebugSeverity severity, + ALsizei length, const char *message); + + void debugMessage(DebugSource source, DebugType type, ALuint id, DebugSeverity severity, + ALsizei length, const char *message) + { + if(!mDebugEnabled.load(std::memory_order_relaxed)) LIKELY + return; + sendDebugMessage(source, type, id, severity, length, message); + } + /* Process-wide current context */ static std::atomic<bool> sGlobalContextLock; static std::atomic<ALCcontext*> sGlobalContext; diff --git a/alc/inprogext.h b/alc/inprogext.h index ccb9a4be..53dc9f0c 100644 --- a/alc/inprogext.h +++ b/alc/inprogext.h @@ -54,6 +54,37 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopvSOFT(ALsizei n, const ALuint * #define AL_STOP_SOURCES_ON_DISCONNECT_SOFT 0x19AB #endif +#ifndef AL_SOFT_debug +#define AL_SOFT_debug +#define AL_DEBUG_OUTPUT_SOFT 0x19B2 +#define AL_DEBUG_CALLBACK_FUNCTION_SOFT 0x19B3 +#define AL_DEBUG_CALLBACK_USER_PARAM_SOFT 0x19B4 +#define AL_DEBUG_SOURCE_API_SOFT 0x19B5 +#define AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT 0x19B6 +#define AL_DEBUG_SOURCE_THIRD_PARTY_SOFT 0x19B7 +#define AL_DEBUG_SOURCE_APPLICATION_SOFT 0x19B8 +#define AL_DEBUG_SOURCE_OTHER_SOFT 0x19B9 +#define AL_DEBUG_TYPE_ERROR_SOFT 0x19BA +#define AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT 0x19BB +#define AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT 0x19BC +#define AL_DEBUG_TYPE_PORTABILITY_SOFT 0x19BD +#define AL_DEBUG_TYPE_PERFORMANCE_SOFT 0x19BE +#define AL_DEBUG_TYPE_MARKER_SOFT 0x19BF +#define AL_DEBUG_TYPE_OTHER_SOFT 0x19C0 +#define AL_DEBUG_SEVERITY_HIGH_SOFT 0x19C1 +#define AL_DEBUG_SEVERITY_MEDIUM_SOFT 0x19C2 +#define AL_DEBUG_SEVERITY_LOW_SOFT 0x19C3 +#define AL_DEBUG_SEVERITY_NOTIFICATION_SOFT 0x19C4 + +typedef void (AL_APIENTRY*ALDEBUGPROCSOFT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message, void *userParam); +typedef void (AL_APIENTRY*LPALDEBUGMESSAGECALLBACKSOFT)(ALDEBUGPROCSOFT callback, void *userParam); +typedef void (AL_APIENTRY*LPALDEBUGMESSAGEINSERTSOFT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message); +#ifdef AL_ALEXT_PROTOTYPES +void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept; +void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) noexcept; +#endif +#endif + /* Non-standard export. Not part of any extension. */ AL_API const ALchar* AL_APIENTRY alsoft_get_version(void); |