Nsight unable to debug OpenGL [The following API usage is unsupported: glBindBufferBase]
Well guys, I'm trying to debug an OpenGL 4.5 Core Profile application and capture a frame, but I get this error: [i]The following API usage is unsupported: glBindBufferBase (target = 0x00008892) To see all incompatibilities, see C:\Users\Tom\Documents\NVIDIA Nsight\nvcompatlog.txt Please send this list to devtools-support@nvidia.com[/i] My system: Windows 10 x64 VisualStudio 15.5.2 Nsight 5.0.0.17240 GeForce 1080Ti, driver: 388.19 Any ideas?
Well guys, I'm trying to debug an OpenGL 4.5 Core Profile application and capture a frame, but I get this error:

The following API usage is unsupported:
glBindBufferBase (target = 0x00008892)
To see all incompatibilities, see C:\Users\Tom\Documents\NVIDIA Nsight\nvcompatlog.txt
Please send this list to devtools-support@nvidia.com


My system:
Windows 10 x64
VisualStudio 15.5.2
Nsight 5.0.0.17240
GeForce 1080Ti, driver: 388.19

Any ideas?

#1
Posted 12/19/2017 05:55 PM   
Hi master.of.m42, I'm sorry for the problem you met, can we have your sample to identify the issue please? I guess the target parameter is unsupported by nsight. Thanks, Letitia
Hi master.of.m42,

I'm sorry for the problem you met, can we have your sample to identify the issue please?
I guess the target parameter is unsupported by nsight.

Thanks,
Letitia

