Browse Source

D3D9: Fixed persist dynamic buffers after device reset.

Branimir Karadžić 8 years ago
parent
commit
04c3322d93
3 changed files with 60 additions and 28 deletions
  1. 7 2
      examples/35-dynamic/dynamic.cpp
  2. 24 20
      src/renderer_d3d9.cpp
  3. 29 6
      src/renderer_d3d9.h

+ 7 - 2
examples/35-dynamic/dynamic.cpp

@@ -130,7 +130,7 @@ public:
 		}
 
 		// Create static index buffer.
-		m_ibh = bgfx::createIndexBuffer(
+		m_ibh = bgfx::createDynamicIndexBuffer(
 				// Static data can be passed with bgfx::makeRef
 				bgfx::makeRef(s_cubeTriStrip, sizeof(s_cubeTriStrip) )
 				);
@@ -220,11 +220,16 @@ public:
 			bgfx::touch(0);
 
 			{
+				float angle = bx::frnd(&m_mwc);
+				float mtx[16];
+				bx::mtxRotateZ(mtx, angle);
+
 				const bgfx::Memory* mem = bgfx::copy(s_cubeVertices, sizeof(s_cubeVertices) );
 				PosColorVertex* vertex = (PosColorVertex*)mem->data;
 				const uint32_t abgr = m_mwc.gen();
 				for (uint32_t ii = 0; ii < BX_COUNTOF(s_cubeVertices); ++ii)
 				{
+					bx::vec3MulMtx(&vertex[ii].m_x, &s_cubeVertices[ii].m_x, mtx);
 					vertex[ii].m_abgr = abgr;
 				}
 
@@ -279,7 +284,7 @@ public:
 	uint32_t m_debug;
 	uint32_t m_reset;
 	bgfx::DynamicVertexBufferHandle m_vbh[kDimWidth*kDimHeight];
-	bgfx::IndexBufferHandle m_ibh;
+	bgfx::DynamicIndexBufferHandle m_ibh;
 	bgfx::ProgramHandle m_program;
 	int64_t m_timeOffset;
 };

+ 24 - 20
src/renderer_d3d9.cpp

@@ -2277,15 +2277,15 @@ namespace bgfx { namespace d3d9
 	{
 		m_size    = _size;
 		m_flags   = _flags;
-		m_dynamic = NULL == _data;
 
 		uint32_t usage = D3DUSAGE_WRITEONLY;
 		D3DPOOL  pool  = s_renderD3D9->m_pool;
 
-		if (m_dynamic)
+		if (NULL == _data)
 		{
 			usage |= D3DUSAGE_DYNAMIC;
 			pool = D3DPOOL_DEFAULT;
+			m_dynamic = (uint8_t*)BX_ALLOC(g_allocator, _size);
 		}
 
 		const D3DFORMAT format = 0 == (_flags & BGFX_BUFFER_INDEX32)
@@ -2309,7 +2309,7 @@ namespace bgfx { namespace d3d9
 
 	void IndexBufferD3D9::preReset()
 	{
-		if (m_dynamic)
+		if (NULL != m_dynamic)
 		{
 			DX_RELEASE(m_ptr, 0);
 		}
@@ -2317,7 +2317,7 @@ namespace bgfx { namespace d3d9
 
 	void IndexBufferD3D9::postReset()
 	{
-		if (m_dynamic)
+		if (NULL != m_dynamic)
 		{
 			const D3DFORMAT format = 0 == (m_flags & BGFX_BUFFER_INDEX32)
 				? D3DFMT_INDEX16
@@ -2331,6 +2331,8 @@ namespace bgfx { namespace d3d9
 				, &m_ptr
 				, NULL
 				) );
+
+			update(0, m_size, m_dynamic);
 		}
 	}
 
@@ -2338,24 +2340,24 @@ namespace bgfx { namespace d3d9
 	{
 		m_size = _size;
 		m_decl = _declHandle;
-		m_dynamic = NULL == _data;
 
 		uint32_t usage = D3DUSAGE_WRITEONLY;
 		D3DPOOL pool = s_renderD3D9->m_pool;
 
-		if (m_dynamic)
+		if (NULL == _data)
 		{
 			usage |= D3DUSAGE_DYNAMIC;
 			pool = D3DPOOL_DEFAULT;
+			m_dynamic = (uint8_t*)BX_ALLOC(g_allocator, _size);
 		}
 
 		DX_CHECK(s_renderD3D9->m_device->CreateVertexBuffer(m_size
-				, usage
-				, 0
-				, pool
-				, &m_ptr
-				, NULL
-				) );
+			, usage
+			, 0
+			, pool
+			, &m_ptr
+			, NULL
+			) );
 
 		if (NULL != _data)
 		{
@@ -2365,7 +2367,7 @@ namespace bgfx { namespace d3d9
 
 	void VertexBufferD3D9::preReset()
 	{
-		if (m_dynamic)
+		if (NULL != m_dynamic)
 		{
 			DX_RELEASE(m_ptr, 0);
 		}
@@ -2373,15 +2375,17 @@ namespace bgfx { namespace d3d9
 
 	void VertexBufferD3D9::postReset()
 	{
-		if (m_dynamic)
+		if (NULL != m_dynamic)
 		{
 			DX_CHECK(s_renderD3D9->m_device->CreateVertexBuffer(m_size
-					, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
-					, 0
-					, D3DPOOL_DEFAULT
-					, &m_ptr
-					, NULL
-					) );
+				, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC
+				, 0
+				, D3DPOOL_DEFAULT
+				, &m_ptr
+				, NULL
+				) );
+
+			update(0, m_size, m_dynamic);
 		}
 	}
 

+ 29 - 6
src/renderer_d3d9.h

@@ -113,15 +113,21 @@ namespace bgfx { namespace d3d9
 	{
 		IndexBufferD3D9()
 			: m_ptr(NULL)
+			, m_dynamic(NULL)
 			, m_size(0)
 			, m_flags(BGFX_BUFFER_NONE)
-			, m_dynamic(false)
 		{
 		}
 
 		void create(uint32_t _size, void* _data, uint16_t _flags);
 		void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
 		{
+			if (NULL  != m_dynamic
+			&&  _data != m_dynamic)
+			{
+				bx::memCopy(&m_dynamic[_offset], _data, _size);
+			}
+
 			void* buffer;
 			DX_CHECK(m_ptr->Lock(_offset
 				, _size
@@ -139,7 +145,12 @@ namespace bgfx { namespace d3d9
 			if (NULL != m_ptr)
 			{
 				DX_RELEASE(m_ptr, 0);
-				m_dynamic = false;
+
+				if (NULL != m_dynamic)
+				{
+					BX_FREE(g_allocator, m_dynamic);
+					m_dynamic = NULL;
+				}
 			}
 		}
 
@@ -147,22 +158,29 @@ namespace bgfx { namespace d3d9
 		void postReset();
 
 		IDirect3DIndexBuffer9* m_ptr;
+		uint8_t* m_dynamic;
 		uint32_t m_size;
 		uint16_t m_flags;
-		bool m_dynamic;
 	};
 
 	struct VertexBufferD3D9
 	{
 		VertexBufferD3D9()
 			: m_ptr(NULL)
-			, m_dynamic(false)
+			, m_dynamic(NULL)
+			, m_size(0)
 		{
 		}
 
 		void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle);
 		void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
 		{
+			if (NULL  != m_dynamic
+			&&  _data != m_dynamic)
+			{
+				bx::memCopy(&m_dynamic[_offset], _data, _size);
+			}
+
 			void* buffer;
 			DX_CHECK(m_ptr->Lock(_offset
 				, _size
@@ -180,7 +198,12 @@ namespace bgfx { namespace d3d9
 			if (NULL != m_ptr)
 			{
 				DX_RELEASE(m_ptr, 0);
-				m_dynamic = false;
+
+				if (NULL != m_dynamic)
+				{
+					BX_FREE(g_allocator, m_dynamic);
+					m_dynamic = NULL;
+				}
 			}
 		}
 
@@ -188,9 +211,9 @@ namespace bgfx { namespace d3d9
 		void postReset();
 
 		IDirect3DVertexBuffer9* m_ptr;
+		uint8_t* m_dynamic;
 		uint32_t m_size;
 		VertexDeclHandle m_decl;
-		bool m_dynamic;
 	};
 
 	struct ShaderD3D9