Path: blob/main_old/src/tests/gl_tests/DebugTest.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// DebugTest.cpp : Tests of the GL_KHR_debug extension78#include "common/debug.h"9#include "test_utils/ANGLETest.h"1011namespace angle12{13constexpr char kBufferObjLabel[] = "buffer";14constexpr char kShaderObjLabel[] = "shader";15constexpr char kProgramObjLabel[] = "program";16constexpr char kVertexArrayObjLabel[] = "vertexarray";17constexpr char kQueryObjLabel[] = "query";18constexpr char kProgramPipelineObjLabel[] = "programpipeline";19constexpr GLenum kObjectTypes[] = {GL_BUFFER_OBJECT_EXT, GL_SHADER_OBJECT_EXT,20GL_PROGRAM_OBJECT_EXT, GL_QUERY_OBJECT_EXT,21GL_PROGRAM_PIPELINE_OBJECT_EXT, GL_VERTEX_ARRAY_OBJECT_EXT};2223class DebugTest : public ANGLETest24{25protected:26DebugTest() : mDebugExtensionAvailable(false)27{28setWindowWidth(128);29setWindowHeight(128);30setConfigRedBits(8);31setConfigGreenBits(8);32setConfigBlueBits(8);33setConfigAlphaBits(8);34setConfigDepthBits(24);35setDebugEnabled(true);36}3738void testSetUp() override39{40mDebugExtensionAvailable = IsGLExtensionEnabled("GL_KHR_debug");41if (mDebugExtensionAvailable)42{43glEnable(GL_DEBUG_OUTPUT);44}45}4647bool mDebugExtensionAvailable;48};4950void createGLObjectAndLabel(GLenum identifier, GLuint &object, const char **label)51{52switch (identifier)53{54case GL_BUFFER_OBJECT_EXT:55glGenBuffers(1, &object);56glBindBuffer(GL_ARRAY_BUFFER, object);57*label = kBufferObjLabel;58break;59case GL_SHADER_OBJECT_EXT:60object = glCreateShader(GL_VERTEX_SHADER);61*label = kShaderObjLabel;62break;63case GL_PROGRAM_OBJECT_EXT:64object = glCreateProgram();65*label = kProgramObjLabel;66break;67case GL_VERTEX_ARRAY_OBJECT_EXT:68glGenVertexArrays(1, &object);69glBindVertexArray(object);70*label = kVertexArrayObjLabel;71break;72case GL_QUERY_OBJECT_EXT:73glGenQueries(1, &object);74glBeginQuery(GL_ANY_SAMPLES_PASSED, object);75*label = kQueryObjLabel;76break;77case GL_PROGRAM_PIPELINE_OBJECT_EXT:78glGenProgramPipelines(1, &object);79glBindProgramPipeline(object);80*label = kProgramPipelineObjLabel;81break;82default:83UNREACHABLE();84break;85}86}8788void deleteGLObject(GLenum identifier, GLuint &object)89{90switch (identifier)91{92case GL_BUFFER_OBJECT_EXT:93glDeleteBuffers(1, &object);94break;95case GL_SHADER_OBJECT_EXT:96glDeleteShader(object);97break;98case GL_PROGRAM_OBJECT_EXT:99glDeleteProgram(object);100break;101case GL_VERTEX_ARRAY_OBJECT_EXT:102glDeleteVertexArrays(1, &object);103break;104case GL_QUERY_OBJECT_EXT:105glEndQuery(GL_ANY_SAMPLES_PASSED);106glDeleteQueries(1, &object);107break;108case GL_PROGRAM_PIPELINE_OBJECT_EXT:109glDeleteProgramPipelines(1, &object);110break;111default:112UNREACHABLE();113break;114}115}116117// Test basic usage of setting and getting labels using GL_EXT_debug_label118TEST_P(DebugTest, ObjectLabelsEXT)119{120ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_debug_label"));121122for (const GLenum identifier : kObjectTypes)123{124bool skip = false;125switch (identifier)126{127case GL_PROGRAM_PIPELINE_OBJECT_EXT:128if (!(getClientMajorVersion() >= 3 && getClientMinorVersion() >= 1) ||129!IsGLExtensionEnabled("GL_EXT_separate_shader_objects"))130{131skip = true;132}133break;134case GL_QUERY_OBJECT_EXT:135// GLES3 context is required for glGenQueries()136if (getClientMajorVersion() < 3 ||137!IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"))138{139skip = true;140}141break;142case GL_VERTEX_ARRAY_OBJECT_EXT:143if (getClientMajorVersion() < 3)144{145skip = true;146}147break;148default:149break;150}151152// if object enum is not supported, move on to the next object type153if (skip)154{155continue;156}157158GLuint object;159const char *label;160createGLObjectAndLabel(identifier, object, &label);161162glLabelObjectEXT(identifier, object, 0, label);163ASSERT_GL_NO_ERROR();164165std::vector<char> labelBuf(strlen(label) + 1);166GLsizei labelLengthBuf = 0;167glGetObjectLabelEXT(identifier, object, static_cast<GLsizei>(labelBuf.size()),168&labelLengthBuf, labelBuf.data());169ASSERT_GL_NO_ERROR();170171EXPECT_EQ(static_cast<GLsizei>(strlen(label)), labelLengthBuf);172EXPECT_STREQ(label, labelBuf.data());173174ASSERT_GL_NO_ERROR();175176deleteGLObject(identifier, object);177178glLabelObjectEXT(identifier, object, 0, label);179EXPECT_GL_ERROR(GL_INVALID_OPERATION);180181glGetObjectLabelEXT(identifier, object, static_cast<GLsizei>(labelBuf.size()),182&labelLengthBuf, labelBuf.data());183EXPECT_GL_ERROR(GL_INVALID_OPERATION);184}185}186187class DebugTestES3 : public DebugTest188{};189190struct Message191{192GLenum source;193GLenum type;194GLuint id;195GLenum severity;196std::string message;197const void *userParam;198};199200static void GL_APIENTRY Callback(GLenum source,201GLenum type,202GLuint id,203GLenum severity,204GLsizei length,205const GLchar *message,206const void *userParam)207{208Message m{source, type, id, severity, std::string(message, length), userParam};209std::vector<Message> *messages =210static_cast<std::vector<Message> *>(const_cast<void *>(userParam));211messages->push_back(m);212}213214// Test that all ANGLE back-ends have GL_KHR_debug enabled215TEST_P(DebugTestES3, Enabled)216{217ASSERT_TRUE(mDebugExtensionAvailable);218}219220// Test that when debug output is disabled, no message are outputted221TEST_P(DebugTestES3, DisabledOutput)222{223ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);224225glDisable(GL_DEBUG_OUTPUT);226227glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 1,228GL_DEBUG_SEVERITY_NOTIFICATION, -1, "discarded");229230GLint numMessages = 0;231glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);232ASSERT_EQ(0, numMessages);233234std::vector<Message> messages;235glDebugMessageCallbackKHR(Callback, &messages);236glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);237238ASSERT_EQ(0u, messages.size());239}240241// Test a basic flow of inserting a message and reading it back242TEST_P(DebugTestES3, InsertMessage)243{244ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);245246const GLenum source = GL_DEBUG_SOURCE_APPLICATION;247const GLenum type = GL_DEBUG_TYPE_OTHER;248const GLuint id = 1;249const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION;250const std::string message = "Message";251252glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str());253254GLint numMessages = 0;255glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);256ASSERT_EQ(1, numMessages);257258GLint messageLength = 0;259glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength);260EXPECT_EQ(static_cast<GLint>(message.length()) + 1, messageLength);261262GLenum sourceBuf = 0;263GLenum typeBuf = 0;264GLenum idBuf = 0;265GLenum severityBuf = 0;266GLsizei lengthBuf = 0;267std::vector<char> messageBuf(messageLength);268GLuint ret =269glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf, &typeBuf,270&idBuf, &severityBuf, &lengthBuf, messageBuf.data());271EXPECT_EQ(1u, ret);272EXPECT_EQ(source, sourceBuf);273EXPECT_EQ(type, typeBuf);274EXPECT_EQ(id, idBuf);275EXPECT_EQ(severity, severityBuf);276EXPECT_EQ(lengthBuf, messageLength);277EXPECT_STREQ(message.c_str(), messageBuf.data());278279glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);280EXPECT_EQ(0, numMessages);281282ASSERT_GL_NO_ERROR();283}284285// Test inserting multiple messages286TEST_P(DebugTestES3, InsertMessageMultiple)287{288ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);289290const GLenum source = GL_DEBUG_SOURCE_APPLICATION;291const GLenum type = GL_DEBUG_TYPE_OTHER;292const GLuint startID = 1;293const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION;294const char messageRepeatChar = 'm';295const size_t messageCount = 32;296297for (size_t i = 0; i < messageCount; i++)298{299std::string message(i + 1, messageRepeatChar);300glDebugMessageInsertKHR(source, type, startID + static_cast<GLuint>(i), severity, -1,301message.c_str());302}303304GLint numMessages = 0;305glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);306ASSERT_EQ(static_cast<GLint>(messageCount), numMessages);307308for (size_t i = 0; i < messageCount; i++)309{310glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);311EXPECT_EQ(static_cast<GLint>(messageCount - i), numMessages);312313std::string expectedMessage(i + 1, messageRepeatChar);314315GLint messageLength = 0;316glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength);317EXPECT_EQ(static_cast<GLint>(expectedMessage.length()) + 1, messageLength);318319GLenum sourceBuf = 0;320GLenum typeBuf = 0;321GLenum idBuf = 0;322GLenum severityBuf = 0;323GLsizei lengthBuf = 0;324std::vector<char> messageBuf(messageLength);325GLuint ret =326glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf,327&typeBuf, &idBuf, &severityBuf, &lengthBuf, messageBuf.data());328EXPECT_EQ(1u, ret);329EXPECT_EQ(source, sourceBuf);330EXPECT_EQ(type, typeBuf);331EXPECT_EQ(startID + i, idBuf);332EXPECT_EQ(severity, severityBuf);333EXPECT_EQ(lengthBuf, messageLength);334EXPECT_STREQ(expectedMessage.c_str(), messageBuf.data());335}336337glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);338EXPECT_EQ(0, numMessages);339340ASSERT_GL_NO_ERROR();341}342343// Test using a debug callback344TEST_P(DebugTestES3, DebugCallback)345{346ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);347348std::vector<Message> messages;349350glDebugMessageCallbackKHR(Callback, &messages);351glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);352353const GLenum source = GL_DEBUG_SOURCE_APPLICATION;354const GLenum type = GL_DEBUG_TYPE_OTHER;355const GLuint id = 1;356const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION;357const std::string message = "Message";358359glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str());360361GLint numMessages = 0;362glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);363EXPECT_EQ(0, numMessages);364365ASSERT_EQ(1u, messages.size());366367const Message &m = messages.front();368EXPECT_EQ(source, m.source);369EXPECT_EQ(type, m.type);370EXPECT_EQ(id, m.id);371EXPECT_EQ(severity, m.severity);372EXPECT_EQ(message, m.message);373374ASSERT_GL_NO_ERROR();375}376377// Test the glGetPointervKHR entry point378TEST_P(DebugTestES3, GetPointer)379{380ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);381382std::vector<Message> messages;383384glDebugMessageCallbackKHR(Callback, &messages);385386void *callback = nullptr;387glGetPointervKHR(GL_DEBUG_CALLBACK_FUNCTION, &callback);388EXPECT_EQ(reinterpret_cast<void *>(Callback), callback);389390void *userData = nullptr;391glGetPointervKHR(GL_DEBUG_CALLBACK_USER_PARAM, &userData);392EXPECT_EQ(static_cast<void *>(&messages), userData);393}394395// Test usage of message control. Example taken from GL_KHR_debug spec.396TEST_P(DebugTestES3, MessageControl1)397{398ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);399400std::vector<Message> messages;401402glDebugMessageCallbackKHR(Callback, &messages);403glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);404405// Setup of the default active debug group: Filter everything in406glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);407408// Generate a debug marker debug output message409glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,410GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 1");411412// Push debug group 1413glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 2");414415// Setup of the debug group 1: Filter everything out416glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);417418// This message won't appear in the debug output log of419glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,420GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 3");421422// Pop debug group 1, restore the volume control of the default debug group.423glPopDebugGroupKHR();424425// Generate a debug marker debug output message426glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,427GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 5");428429// Expected debug output from the GL implementation430// Message 1431// Message 2432// Message 2433// Message 5434EXPECT_EQ(4u, messages.size());435EXPECT_STREQ(messages[0].message.c_str(), "Message 1");436EXPECT_STREQ(messages[1].message.c_str(), "Message 2");437EXPECT_STREQ(messages[2].message.c_str(), "Message 2");438EXPECT_STREQ(messages[3].message.c_str(), "Message 5");439440ASSERT_GL_NO_ERROR();441}442443// Test usage of message control. Example taken from GL_KHR_debug spec.444TEST_P(DebugTestES3, MessageControl2)445{446ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);447448std::vector<Message> messages;449450glDebugMessageCallbackKHR(Callback, &messages);451glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);452453// Setup the control of de debug output for the default debug group454glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);455glDebugMessageControlKHR(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr,456GL_FALSE);457std::vector<GLuint> ids0 = {1234, 2345, 3456, 4567};458glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,459static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE);460glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, GL_DONT_CARE,461static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE);462463// Push debug group 1464// Inherit of the default debug group debug output volume control465// Filtered out by glDebugMessageControl466glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 1");467468// In this section of the code, we are interested in performances.469glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE,4700, nullptr, GL_TRUE);471// But we already identify that some messages are not really useful for us.472std::vector<GLuint> ids1 = {5678, 6789};473glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,474static_cast<GLuint>(ids1.size()), ids1.data(), GL_FALSE);475476glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 1357,477GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 2");478glDebugMessageInsertKHR(GL_DEBUG_SOURCE_THIRD_PARTY, // We still filter out these messages.479GL_DEBUG_TYPE_OTHER, 3579, GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 3");480481glPopDebugGroupKHR();482483// Expected debug output from the GL implementation484// Message 2485EXPECT_EQ(1u, messages.size());486EXPECT_STREQ(messages[0].message.c_str(), "Message 2");487488ASSERT_GL_NO_ERROR();489}490491// Test basic usage of setting and getting labels492TEST_P(DebugTestES3, ObjectLabels)493{494ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);495496GLuint renderbuffer = 0;497glGenRenderbuffers(1, &renderbuffer);498glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);499500const std::string &label = "renderbuffer";501glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str());502503std::vector<char> labelBuf(label.length() + 1);504GLsizei labelLengthBuf = 0;505glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()),506&labelLengthBuf, labelBuf.data());507508EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);509EXPECT_STREQ(label.c_str(), labelBuf.data());510511ASSERT_GL_NO_ERROR();512513glDeleteRenderbuffers(1, &renderbuffer);514515glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str());516EXPECT_GL_ERROR(GL_INVALID_VALUE);517518glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()),519&labelLengthBuf, labelBuf.data());520EXPECT_GL_ERROR(GL_INVALID_VALUE);521}522523// Test basic usage of setting and getting labels524TEST_P(DebugTestES3, ObjectPtrLabels)525{526ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);527528GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);529530const std::string &label = "sync";531glObjectPtrLabelKHR(sync, -1, label.c_str());532533std::vector<char> labelBuf(label.length() + 1);534GLsizei labelLengthBuf = 0;535glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf,536labelBuf.data());537538EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);539EXPECT_STREQ(label.c_str(), labelBuf.data());540541ASSERT_GL_NO_ERROR();542543glDeleteSync(sync);544545glObjectPtrLabelKHR(sync, -1, label.c_str());546EXPECT_GL_ERROR(GL_INVALID_VALUE);547548glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf,549labelBuf.data());550EXPECT_GL_ERROR(GL_INVALID_VALUE);551}552553GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DebugTestES3);554ANGLE_INSTANTIATE_TEST_ES3(DebugTestES3);555556ANGLE_INSTANTIATE_TEST(DebugTest,557ANGLE_ALL_TEST_PLATFORMS_ES1,558ANGLE_ALL_TEST_PLATFORMS_ES2,559ANGLE_ALL_TEST_PLATFORMS_ES3,560ANGLE_ALL_TEST_PLATFORMS_ES31);561} // namespace angle562563564