#2
Posted 12/20/2017 02:49 AM   
[b]Letitia[/b], thanks for response! Well, my project is very large, but the function glBindBuffer is used only in one class, called [b]GPUBuffer[/b], this class is designed to facilitate the work on the creation and filling of OpenGL buffers buffers, it is still at the development stage and it is on Qt 5.10 (QOpenGLFunctions_4_5_Core *_f - just pointer to collection of OpenGL function). [b]GPUBuffer[/b] - like std::vector, only for OpenGL. Here is it: [code] #ifndef GPUBUFFER_H #define GPUBUFFER_H #include <QDebug> #include <QOpenGLFunctions_4_5_Core> #include <vector> template <class T> class GPUBuffer { public: GPUBuffer(GLuint _bindingPoint, GLenum _target, GLenum _usage, QOpenGLFunctions_4_5_Core *_f, uint_fast64_t reserve = 100) : bindingPoint(_bindingPoint), target(_target), usage(_usage), f(_f) { if(!f) qDebug() << "GPUBuffer error! QOpenGLFunctions_4_5_Core is null!"; Q_ASSERT(f); elementSize = sizeof(T); capacity = reserve; f->glGenBuffers(1, &bufferId); f->glBindBuffer(target, bufferId); f->glBufferData(target, elementSize * capacity, nullptr, usage); f->glBindBufferBase(target, bindingPoint, bufferId); //!!! f->glBindBuffer(target, 0); } void reserve(uint_fast64_t desiredElNum) { if(desiredElNum < capacity) return; T* cpuBlock = nullptr; if(elementsNum > 0) { GLvoid* p = mapBuffer(); cpuBlock = new T[elementsNum]; memcpy(cpuBlock, p, elementSize * elementsNum); unmapBuffer(); } f->glDeleteBuffers(1, &bufferId); capacity = desiredElNum; f->glGenBuffers(1, &bufferId); f->glBindBuffer(target, bufferId); f->glBufferData(target, elementSize * capacity, nullptr, usage); if(cpuBlock) { f->glBufferSubData(target, 0, elementSize * elementsNum, cpuBlock); delete cpuBlock; } f->glBindBufferBase(target, bindingPoint, bufferId); //!!! f->glBindBuffer(target, 0); } void push_back(T item) { push_back(&item); } void push_back(T* item) { if(capacity < elementsNum + 1) reserve(elementsNum + 1 + capacityOverhead); f->glBindBuffer(target, bufferId); f->glBufferSubData(target, elementSize * elementsNum++, elementSize, item); f->glBindBuffer(target, 0); } void push_back_range(T* item, int size) { if(capacity < elementSize + size) reserve(elementSize + size + capacityOverhead); f->glBindBuffer(target, bufferId); f->glBufferSubData(target, elementSize * elementsNum, elementSize * size, item); elementsNum += size; f->glBindBuffer(target, 0); } void erase(uint_fast64_t from, uint_fast64_t length) { if(length == 0) return; if(elementsNum == 0) return; if(from > elementsNum - 1) return; uint_fast64_t cuttedLength = length; if(from + cuttedLength > elementsNum) cuttedLength = elementsNum - from; uint_fast64_t newLength = elementsNum - cuttedLength; T* newBlock = new T[newLength]; GLvoid* p = mapBuffer(); T* pt = reinterpret_cast<T*>(p); uint_fast64_t leftLen = from; uint_fast64_t rightLen = elementsNum - (from + cuttedLength); if(leftLen > 0) memcpy(newBlock, pt, elementSize * leftLen); if(rightLen > 0) memcpy(newBlock + from, pt + (from + cuttedLength), elementSize * rightLen); unmapBuffer(); f->glDeleteBuffers(1, &bufferId); elementsNum = newLength; capacity = elementsNum + capacityOverhead; f->glGenBuffers(1, &bufferId); f->glBindBuffer(target, bufferId); f->glBufferData(target, elementSize * capacity, nullptr, usage); f->glBufferSubData(target, 0, elementSize * elementsNum, newBlock); delete newBlock; f->glBindBufferBase(target, bindingPoint, bufferId); //!!! f->glBindBuffer(target, 0); } void insert(uint_fast64_t from, T* items, uint_fast64_t length) { if(length == 0) return; if(from > elementsNum) return; uint_fast64_t newLength = elementsNum + length; T* newBlock = new T[newLength]; if(elementsNum > 0) { GLvoid* p = mapBuffer(); T* pt = reinterpret_cast<T*>(p); uint_fast64_t leftLen = from; uint_fast64_t rightLen = elementsNum - from; if(leftLen > 0) memcpy(newBlock, pt, elementSize * leftLen); if(rightLen > 0) memcpy(newBlock + (from + length), pt + from, elementSize * rightLen); unmapBuffer(); } memcpy(newBlock + from, items, length); f->glDeleteBuffers(1, &bufferId); elementsNum = newLength; capacity = elementsNum + capacityOverhead; f->glGenBuffers(1, &bufferId); f->glBindBuffer(target, bufferId); f->glBufferData(target, elementSize * capacity, nullptr, usage); f->glBufferSubData(target, 0, elementSize * elementsNum, newBlock); delete newBlock; f->glBindBufferBase(target, bindingPoint, bufferId); //!!! f->glBindBuffer(target, 0); } void bind() { f->glBindBuffer(target, bufferId); } void unbind() { f->glBindBuffer(target, 0); } void bindBufferBase() { f->glBindBuffer(target, bufferId); f->glBindBufferBase(target, bindingPoint, bufferId); f->glBindBuffer(target, 0); } void reserveFromEnd(uint_fast64_t desiredSizeFromEnd) { if(capacity < elementsNum + desiredSizeFromEnd) reserve(elementsNum + desiredSizeFromEnd + capacityOverhead); } bool empty() { return elementsNum > 0 ? false : true; } GLvoid* mapBuffer(GLenum access = GL_READ_ONLY) { f->glBindBuffer(target, bufferId); GLvoid* p = f->glMapBuffer(target, access); Q_ASSERT(p); return p; } void unmapBuffer(bool forceUnbind = true) { f->glUnmapBuffer(target); if(forceUnbind) unbind(); } T readElement(uint_fast64_t id) { T t; if(id > elementsNum - 1) return t; f->glBindBuffer(target, bufferId); GLvoid* p = f->glMapBufferRange(target, elementSize * id, elementSize, GL_MAP_READ_BIT); if(p) memcpy(&t, p, elementSize); f->glUnmapBuffer(target); f->glBindBuffer(target, 0); return t; } void writeElement(uint_fast64_t id, T t) { f->glBindBuffer(target, bufferId); f->glBufferSubData(target, elementSize * id, elementSize, &t); f->glBindBuffer(target, 0); } uint_fast64_t getElementsNum() { return elementsNum; } GLuint getBufferId() { return bufferId; } private: QOpenGLFunctions_4_5_Core* f = nullptr; GLuint bufferId; GLuint bindingPoint; GLenum usage; GLenum target; uint_fast64_t elementSize = 0; uint_fast64_t elementsNum = 0; uint_fast64_t capacity = 0; uint_fast64_t capacityOverhead = 50; }; #endif // GPUBUFFER_H [/code] Example of usage: Decalration: [code]GPUBuffer<QMatrix4x4>* ssbo_model_matrices = nullptr;[/code] Initialization: [code] ssbo_model_matrices = new GPUBuffer<QMatrix4x4>(0, GL_SHADER_STORAGE_BUFFER, GL_STATIC_DRAW, f); ssbo_model_matrices ->reserve(desired_size); for(int i - 0; i < desired_size; i++) ssbo_model_matrices.push_back(QMatrix()); [/code] Usage in render function, just add one line before draw call: [code]ssbo_screen_info->bindBufferBase();[/code] Well, i think, [b]glBindBufferBase[/b] is not supported by Nsight, and it's very very stange... And [b]Letitia[/b], about "I guess the target parameter is unsupported by nsight"... My target platform vesion is 10.0.16299.0 (windows 10 sdk) and platform toolset VisualStudio 2015 v140 (on VisualStudio 2017) because Nsight also doesn't work with CUDA, which is also involved in this project, on latest version of Visual Studio 2017 :-D What a hell! :-) Dear developers of Nsight, well, finally make a version for QtCreator.... VisualStudio is very problematic IDE :(
Letitia, thanks for response!
Well, my project is very large, but the function glBindBuffer is used only in one class, called GPUBuffer, this class is designed to facilitate the work on the creation and filling of OpenGL buffers buffers, it is still at the development stage and it is on Qt 5.10 (QOpenGLFunctions_4_5_Core *_f - just pointer to collection of OpenGL function). GPUBuffer - like std::vector, only for OpenGL.
Here is it:
#ifndef GPUBUFFER_H
#define GPUBUFFER_H

