aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--al/debug.cpp145
-rw-r--r--al/debug.h5
-rw-r--r--al/state.cpp23
-rw-r--r--alc/alc.cpp7
-rw-r--r--alc/context.cpp105
-rw-r--r--alc/context.h7
-rw-r--r--alc/inprogext.h27
7 files changed, 197 insertions, 122 deletions
diff --git a/al/debug.cpp b/al/debug.cpp
index fc893490..2dd0e7c7 100644
--- a/al/debug.cpp
+++ b/al/debug.cpp
@@ -17,12 +17,15 @@
#include "alc/inprogext.h"
#include "aloptional.h"
#include "alspan.h"
+#include "core/logging.h"
#include "opthelpers.h"
#include "threads.h"
namespace {
+static_assert(DebugSeverityBase+DebugSeverityCount <= 32, "Too many debug bits");
+
template<typename T, T ...Vals>
constexpr auto make_array(std::integer_sequence<T, Vals...>)
{ return std::array<T,sizeof...(Vals)>{Vals...}; }
@@ -55,6 +58,8 @@ constexpr al::optional<DebugType> GetDebugType(ALenum type) noexcept
case AL_DEBUG_TYPE_PORTABILITY_SOFT: return DebugType::Portability;
case AL_DEBUG_TYPE_PERFORMANCE_SOFT: return DebugType::Performance;
case AL_DEBUG_TYPE_MARKER_SOFT: return DebugType::Marker;
+ case AL_DEBUG_TYPE_PUSH_GROUP_SOFT: return DebugType::PushGroup;
+ case AL_DEBUG_TYPE_POP_GROUP_SOFT: return DebugType::PopGroup;
case AL_DEBUG_TYPE_OTHER_SOFT: return DebugType::Other;
}
return al::nullopt;
@@ -72,7 +77,6 @@ constexpr al::optional<DebugSeverity> GetDebugSeverity(ALenum severity) noexcept
return al::nullopt;
}
-} // namespace
ALenum GetDebugSourceEnum(DebugSource source)
{
@@ -97,6 +101,8 @@ ALenum GetDebugTypeEnum(DebugType type)
case DebugType::Portability: return AL_DEBUG_TYPE_PORTABILITY_SOFT;
case DebugType::Performance: return AL_DEBUG_TYPE_PERFORMANCE_SOFT;
case DebugType::Marker: return AL_DEBUG_TYPE_MARKER_SOFT;
+ case DebugType::PushGroup: return AL_DEBUG_TYPE_PUSH_GROUP_SOFT;
+ case DebugType::PopGroup: return AL_DEBUG_TYPE_POP_GROUP_SOFT;
case DebugType::Other: return AL_DEBUG_TYPE_OTHER_SOFT;
}
throw std::runtime_error{"Unexpected debug type value "+std::to_string(al::to_underlying(type))};
@@ -114,6 +120,74 @@ ALenum GetDebugSeverityEnum(DebugSeverity severity)
throw std::runtime_error{"Unexpected debug severity value "+std::to_string(al::to_underlying(severity))};
}
+} // namespace
+
+
+void ALCcontext::sendDebugMessage(std::unique_lock<std::mutex> &debuglock, DebugSource source,
+ DebugType type, ALuint id, DebugSeverity severity, ALsizei length, const char *message)
+{
+ if(!mDebugEnabled.load()) UNLIKELY
+ return;
+
+ /* MaxDebugMessageLength is the size including the null terminator,
+ * <length> does not include the null terminator.
+ */
+ if(length < 0)
+ {
+ size_t newlen{std::strlen(message)};
+ if(newlen >= MaxDebugMessageLength) UNLIKELY
+ {
+ ERR("Debug message too long (%zu >= %d)\n", newlen, MaxDebugMessageLength);
+ return;
+ }
+ length = static_cast<ALsizei>(newlen);
+ }
+ else if(length >= MaxDebugMessageLength) UNLIKELY
+ {
+ ERR("Debug message too long (%d >= %d)\n", length, MaxDebugMessageLength);
+ return;
+ }
+
+ DebugGroup &debug = mDebugGroups.back();
+
+ const uint64_t idfilter{(1_u64 << (DebugSourceBase+al::to_underlying(source)))
+ | (1_u64 << (DebugTypeBase+al::to_underlying(type)))
+ | (uint64_t{id} << 32)};
+ auto iditer = std::lower_bound(debug.mIdFilters.cbegin(), debug.mIdFilters.cend(), idfilter);
+ if(iditer != debug.mIdFilters.cend() && *iditer == idfilter)
+ return;
+
+ const uint filter{(1u << (DebugSourceBase+al::to_underlying(source)))
+ | (1u << (DebugTypeBase+al::to_underlying(type)))
+ | (1u << (DebugSeverityBase+al::to_underlying(severity)))};
+ auto iter = std::lower_bound(debug.mFilters.cbegin(), debug.mFilters.cend(), filter);
+ if(iter != debug.mFilters.cend() && *iter == filter)
+ return;
+
+ if(mDebugCb)
+ {
+ auto callback = mDebugCb;
+ auto param = mDebugParam;
+ debuglock.unlock();
+ callback(GetDebugSourceEnum(source), GetDebugTypeEnum(type), id,
+ GetDebugSeverityEnum(severity), length, message, param);
+ }
+ else
+ {
+ if(mDebugLog.size() < MaxDebugLoggedMessages)
+ mDebugLog.emplace_back(source, type, id, severity, message);
+ else UNLIKELY
+ ERR("Debug message log overflow. Lost message:\n"
+ " Source: 0x%04x\n"
+ " Type: 0x%04x\n"
+ " ID: %u\n"
+ " Severity: 0x%04x\n"
+ " Message: \"%s\"\n",
+ GetDebugSourceEnum(source), GetDebugTypeEnum(type), id,
+ GetDebugSeverityEnum(severity), message);
+ }
+}
+
FORCE_ALIGN void AL_APIENTRY alDebugMessageCallbackSOFT(ALDEBUGPROCSOFT callback, void *userParam) noexcept
{
@@ -134,9 +208,6 @@ FORCE_ALIGN void AL_APIENTRY alDebugMessageInsertSOFT(ALenum source, ALenum type
if(!message)
return context->setError(AL_INVALID_VALUE, "Null message pointer");
- /* MaxDebugMessageLength is the size including the null terminator,
- * <length> does not include the null terminator.
- */
if(length < 0)
{
size_t newlen{std::strlen(message)};
@@ -265,6 +336,72 @@ FORCE_ALIGN void AL_APIENTRY alDebugMessageControlSOFT(ALenum source, ALenum typ
}
+FORCE_ALIGN void AL_APIENTRY alPushDebugGroupSOFT(ALenum source, ALuint id, ALsizei length, const ALchar *message) noexcept
+{
+ ContextRef context{GetContextRef()};
+ if(!context) UNLIKELY return;
+
+ if(length < 0)
+ {
+ size_t newlen{std::strlen(message)};
+ if(newlen >= MaxDebugMessageLength) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Debug message too long (%zu >= %d)",
+ newlen, MaxDebugMessageLength);
+ length = static_cast<ALsizei>(newlen);
+ }
+ else if(length >= MaxDebugMessageLength) UNLIKELY
+ return context->setError(AL_INVALID_VALUE, "Debug message too long (%d > %d)", length,
+ MaxDebugMessageLength);
+
+ auto dsource = GetDebugSource(source);
+ if(!dsource)
+ return context->setError(AL_INVALID_ENUM, "Invalid debug source 0x%04x", source);
+ if(*dsource != DebugSource::ThirdParty && *dsource != DebugSource::Application)
+ return context->setError(AL_INVALID_ENUM, "Debug source 0x%04x not allowed", source);
+
+ std::unique_lock<std::mutex> debuglock{context->mDebugCbLock};
+ if(context->mDebugGroups.size() >= MaxDebugGroupDepth)
+ {
+ debuglock.unlock();
+ return context->setError(AL_STACK_OVERFLOW_SOFT, "Pushing too many debug groups");
+ }
+
+ context->mDebugGroups.emplace_back(*dsource, id, message);
+ auto &oldback = *(context->mDebugGroups.end()-2);
+ auto &newback = context->mDebugGroups.back();
+
+ newback.mFilters = oldback.mFilters;
+ newback.mIdFilters = oldback.mIdFilters;
+
+ context->sendDebugMessage(debuglock, newback.mSource, DebugType::PushGroup, newback.mId,
+ DebugSeverity::Notification, static_cast<ALsizei>(newback.mMessage.size()),
+ newback.mMessage.data());
+}
+
+FORCE_ALIGN void AL_APIENTRY alPopDebugGroupSOFT(void) noexcept
+{
+ ContextRef context{GetContextRef()};
+ if(!context) UNLIKELY return;
+
+ std::unique_lock<std::mutex> debuglock{context->mDebugCbLock};
+ if(context->mDebugGroups.size() <= 1)
+ {
+ debuglock.unlock();
+ return context->setError(AL_STACK_UNDERFLOW_SOFT,
+ "Attempting to pop the default debug group");
+ }
+
+ DebugGroup &debug = context->mDebugGroups.back();
+ const auto source = debug.mSource;
+ const auto id = debug.mId;
+ std::string message{std::move(debug.mMessage)};
+
+ context->mDebugGroups.pop_back();
+ context->sendDebugMessage(debuglock, source, DebugType::PopGroup, id,
+ DebugSeverity::Notification, static_cast<ALsizei>(message.size()), message.data());
+}
+
+
FORCE_ALIGN ALuint AL_APIENTRY alGetDebugMessageLogSOFT(ALuint count, ALsizei logBufSize,
ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths,
ALchar *logBuf) noexcept
diff --git a/al/debug.h b/al/debug.h
index c2147cf4..8f83fd5e 100644
--- a/al/debug.h
+++ b/al/debug.h
@@ -13,6 +13,7 @@ using uint = unsigned int;
*/
constexpr uint8_t MaxDebugLoggedMessages{64};
constexpr uint16_t MaxDebugMessageLength{1024};
+constexpr uint8_t MaxDebugGroupDepth{64};
constexpr uint DebugSourceBase{0};
@@ -33,9 +34,11 @@ enum class DebugType : uint8_t {
Portability,
Performance,
Marker,
+ PushGroup,
+ PopGroup,
Other,
};
-constexpr uint DebugTypeCount{7};
+constexpr uint DebugTypeCount{9};
constexpr uint DebugSeverityBase{DebugTypeBase + DebugTypeCount};
enum class DebugSeverity : uint8_t {
diff --git a/al/state.cpp b/al/state.cpp
index 1e1a0085..2a350646 100644
--- a/al/state.cpp
+++ b/al/state.cpp
@@ -69,6 +69,8 @@ constexpr ALchar alErrInvalidEnum[] = "Invalid Enum";
constexpr ALchar alErrInvalidValue[] = "Invalid Value";
constexpr ALchar alErrInvalidOp[] = "Invalid Operation";
constexpr ALchar alErrOutOfMemory[] = "Out of Memory";
+constexpr ALchar alStackOverflow[] = "Stack Overflow";
+constexpr ALchar alStackUnderflow[] = "Stack Underflow";
/* Resampler strings */
template<Resampler rtype> struct ResamplerName { };
@@ -264,6 +266,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
return alGetInteger(pname) != 0;
}
@@ -308,6 +311,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
return alGetInteger(pname);
}
@@ -338,6 +342,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
return static_cast<ALfloat>(alGetInteger(pname));
case AL_DEFERRED_UPDATES_SOFT:
@@ -436,6 +441,10 @@ START_API_FUNC
value = MaxDebugLoggedMessages;
break;
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
+ value = MaxDebugGroupDepth;
+ break;
+
#ifdef ALSOFT_EAX
#define EAX_ERROR "[alGetInteger] EAX not enabled."
@@ -491,6 +500,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
return alGetInteger(pname);
}
@@ -562,6 +572,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
values[0] = alGetBoolean(pname);
return;
}
@@ -599,6 +610,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
values[0] = alGetDouble(pname);
return;
}
@@ -636,6 +648,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
values[0] = alGetFloat(pname);
return;
}
@@ -673,6 +686,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
values[0] = alGetInteger(pname);
return;
}
@@ -710,6 +724,7 @@ START_API_FUNC
case AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT:
case AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT:
+ case AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT:
values[0] = alGetInteger64SOFT(pname);
return;
}
@@ -806,6 +821,14 @@ START_API_FUNC
value = alErrOutOfMemory;
break;
+ case AL_STACK_OVERFLOW_SOFT:
+ value = alStackOverflow;
+ break;
+
+ case AL_STACK_UNDERFLOW_SOFT:
+ value = alStackUnderflow;
+ break;
+
default:
context->setError(AL_INVALID_VALUE, "Invalid string property 0x%04x", pname);
}
diff --git a/alc/alc.cpp b/alc/alc.cpp
index aa65222c..50982ed2 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -464,6 +464,8 @@ const struct {
DECL(alDebugMessageCallbackSOFT),
DECL(alDebugMessageInsertSOFT),
DECL(alDebugMessageControlSOFT),
+ DECL(alPushDebugGroupSOFT),
+ DECL(alPopDebugGroupSOFT),
DECL(alGetDebugMessageLogSOFT),
#ifdef ALSOFT_EAX
}, eaxFunctions[] = {
@@ -936,6 +938,8 @@ constexpr struct {
DECL(AL_DEBUG_TYPE_PORTABILITY_SOFT),
DECL(AL_DEBUG_TYPE_PERFORMANCE_SOFT),
DECL(AL_DEBUG_TYPE_MARKER_SOFT),
+ DECL(AL_DEBUG_TYPE_PUSH_GROUP_SOFT),
+ DECL(AL_DEBUG_TYPE_POP_GROUP_SOFT),
DECL(AL_DEBUG_TYPE_OTHER_SOFT),
DECL(AL_DEBUG_SEVERITY_HIGH_SOFT),
DECL(AL_DEBUG_SEVERITY_MEDIUM_SOFT),
@@ -945,6 +949,9 @@ constexpr struct {
DECL(AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT),
DECL(AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT),
DECL(AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT),
+ DECL(AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT),
+ DECL(AL_STACK_OVERFLOW_SOFT),
+ DECL(AL_STACK_UNDERFLOW_SOFT),
DECL(AL_STOP_SOURCES_ON_DISCONNECT_SOFT),
diff --git a/alc/context.cpp b/alc/context.cpp
index 755a1e41..0c8253fb 100644
--- a/alc/context.cpp
+++ b/alc/context.cpp
@@ -304,111 +304,6 @@ void ALCcontext::applyAllUpdates()
}
-void ALCcontext::sendDebugMessage(DebugSource source, DebugType type, ALuint id,
- DebugSeverity severity, ALsizei length, const char *message)
-{
- static_assert(DebugSeverityBase+DebugSeverityCount <= 32, "Too many debug bits");
-
- /* MaxDebugMessageLength is the size including the null terminator,
- * <length> does not include the null terminator.
- */
- if(length < 0)
- {
- size_t newlen{std::strlen(message)};
- if(newlen >= MaxDebugMessageLength) UNLIKELY
- {
- ERR("Debug message too long (%zu >= %d)\n", newlen, MaxDebugMessageLength);
- return;
- }
- length = static_cast<ALsizei>(newlen);
- }
- else if(length >= MaxDebugMessageLength) UNLIKELY
- {
- ERR("Debug message too long (%d >= %d)\n", length, MaxDebugMessageLength);
- return;
- }
-
- std::unique_lock<std::mutex> debuglock{mDebugCbLock};
- DebugGroup &debug = mDebugGroups.back();
- if(!mDebugEnabled.load()) UNLIKELY
- return;
-
- auto get_source_enum = [source]()
- {
- switch(source)
- {
- case DebugSource::API: return AL_DEBUG_SOURCE_API_SOFT;
- case DebugSource::System: return AL_DEBUG_SOURCE_AUDIO_SYSTEM_SOFT;
- case DebugSource::ThirdParty: return AL_DEBUG_SOURCE_THIRD_PARTY_SOFT;
- case DebugSource::Application: return AL_DEBUG_SOURCE_APPLICATION_SOFT;
- case DebugSource::Other: return AL_DEBUG_SOURCE_OTHER_SOFT;
- }
- throw std::runtime_error{"Unexpected debug source value "+std::to_string(al::to_underlying(source))};
- };
- auto get_type_enum = [type]()
- {
- switch(type)
- {
- case DebugType::Error: return AL_DEBUG_TYPE_ERROR_SOFT;
- case DebugType::DeprecatedBehavior: return AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_SOFT;
- case DebugType::UndefinedBehavior: return AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_SOFT;
- case DebugType::Portability: return AL_DEBUG_TYPE_PORTABILITY_SOFT;
- case DebugType::Performance: return AL_DEBUG_TYPE_PERFORMANCE_SOFT;
- case DebugType::Marker: return AL_DEBUG_TYPE_MARKER_SOFT;
- case DebugType::Other: return AL_DEBUG_TYPE_OTHER_SOFT;
- }
- throw std::runtime_error{"Unexpected debug type value "+std::to_string(al::to_underlying(type))};
- };
- auto get_severity_enum = [severity]()
- {
- switch(severity)
- {
- case DebugSeverity::High: return AL_DEBUG_SEVERITY_HIGH_SOFT;
- case DebugSeverity::Medium: return AL_DEBUG_SEVERITY_MEDIUM_SOFT;
- case DebugSeverity::Low: return AL_DEBUG_SEVERITY_LOW_SOFT;
- case DebugSeverity::Notification: return AL_DEBUG_SEVERITY_NOTIFICATION_SOFT;
- }
- throw std::runtime_error{"Unexpected debug severity value "+std::to_string(al::to_underlying(severity))};
- };
-
- const uint64_t idfilter{(1_u64 << (DebugSourceBase+al::to_underlying(source)))
- | (1_u64 << (DebugTypeBase+al::to_underlying(type)))
- | (uint64_t{id} << 32)};
- auto iditer = std::lower_bound(debug.mIdFilters.cbegin(), debug.mIdFilters.cend(), idfilter);
- if(iditer != debug.mIdFilters.cend() && *iditer == idfilter)
- return;
-
- const uint filter{(1u << (DebugSourceBase+al::to_underlying(source)))
- | (1u << (DebugTypeBase+al::to_underlying(type)))
- | (1u << (DebugSeverityBase+al::to_underlying(severity)))};
- auto iter = std::lower_bound(debug.mFilters.cbegin(), debug.mFilters.cend(), filter);
- if(iter != debug.mFilters.cend() && *iter == filter)
- return;
-
- if(mDebugCb)
- {
- auto callback = mDebugCb;
- auto param = mDebugParam;
- debuglock.unlock();
- callback(get_source_enum(), get_type_enum(), id, get_severity_enum(), length, message,
- param);
- }
- else
- {
- if(mDebugLog.size() < MaxDebugLoggedMessages)
- mDebugLog.emplace_back(source, type, id, severity, message);
- else UNLIKELY
- ERR("Debug message log overflow. Lost message:\n"
- " Source: 0x%04x\n"
- " Type: 0x%04x\n"
- " ID: %u\n"
- " Severity: 0x%04x\n"
- " Message: \"%s\"\n",
- get_source_enum(), get_type_enum(), id, get_severity_enum(), message);
- }
-}
-
-
#ifdef ALSOFT_EAX
namespace {
diff --git a/alc/context.h b/alc/context.h
index 3e31c9b8..8757b041 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -166,15 +166,16 @@ 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 sendDebugMessage(std::unique_lock<std::mutex> &debuglock, 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);
+ std::unique_lock<std::mutex> debuglock{mDebugCbLock};
+ sendDebugMessage(debuglock, source, type, id, severity, length, message);
}
/* Process-wide current context */
diff --git a/alc/inprogext.h b/alc/inprogext.h
index f73963cb..7f9d7766 100644
--- a/alc/inprogext.h
+++ b/alc/inprogext.h
@@ -71,25 +71,34 @@ AL_API void AL_APIENTRY alAuxiliaryEffectSlotStopvSOFT(ALsizei n, const ALuint *
#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
-#define AL_DEBUG_LOGGED_MESSAGES_SOFT 0x19C5
-#define AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT 0x19C6
-#define AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT 0x19C7
-#define AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT 0x19C8
+#define AL_DEBUG_TYPE_PUSH_GROUP_SOFT 0x19C0
+#define AL_DEBUG_TYPE_POP_GROUP_SOFT 0x19C1
+#define AL_DEBUG_TYPE_OTHER_SOFT 0x19C2
+#define AL_DEBUG_SEVERITY_HIGH_SOFT 0x19C3
+#define AL_DEBUG_SEVERITY_MEDIUM_SOFT 0x19C4
+#define AL_DEBUG_SEVERITY_LOW_SOFT 0x19C5
+#define AL_DEBUG_SEVERITY_NOTIFICATION_SOFT 0x19C6
+#define AL_DEBUG_LOGGED_MESSAGES_SOFT 0x19C7
+#define AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_SOFT 0x19C8
+#define AL_MAX_DEBUG_MESSAGE_LENGTH_SOFT 0x19C9
+#define AL_MAX_DEBUG_LOGGED_MESSAGES_SOFT 0x19CA
+#define AL_MAX_DEBUG_GROUP_STACK_DEPTH_SOFT 0x19CB
+#define AL_STACK_OVERFLOW_SOFT 0x19CC
+#define AL_STACK_UNDERFLOW_SOFT 0x19CD
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);
typedef void (AL_APIENTRY*LPALDEBUGMESSAGECONTROLSOFT)(ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable);
+typedef void (AL_APIENTRY*LPALPUSHDEBUGGROUPSOFT)(ALenum source, ALuint id, ALsizei length, const ALchar *message);
+typedef void (AL_APIENTRY*LPALPOPDEBUGGROUPSOFT)(void);
typedef ALuint (AL_APIENTRY*LPALGETDEBUGMESSAGELOGSOFT)(ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf);
#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;
void AL_APIENTRY alDebugMessageControlSOFT(ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable) noexcept;
+void AL_APIENTRY alPushDebugGroupSOFT(ALenum source, ALuint id, ALsizei length, const ALchar *message) noexcept;
+void AL_APIENTRY alPopDebugGroupSOFT(void) noexcept;
ALuint AL_APIENTRY alGetDebugMessageLogSOFT(ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf) noexcept;
#endif
#endif