コード例 #1
0
        /// <summary>
        /// Flushes all the pending debug messages for all existing <see cref="ID3D12Device"/> instances to the console/debugger.
        /// It also checks whether or not there are any error messages being logged that didn't result in an actual crash yet.
        /// </summary>
        /// <return>Whether or not there are any logged errors or warnings.</return>
        public static unsafe bool FlushAllID3D12InfoQueueMessagesAndCheckForErrorsOrWarnings()
        {
            bool hasErrorsOrWarnings = false;

            lock (DevicesCache)
            {
                int           j       = 0;
                StringBuilder builder = new(1024);

                foreach (var pair in D3D12InfoQueueMap)
                {
                    var device = DevicesCache[pair.Key];
                    var queue  = pair.Value;

                    ulong messages = queue.Get()->GetNumStoredMessagesAllowedByRetrievalFilter();

                    for (ulong i = 0; i < messages; i++)
                    {
                        nuint length;
                        queue.Get()->GetMessage(i, null, &length);

                        D3D12_MESSAGE *message = (D3D12_MESSAGE *)Marshal.AllocHGlobal((nint)length);

                        queue.Get()->GetMessage(i, message, &length);

                        builder.Clear();
                        builder.AppendLine($"[D3D12 message #{i} for \"{device}\" (HW: {device.IsHardwareAccelerated}, UMA: {device.IsCacheCoherentUMA})]");
                        builder.AppendLine($"[Category]: {Enum.GetName(message->Category)}");
                        builder.AppendLine($"[Severity]: {Enum.GetName(message->Severity)}");
                        builder.AppendLine($"[ID]: {Enum.GetName(message->ID)}");
                        builder.Append($"[Description]: \"{new string(message->pDescription)}\"");

                        Marshal.FreeHGlobal((IntPtr)message);

                        if (message->Severity is D3D12_MESSAGE_SEVERITY_ERROR or D3D12_MESSAGE_SEVERITY_CORRUPTION or D3D12_MESSAGE_SEVERITY_WARNING)
                        {
                            hasErrorsOrWarnings = true;
                        }

                        string text = builder.ToString();

                        if (Debugger.IsAttached)
                        {
                            Debug.WriteLine(text);
                        }
                        else
                        {
                            Console.WriteLine(text);
                        }
                    }

                    queue.Get()->ClearStoredMessages();

                    j++;
                }
            }

            return(hasErrorsOrWarnings);
        }
コード例 #2
0
 public int GetMessage([NativeTypeName("UINT64")] ulong MessageIndex, [NativeTypeName("D3D12_MESSAGE *")] D3D12_MESSAGE *pMessage, [NativeTypeName("SIZE_T *")] nuint *pMessageByteLength)
 {
     return(((delegate * unmanaged <ID3D12InfoQueue *, ulong, D3D12_MESSAGE *, nuint *, int>)(lpVtbl[5]))((ID3D12InfoQueue *)Unsafe.AsPointer(ref this), MessageIndex, pMessage, pMessageByteLength));
 }
コード例 #3
0
    /// <summary>
    /// Flushes all the pending debug messages for all existing <see cref="ID3D12Device"/> instances to the console/debugger.
    /// It also checks whether or not there are any error messages being logged that didn't result in an actual crash yet.
    /// </summary>
    /// <return>Whether or not there are any logged errors or warnings.</return>
    public static unsafe bool FlushAllID3D12InfoQueueMessagesAndCheckForErrorsOrWarnings()
    {
        bool hasErrorsOrWarnings = false;

        lock (DevicesCache)
        {
            StringBuilder builder = new(1024);

            foreach (var pair in D3D12InfoQueueMap)
            {
                GraphicsDevice   device = DevicesCache[pair.Key];
                ID3D12InfoQueue *queue  = pair.Value.Get();

                ulong messages = queue->GetNumStoredMessagesAllowedByRetrievalFilter();

                for (ulong i = 0; i < messages; i++)
                {
                    nuint length;

                    queue->GetMessage(i, null, &length);

                    D3D12_MESSAGE *message = (D3D12_MESSAGE *)NativeMemory.Alloc(length);

                    try
                    {
                        queue->GetMessage(i, message, &length);

                        builder.Clear();
                        builder.AppendLine($"[D3D12 message #{i} for \"{device}\" (HW: {device.IsHardwareAccelerated}, UMA: {device.IsCacheCoherentUMA})]");
                        builder.AppendLine($"[Category]: {Enum.GetName(message->Category)}");
                        builder.AppendLine($"[Severity]: {Enum.GetName(message->Severity)}");
                        builder.AppendLine($"[ID]: {Enum.GetName(message->ID)}");
                        builder.Append($"[Description]: \"{new string(message->pDescription)}\"");
                    }
                    finally
                    {
                        NativeMemory.Free(message);
                    }

                    if (message->Severity is D3D12_MESSAGE_SEVERITY_ERROR or D3D12_MESSAGE_SEVERITY_CORRUPTION or D3D12_MESSAGE_SEVERITY_WARNING)
                    {
                        hasErrorsOrWarnings = true;
                    }

                    Trace.WriteLine(builder);
                }

                queue->ClearStoredMessages();

                HRESULT result = device.D3D12Device->GetDeviceRemovedReason();

                if (result != S.S_OK)
                {
                    string message = (int)result switch
                    {
                        DXGI.DXGI_ERROR_DEVICE_HUNG => nameof(DXGI.DXGI_ERROR_DEVICE_HUNG),
                        DXGI.DXGI_ERROR_DEVICE_REMOVED => nameof(DXGI.DXGI_ERROR_DEVICE_REMOVED),
                        DXGI.DXGI_ERROR_DEVICE_RESET => nameof(DXGI.DXGI_ERROR_DEVICE_RESET),
                        DXGI.DXGI_ERROR_DRIVER_INTERNAL_ERROR => nameof(DXGI.DXGI_ERROR_DRIVER_INTERNAL_ERROR),
                        DXGI.DXGI_ERROR_INVALID_CALL => nameof(DXGI.DXGI_ERROR_INVALID_CALL),
                        _ => ThrowHelper.ThrowArgumentOutOfRangeException <string>("Invalid GetDeviceRemovedReason HRESULT.")
                    };

                    builder.Clear();
                    builder.AppendLine($"[D3D12 device \"{device}\" removed (HW: {device.IsHardwareAccelerated}, UMA: {device.IsCacheCoherentUMA})]");
                    builder.AppendLine($"[Reason]: {message}");

                    hasErrorsOrWarnings = true;

                    Trace.WriteLine(builder);
                }
            }
        }

        return(hasErrorsOrWarnings);
    }
}