#include <QDebug>
#include <QOpenGLFunctions_4_5_Core>
#include <vector>

template <class T>
class GPUBuffer
{
public:
GPUBuffer(GLuint _bindingPoint, GLenum _target, GLenum _usage, QOpenGLFunctions_4_5_Core *_f, uint_fast64_t reserve = 100) : bindingPoint(_bindingPoint), target(_target), usage(_usage), f(_f)
{
if(!f)
qDebug() << "GPUBuffer error! QOpenGLFunctions_4_5_Core is null!";
Q_ASSERT(f);

elementSize = sizeof(T);
capacity = reserve;

f->glGenBuffers(1, &bufferId);
f->glBindBuffer(target, bufferId);
f->glBufferData(target, elementSize * capacity, nullptr, usage);
f->glBindBufferBase(target, bindingPoint, bufferId); //!!!
f->glBindBuffer(target, 0);
}

void reserve(uint_fast64_t desiredElNum)
{
if(desiredElNum < capacity)
return;

T* cpuBlock = nullptr;
if(elementsNum > 0)
{
GLvoid* p = mapBuffer();
cpuBlock = new T[elementsNum];
memcpy(cpuBlock, p, elementSize * elementsNum);
unmapBuffer();
}

f->glDeleteBuffers(1, &bufferId);

capacity = desiredElNum;

f->glGenBuffers(1, &bufferId);
f->glBindBuffer(target, bufferId);
f->glBufferData(target, elementSize * capacity, nullptr, usage);
if(cpuBlock)
{
f->glBufferSubData(target, 0, elementSize * elementsNum, cpuBlock);
delete cpuBlock;
}
f->glBindBufferBase(target, bindingPoint, bufferId); //!!!
f->glBindBuffer(target, 0);
}

void push_back(T item)
{
push_back(&item);
}
void push_back(T* item)
{
if(capacity < elementsNum + 1)
reserve(elementsNum + 1 + capacityOverhead);

f->glBindBuffer(target, bufferId);
f->glBufferSubData(target, elementSize * elementsNum++, elementSize, item);
f->glBindBuffer(target, 0);
}
void push_back_range(T* item, int size)
{
if(capacity < elementSize + size)
reserve(elementSize + size + capacityOverhead);

f->glBindBuffer(target, bufferId);
f->glBufferSubData(target, elementSize * elementsNum, elementSize * size, item);
elementsNum += size;
f->glBindBuffer(target, 0);
}

void erase(uint_fast64_t from, uint_fast64_t length)
{
if(length == 0)
return;
if(elementsNum == 0)
return;
if(from > elementsNum - 1)
return;

uint_fast64_t cuttedLength = length;
if(from + cuttedLength > elementsNum)
cuttedLength = elementsNum - from;

uint_fast64_t newLength = elementsNum - cuttedLength;
T* newBlock = new T[newLength];

GLvoid* p = mapBuffer();
T* pt = reinterpret_cast<T*>(p);

uint_fast64_t leftLen = from;
uint_fast64_t rightLen = elementsNum - (from + cuttedLength);

if(leftLen > 0)
memcpy(newBlock, pt, elementSize * leftLen);

if(rightLen > 0)
memcpy(newBlock + from, pt + (from + cuttedLength), elementSize * rightLen);

unmapBuffer();

f->glDeleteBuffers(1, &bufferId);

elementsNum = newLength;
capacity = elementsNum + capacityOverhead;

f->glGenBuffers(1, &bufferId);
f->glBindBuffer(target, bufferId);
f->glBufferData(target, elementSize * capacity, nullptr, usage);

f->glBufferSubData(target, 0, elementSize * elementsNum, newBlock);
delete newBlock;

f->glBindBufferBase(target, bindingPoint, bufferId); //!!!
f->glBindBuffer(target, 0);
}


void insert(uint_fast64_t from, T* items, uint_fast64_t length)
{
if(length == 0)
return;
if(from > elementsNum)
return;

uint_fast64_t newLength = elementsNum + length;

T* newBlock = new T[newLength];

if(elementsNum > 0)
{
GLvoid* p = mapBuffer();
T* pt = reinterpret_cast<T*>(p);

uint_fast64_t leftLen = from;
uint_fast64_t rightLen = elementsNum - from;

if(leftLen > 0)
memcpy(newBlock, pt, elementSize * leftLen);

if(rightLen > 0)
memcpy(newBlock + (from + length), pt + from, elementSize * rightLen);

unmapBuffer();
}
memcpy(newBlock + from, items, length);

f->glDeleteBuffers(1, &bufferId);

elementsNum = newLength;
capacity = elementsNum + capacityOverhead;

f->glGenBuffers(1, &bufferId);
f->glBindBuffer(target, bufferId);
f->glBufferData(target, elementSize * capacity, nullptr, usage);

f->glBufferSubData(target, 0, elementSize * elementsNum, newBlock);
delete newBlock;

f->glBindBufferBase(target, bindingPoint, bufferId); //!!!
f->glBindBuffer(target, 0);
}

void bind()
{
f->glBindBuffer(target, bufferId);
}
void unbind()
{
f->glBindBuffer(target, 0);
}

void bindBufferBase()
{
f->glBindBuffer(target, bufferId);
f->glBindBufferBase(target, bindingPoint, bufferId);
f->glBindBuffer(target, 0);
}

void reserveFromEnd(uint_fast64_t desiredSizeFromEnd)
{
if(capacity < elementsNum + desiredSizeFromEnd)
reserve(elementsNum + desiredSizeFromEnd + capacityOverhead);
}

bool empty()
{
return elementsNum > 0 ? false : true;
}

GLvoid* mapBuffer(GLenum access = GL_READ_ONLY)
{
f->glBindBuffer(target, bufferId);
GLvoid* p = f->glMapBuffer(target, access);
Q_ASSERT(p);
return p;
}
void unmapBuffer(bool forceUnbind = true)
{
f->glUnmapBuffer(target);
if(forceUnbind)
unbind();
}

T readElement(uint_fast64_t id)
{
T t;
if(id > elementsNum - 1)
return t;
f->glBindBuffer(target, bufferId);
GLvoid* p = f->glMapBufferRange(target, elementSize * id, elementSize, GL_MAP_READ_BIT);
if(p)
memcpy(&t, p, elementSize);
f->glUnmapBuffer(target);
f->glBindBuffer(target, 0);
return t;
}

void writeElement(uint_fast64_t id, T t)
{
f->glBindBuffer(target, bufferId);
f->glBufferSubData(target, elementSize * id, elementSize, &t);
f->glBindBuffer(target, 0);
}

uint_fast64_t getElementsNum()
{
return elementsNum;
}

GLuint getBufferId()
{
return bufferId;
}

private:
QOpenGLFunctions_4_5_Core* f = nullptr;
GLuint bufferId;
GLuint bindingPoint;
GLenum usage;
GLenum target;

uint_fast64_t elementSize = 0;
uint_fast64_t elementsNum = 0;
uint_fast64_t capacity = 0;
uint_fast64_t capacityOverhead = 50;
};

