[2.1] Crash locking ManualObject::convertToMesh vertexbuffer

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
N0vember
Gremlin
Posts: 196
Joined: Tue Jan 27, 2009 12:27 am
x 24

[2.1] Crash locking ManualObject::convertToMesh vertexbuffer

Post by N0vember »

This has to do with v1::ManualObject and v1::HardwareVertexBuffer.

I hit a strange bug where locking the mesh vertex buffer of the mesh produced by ManualObject::convertToMesh will crash with this message :
Assertion failed: ((mUsage & HBU_WRITE_ONLY && options != HBL_NORMAL && options != HBL_READ_ONLY) || !(mUsage & HBU_WRITE_ONLY)) && "Reading from a write-only buffer! Create the buffer without HBL_WRITE_ONLY bit", file ..\..\..\RenderSystems\GL3Plus\src\OgreGL3PlusHardwareVertexBuffer.cpp, line 86
I'm locking it HBL_READ_ONLY.
Doing the same operation in 2.0 didn't yield this error.
The vertex buffer of the ManualObject is indeed created with HBU_WRITE_ONLY.
The vertexdata is then cloned in convertToMesh, so maybe it's the cloning behavior that changed ?

Edit : This is a bit weird... I suppose most Meshes and Meshes converted from ManualObject have always had WRITE_ONLY vertex buffers. But the code in picking tools like MOC CollisionTools has always locked these same buffers to be read in READ_ONLY mode and this was never a problem. So this is just a case of stronger enforcement of those rules in the new renderer ?
User avatar
Jayray
Greenskin
Posts: 115
Joined: Sun Sep 09, 2012 5:29 pm
Location: Strasbourg, France
x 9

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by Jayray »

This issue looks a lot like this one: http://www.ogre3d.org/forums/viewtopic.php?f=25&t=83019
If this is the same issue, then it is a bug, and it is already on Matia's trello in the TODO list :)
N0vember
Gremlin
Posts: 196
Joined: Tue Jan 27, 2009 12:27 am
x 24

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by N0vember »

Jayray wrote:This issue looks a lot like this one: http://www.ogre3d.org/forums/viewtopic.php?f=25&t=83019
If this is the same issue, then it is a bug, and it is already on Matia's trello in the TODO list :)
Thanks, didn't see that. But I'm not sure it's the same. In the other issue a mesh is explicitly created with HBU_STATIC (so, not WRITE_ONLY)
I'm afraid in my case the meshes have always been WRITE_ONLY (I think Mesh loaded from ressources are, and it seems Meshes converted from ManualObject are too)
but the mismatch just wasn't crashing the app before.
The problem being that all picking solutions use reading from the vertex buffers to determine if the object is hit...
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by dark_sylinc »

Locking a write-only buffer for reading isn't really valid behavior (it's write-only, d'oh!).
Ogre 1.x was silently letting this happen and continue to work.

We found the problem when suddenly a particular machine (NVIDIA drivers) was returning zeros when read. Also RenderDoc was exhibiting the same behavior. After further examination the problem was that... well we were trying to read from a write only buffer.

OpenGL can be forced to read from these kinds of buffers correctly; however I thought placing the assert would enforce correctness (you can already guess performance in 1.x can go down the drain the moment we tell the API to read from a buffer we promised we would never read from). AFAIK D3D9 (in 1.x) and D3D11 (in 2.1) can handle it gracefully too.
Apparently this misuage of the flags was much more widespread than I thought.

That's really the reason it was working before: it shouldn't have, we're now seeing if we can enforce correctness (we can revert that if it proves too cumbersome)
N0vember
Gremlin
Posts: 196
Joined: Tue Jan 27, 2009 12:27 am
x 24

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by N0vember »

dark_sylinc wrote:Locking a write-only buffer for reading isn't really valid behavior (it's write-only, d'oh!).
Ogre 1.x was silently letting this happen and continue to work.
I'm all for enforcing correct use, especially if it helps us code more efficient apps, but then we have a serious Ogre mouse picking problem which we will need to solve for most of Ogre users : there must be at least one practical way to implement it. Did you implement that in your own projects if you are working on any these days ?
The only accurate solutions out there (MOC, and the new one by SuperNess) was to read from the vertex buffer. So now that most meshes are really write-only, how do we do that ?
The solution by SuperNess enhanced MOC by copying the vertex data only once when an object is registered instead of accessing the buffer per-picking-call. It's better but we still need to access the vertex data once, which is not possible.

For example, we could clone the VertexData and get a copy of the buffer, but the clone() function doesn't take any parameter to specify a different usage, so we're still stuck with WRITE_ONLY
Is there any way to do that with current state of the engine ?
zxz
Gremlin
Posts: 184
Joined: Sat Apr 16, 2016 9:25 pm
x 19

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by zxz »

Is there any workaround for this problem available?

I have run into this issue in my ongoing 1.8->2.1 porting work.

Like N0vember, we run into this issue when accessing vertex data for picking purposes.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by dark_sylinc »

For regular meshes, you'll have to ask Ogre to load the mesh with HBU_STATIC, like the samples do:

Code: Select all

v1Mesh = Ogre::v1::MeshManager::getSingleton().load(
                    "athene.mesh", Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,
                    Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC );
For ManualObjects, I don't know, but a quick find files reveals Ogre does:

Code: Select all

vbuf =
    HardwareBufferManager::getSingleton().createVertexBuffer(
        mDeclSize,
        vertexCount,
        mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
and

Code: Select all

rop->indexData->indexBuffer =
    HardwareBufferManager::getSingleton().createIndexBuffer(
        indexType,
        indexCount,
        mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
Very likely if they get changed for their non-write_only counterparts it should start working. If it does, we can add a flag to toggle this via a boolean instead of hardcoding it.
zxz
Gremlin
Posts: 184
Joined: Sat Apr 16, 2016 9:25 pm
x 19

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbu

Post by zxz »

Thanks!

I hadn't noticed that these flags were exposed as arguments to MeshManager::load.
User avatar
Ybalrid
Halfling
Posts: 89
Joined: Thu Jul 10, 2014 6:52 pm
Location: France
x 31
Contact:

Re: [2.1] Crash locking ManualObject::convertToMesh vertexbuffer

Post by Ybalrid »

Sorry to unearth a super old topic... :P
dark_sylinc wrote: Sat Oct 29, 2016 3:35 am
[...}

For ManualObjects, I don't know, but a quick find files reveals Ogre does:

Code: Select all

vbuf =
    HardwareBufferManager::getSingleton().createVertexBuffer(
        mDeclSize,
        vertexCount,
        mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
and

Code: Select all

rop->indexData->indexBuffer =
    HardwareBufferManager::getSingleton().createIndexBuffer(
        indexType,
        indexCount,
        mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
            HardwareBuffer::HBU_STATIC_WRITE_ONLY);
Very likely if they get changed for their non-write_only counterparts it should start working. If it does, we can add a flag to toggle this via a boolean instead of hardcoding it.
I ran into that issue. I've oppened a Pull Request to add the boolean that permit to toggle the non-write version of theses in v1 ManualObjects.
Ogre_glTF Ogre v2-1 GLTF2 loader : topic link github repo
BtOgre21 Fork of btOgre, for Ogre v2-1 : topic link github repo
OIS Current maintainer : Official repository
Annwvyn VR focused game engine using Ogre : https://github.com/Ybalrid/Annwvyn https://annwvyn.org/
Post Reply