{"action":"created","issue":{"url":"https://api.github.com/repos/bkaradzic/bgfx/issues/694","repository_url":"https://api.github.com/repos/bkaradzic/bgfx","labels_url":"https://api.github.com/repos/bkaradzic/bgfx/issues/694/labels{/name}","comments_url":"https://api.github.com/repos/bkaradzic/bgfx/issues/694/comments","events_url":"https://api.github.com/repos/bkaradzic/bgfx/issues/694/events","html_url":"https://github.com/bkaradzic/bgfx/issues/694","id":136001952,"number":694,"title":"DynamicVertexBuffers bug with D3D11 renderer","user":{"login":"jdryg","id":5159208,"avatar_url":"https://avatars.githubusercontent.com/u/5159208?v=3","gravatar_id":"","url":"https://api.github.com/users/jdryg","html_url":"https://github.com/jdryg","followers_url":"https://api.github.com/users/jdryg/followers","following_url":"https://api.github.com/users/jdryg/following{/other_user}","gists_url":"https://api.github.com/users/jdryg/gists{/gist_id}","starred_url":"https://api.github.com/users/jdryg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdryg/subscriptions","organizations_url":"https://api.github.com/users/jdryg/orgs","repos_url":"https://api.github.com/users/jdryg/repos","events_url":"https://api.github.com/users/jdryg/events{/privacy}","received_events_url":"https://api.github.com/users/jdryg/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-02-24T09:19:38Z","updated_at":"2016-02-25T10:06:20Z","closed_at":null,"body":"Probably related to #239?\r\n\r\nCan be reproduced in the terrain example. See changes here: https://github.com/jdryg/bgfx/commit/332c2b7fad70200376c4208d5f62cb4206f2d815\r\n\r\nWhat you are supposed to see is holes in the terrain as it animates. \r\n\r\nUnfortunately, I cannot capture it on a screenshot or video. It seems to be related to the time between frames. Toggling vsync sometimes solves the issue. \r\n\r\nTested on Win7 x64 with an nv440GT (driver version 361.91).\r\n\r\nWhat I've tried:\r\n- Both BGFX_CONFIG_MULTITHREADED=0 and 1. With BGFX_CONFIG_MULTITHREADED enabled the bug is somewhat hidden in the terrain example, but it's still there (toggle vsync multiple times and for a couple of frames the holes will be visible).\r\n- Visible on both Debug and Release versions, although since it seems to be related to frame time, it's more visible in Debug mode or Release with vsync enabled.\r\n- Using static vertex buffers works correctly.\r\n- Using the OpenGL renderer with dynamic VBs works correctly.\r\n- Using the D3D9 renderer with dynamic VBs works correctly.\r\n"},"comment":{"url":"https://api.github.com/repos/bkaradzic/bgfx/issues/comments/188702396","html_url":"https://github.com/bkaradzic/bgfx/issues/694#issuecomment-188702396","issue_url":"https://api.github.com/repos/bkaradzic/bgfx/issues/694","id":188702396,"user":{"login":"jdryg","id":5159208,"avatar_url":"https://avatars.githubusercontent.com/u/5159208?v=3","gravatar_id":"","url":"https://api.github.com/users/jdryg","html_url":"https://github.com/jdryg","followers_url":"https://api.github.com/users/jdryg/followers","following_url":"https://api.github.com/users/jdryg/following{/other_user}","gists_url":"https://api.github.com/users/jdryg/gists{/gist_id}","starred_url":"https://api.github.com/users/jdryg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdryg/subscriptions","organizations_url":"https://api.github.com/users/jdryg/orgs","repos_url":"https://api.github.com/users/jdryg/repos","events_url":"https://api.github.com/users/jdryg/events{/privacy}","received_events_url":"https://api.github.com/users/jdryg/received_events","type":"User","site_admin":false},"created_at":"2016-02-25T10:06:19Z","updated_at":"2016-02-25T10:06:19Z","body":"Managed to capture the bug using OBS with monitor capture. Here's a short video: https://youtu.be/RCkdGZNtcLg\r\n\r\nHere's a video of the same bug with NanoVG using DynamicVertexBuffers instead of transient buffers (in order to be able to handle arbitrary amount of vertices per frame): https://youtu.be/HhJAxxD7Q9E\r\n\r\nNanoVG changes for DVBs here: https://github.com/jdryg/bgfx/commit/43c9814bb620cb6f9aed43f5db8f5674490ffa3b \r\n\r\nI've reverted all my previous changes and rewrote it, while trying to keep the changes to a minimum. Hope it's easy to follow.\r\n\r\nThe problem should be more visible with NanoVG since (e.g.) animating a curve changes its geometry (by adding/removing vertices). OTOH, the terrain has a fixed amount of vertices and changing their position every frame might not show the problem.\r\n\r\nIf I haven't screwed up something in NanoVG (I guess if I had, problem would be visible under i.e. OpenGL too), this is what I think happens.\r\n\r\nFirst frame only:\r\n- NanoVG requests a DVB of size 1MB (65536 vertices * 16 bytes / vertex)\r\n  - bgfx allocates a new D3D11 buffer with size equal to BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE (default = 3MB) and returns a DVB handle pointing to the beginning of this buffer (offset 0, size 1MB).\r\n\r\nAll frames (including the 1st after the allocation).\r\n- NanoVG updates the DVB\r\n  - bgfx maps the D3D11 buffer with D3D11_MAP_WRITE_NO_OVERWRITE and copies the data to the buffer.\r\n- NanoVG renders the geometry using this buffer.\r\n  - bgfx does its job...\r\n\r\n(I know that bgfx ops do not happen immediately, but the sequence should be the correct).\r\n\r\nAccording to [MSDN on D3D11_MAP_WRITE_NO_OVERWRITE](https://msdn.microsoft.com/en-us/library/windows/desktop/ff476181(v=vs.85).aspx#NO_OVERWRITE_DETAILS)\r\n\r\n> D3D11_MAP_WRITE_NO_OVERWRITE signifies that the application promises not to write to data that the input assembler (IA) stage is using. In exchange, the GPU allows the application to write to other parts of the same buffer. The application must ensure that it does not write over any data in use by the IA stage.\r\n\r\nProblem is that at the point where bgfx maps the D3D11 buffer, it doesn't know if the IA is using any data from the buffer (is there a way to find out?). Searching for more details around the net, I've found several places suggesting that the proper approach would be to D3D11_MAP_WRITE_DISCARD once, every time you are going to update the buffer, and then remap it with D3D11_MAP_WRITE_NO_OVERWRITE in order to fill it with additional data. \r\n\r\nFrom the same MSDN page: \r\n\r\n> A common use of these two flags involves filling dynamic index/vertex buffers with geometry that can be seen from the camera's current position. The first time that data is entered into the buffer on a given frame, Map is called with D3D11_MAP_WRITE_DISCARD; doing so invalidates the previous contents of the buffer. The buffer is then filled with all available data.\r\nSubsequent writes to the buffer within the same frame should use D3D11_MAP_WRITE_NO_OVERWRITE. This will enable the CPU to access a resource that is potentially being used by the GPU as long as the restrictions described previously are respected.\r\n\r\nAs I said in my 2nd comment above, the terrain example seems to be fixed is the buffer is always discarded. Unfortunately, this doesn't solve the NanoVG problem, when the amount of vertices exceeds 65536 (in other words, when 2 or more DVBs are needed). If you always discard the previous contents of the D3D11 buffer, when updating the 2nd DVB (offset 1M, size 1MB inside the same D3D11 buffer), the data from the first DVB will be lost. Even if it works, it wastes memory by telling the driver to discard a 3MB buffer only to update a 1MB portion of it.\r\n\r\nHope the above make some sense :)\r\n\r\nSorry in advance if I have missed any part in bgfx which does what is mentioned in the article I posted. I should probably try and run the examples through APITrace to see if I'm missing something."}}