#endif // GPUBUFFER_H


Example of usage:
Decalration:
GPUBuffer<QMatrix4x4>* ssbo_model_matrices = nullptr;

Initialization:
ssbo_model_matrices = new GPUBuffer<QMatrix4x4>(0, GL_SHADER_STORAGE_BUFFER, GL_STATIC_DRAW, f);
ssbo_model_matrices ->reserve(desired_size);
for(int i - 0; i < desired_size; i++)
ssbo_model_matrices.push_back(QMatrix());


Usage in render function, just add one line before draw call:
ssbo_screen_info->bindBufferBase();


Well, i think, glBindBufferBase is not supported by Nsight, and it's very very stange...


And Letitia, about "I guess the target parameter is unsupported by nsight"... My target platform vesion is 10.0.16299.0 (windows 10 sdk) and platform toolset VisualStudio 2015 v140 (on VisualStudio 2017) because Nsight also doesn't work with CUDA, which is also involved in this project, on latest version of Visual Studio 2017 :-D What a hell! :-)

Dear developers of Nsight, well, finally make a version for QtCreator.... VisualStudio is very problematic IDE :(

#3
Posted 12/20/2017 06:59 AM   
Hi master.of.m42, Nsight 5.4 supports the OpenGL 4.5 core profile which contains the function glBindBufferBase, which can be referred to the link http://docs.nvidia.com/nsight-visual-studio-edition/5.4/Nsight_Visual_Studio_Edition_User_Guide.htm#Graphics_OGL_Functions.htm%3FTocPath%3DGraphics%2520Debugger%7CFrame%2520Debugging%7COpenGL%7C_____12 As far as the version for QtCreator, I am not sure about the plan or schedule, but I will take a track for your request and let you know if there are some update. Thanks, Letitia
Hi master.of.m42,

Nsight 5.4 supports the OpenGL 4.5 core profile which contains the function glBindBufferBase, which can be referred to the link http://docs.nvidia.com/nsight-visual-studio-edition/5.4/Nsight_Visual_Studio_Edition_User_Guide.htm#Graphics_OGL_Functions.htm%3FTocPath%3DGraphics%2520Debugger%7CFrame%2520Debugging%7COpenGL%7C_____12

As far as the version for QtCreator, I am not sure about the plan or schedule, but I will take a track for your request and let you know if there are some update.

Thanks,
Letitia

#4
Posted 12/25/2017 07:40 AM   
[b]Letitia[/b], yes, please, ask the developers to make a version for QtCreator, this fu...d studio already got me with its bugs and lags ... And where will you create this thread? Give me a link please to the question to the developers...
Letitia, yes, please, ask the developers to make a version for QtCreator, this fu...d studio already got me with its bugs and lags ...
And where will you create this thread? Give me a link please to the question to the developers...

#5
Posted 12/25/2017 03:45 PM   
Hi master.of.m42, Maybe you can find the related forum in the link https://devtalk.nvidia.com/ and raise your questions. Regards, Letitia
Hi master.of.m42,

Maybe you can find the related forum in the link https://devtalk.nvidia.com/ and raise your questions.

Regards,
Letitia

#6
Posted 12/26/2017 06:02 AM   
Scroll To Top

Add Reply