From ce818263a13a591fc891e36b30072641e9e8990d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 24 Nov 2017 17:53:42 +0100 Subject: [PATCH] Fix D3D11 push buffer overflow --- GPU/D3D11/D3D11Util.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/GPU/D3D11/D3D11Util.h b/GPU/D3D11/D3D11Util.h index 3184053bcda5..11dba6ee4cfe 100644 --- a/GPU/D3D11/D3D11Util.h +++ b/GPU/D3D11/D3D11Util.h @@ -22,7 +22,7 @@ class PushBufferD3D11 { public: - PushBufferD3D11(ID3D11Device *device, size_t size, D3D11_BIND_FLAG bindFlags) { + PushBufferD3D11(ID3D11Device *device, size_t size, D3D11_BIND_FLAG bindFlags) : size_(size) { D3D11_BUFFER_DESC desc{}; desc.BindFlags = bindFlags; desc.ByteWidth = (UINT)size; @@ -47,6 +47,12 @@ class PushBufferD3D11 { uint8_t *BeginPush(ID3D11DeviceContext *context, UINT *offset, size_t size, int align = 16) { D3D11_MAPPED_SUBRESOURCE map; pos_ = (pos_ + align - 1) & ~(align - 1); + if (pos_ + size > size_) { + // Wrap! Note that with this method, since we return the same buffer as before, you have to do the draw immediately after, + // can't defer like in Vulkan. We instead let the driver handle the invalidation etc. + pos_ = 0; + nextMapDiscard_ = true; + } context->Map(buffer_, 0, nextMapDiscard_ ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE, 0, &map); nextMapDiscard_ = false; *offset = (UINT)pos_; @@ -61,6 +67,7 @@ class PushBufferD3D11 { private: ID3D11Buffer *buffer_ = nullptr; size_t pos_ = 0; + size_t size_; bool nextMapDiscard_ = false; };