Browse Source

Added support for GPU compute dynamic index buffer.

Branimir Karadžić 11 years ago
parent
commit
ef05e607d6
8 changed files with 193 additions and 162 deletions
  1. 13 6
      include/bgfx.h
  2. 18 3
      src/bgfx.cpp
  3. 72 28
      src/bgfx_p.h
  4. 48 79
      src/renderer_d3d11.cpp
  5. 15 27
      src/renderer_d3d11.h
  6. 14 14
      src/renderer_d3d9.cpp
  7. 12 4
      src/renderer_gl.cpp
  8. 1 1
      src/renderer_null.cpp

+ 13 - 6
include/bgfx.h

@@ -161,7 +161,7 @@ namespace bgfx
 			D24F,
 			D32F,
 			D0S8,
-			
+
 			Count
 		};
 	};
@@ -379,7 +379,7 @@ namespace bgfx
 			float translation[3];       //!< Eye translation.
 			float fov[4];               //!< Field of view (up, down, left, right).
 			float viewOffset[3];        //!< Eye view matrix translation adjustment.
-			float pixelsPerTanAngle[2]; //!< 
+			float pixelsPerTanAngle[2]; //!<
 		};
 
 		Eye eye[2];
@@ -600,7 +600,7 @@ namespace bgfx
 	void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...);
 
 	/// Draw image into internal debug text buffer.
-	/// 
+	///
 	/// @param _x      X position from top-left.
 	/// @param _y      Y position from top-left.
 	/// @param _width  Image width.
@@ -637,11 +637,12 @@ namespace bgfx
 	/// Create empty dynamic index buffer.
 	///
 	/// @param _num Number of indices.
+	/// @param _flags `BGFX_BUFFER_*` flags.
 	///
 	/// @remarks
 	///   Only 16-bit index buffer is supported.
 	///
-	DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num);
+	DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint8_t _flags = BGFX_BUFFER_COMPUTE_NONE);
 
 	/// Create dynamic index buffer and initialized it.
 	///
@@ -669,7 +670,7 @@ namespace bgfx
 	///
 	/// @param _num Number of vertices.
 	/// @param _decl Vertex declaration.
-	/// @param _compute True if vertex buffer will be used by compute shader.
+	/// @param _flags `BGFX_BUFFER_*` flags.
 	///
 	DynamicVertexBufferHandle createDynamicVertexBuffer(uint16_t _num, const VertexDecl& _decl, uint8_t _flags = BGFX_BUFFER_COMPUTE_NONE);
 
@@ -932,7 +933,7 @@ namespace bgfx
 	///
 	/// @param _num Number of texture attachments.
 	/// @param _handles Texture attachments.
-	/// @param _destroyTextures If true, textures will be destroyed when 
+	/// @param _destroyTextures If true, textures will be destroyed when
 	///   frame buffer is destroyed.
 	///
 	FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles, bool _destroyTextures = false);
@@ -1244,9 +1245,15 @@ namespace bgfx
 	///
 	uint32_t submit(uint8_t _id, int32_t _depth = 0);
 
+	///
+	void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access);
+
 	///
 	void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access);
 
+	///
+	void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access);
+
 	///
 	void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access);
 

+ 18 - 3
src/bgfx.cpp

@@ -1564,7 +1564,10 @@ again:
 					uint32_t size;
 					_cmdbuf.read(size);
 
-					m_renderCtx->createDynamicIndexBuffer(handle, size);
+					uint8_t flags;
+					_cmdbuf.read(flags);
+
+					m_renderCtx->createDynamicIndexBuffer(handle, size, flags);
 				}
 				break;
 
@@ -2086,10 +2089,10 @@ again:
 		s_ctx->destroyVertexBuffer(_handle);
 	}
 
-	DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num)
+	DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint8_t _flags)
 	{
 		BGFX_CHECK_MAIN_THREAD();
-		return s_ctx->createDynamicIndexBuffer(_num);
+		return s_ctx->createDynamicIndexBuffer(_num, _flags);
 	}
 
 	DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem)
@@ -2762,12 +2765,24 @@ again:
 		return s_ctx->submit(_id, _depth);
 	}
 
+	void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		s_ctx->setBuffer(_stage, _handle, _access);
+	}
+
 	void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		s_ctx->setBuffer(_stage, _handle, _access);
 	}
 
+	void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access)
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		s_ctx->setBuffer(_stage, _handle, _access);
+	}
+
 	void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access)
 	{
 		BGFX_CHECK_MAIN_THREAD();

+ 72 - 28
src/bgfx_p.h

@@ -1092,16 +1092,17 @@ namespace bgfx
 		enum Enum
 		{
 			Image,
-			Buffer,
+			VertexBuffer,
+			IndexBuffer,
 
 			Count
 		};
 
 		uint16_t m_idx;
-		uint8_t m_format;
-		uint8_t m_access;
-		uint8_t m_mip;
-		uint8_t m_type;
+		uint8_t  m_format;
+		uint8_t  m_access;
+		uint8_t  m_mip;
+		uint8_t  m_type;
 	};
 
 	struct RenderCompute
@@ -1387,14 +1388,24 @@ namespace bgfx
 			}
 		}
 
-		void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
+		void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
 		{
 			ComputeBinding& bind = m_compute.m_bind[_stage];
 			bind.m_idx    = _handle.idx;
 			bind.m_format = 0;
 			bind.m_access = uint8_t(_access);
 			bind.m_mip    = 0;
-			bind.m_type   = uint8_t(ComputeBinding::Buffer);
+			bind.m_type   = uint8_t(ComputeBinding::IndexBuffer);
+		}
+
+		void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
+		{
+			ComputeBinding& bind = m_compute.m_bind[_stage];
+			bind.m_idx = _handle.idx;
+			bind.m_format = 0;
+			bind.m_access = uint8_t(_access);
+			bind.m_mip = 0;
+			bind.m_type = uint8_t(ComputeBinding::VertexBuffer);
 		}
 
 		void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, TextureFormat::Enum _format, Access::Enum _access)
@@ -1779,7 +1790,7 @@ namespace bgfx
 		virtual void destroyVertexDecl(VertexDeclHandle _handle) = 0;
 		virtual void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint8_t _flags) = 0;
 		virtual void destroyVertexBuffer(VertexBufferHandle _handle) = 0;
-		virtual void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) = 0;
+		virtual void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t _flags) = 0;
 		virtual void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) = 0;
 		virtual void destroyDynamicIndexBuffer(IndexBufferHandle _handle) = 0;
 		virtual void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint8_t _flags) = 0;
@@ -1982,26 +1993,47 @@ namespace bgfx
 			m_vertexBufferHandle.free(_handle.idx);
 		}
 
-		BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num) )
+		BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint8_t _flags))
 		{
 			DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE;
 			uint32_t size = BX_ALIGN_16(_num*2);
-			uint64_t ptr = m_dynamicIndexBufferAllocator.alloc(size);
-			if (ptr == NonLocalAllocator::invalidBlock)
+
+			uint64_t ptr = 0;
+			if (0 != (_flags & BGFX_BUFFER_COMPUTE_WRITE))
 			{
-				IndexBufferHandle indexBufferHandle = { m_indexBufferHandle.alloc() };
-				BX_WARN(isValid(indexBufferHandle), "Failed to allocate index buffer handle.");
-				if (!isValid(indexBufferHandle) )
+				VertexBufferHandle vertexBufferHandle = { m_vertexBufferHandle.alloc() };
+				if (!isValid(vertexBufferHandle))
 				{
 					return handle;
 				}
 
-				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
-				cmdbuf.write(indexBufferHandle);
-				cmdbuf.write(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
+				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicVertexBuffer);
+				cmdbuf.write(vertexBufferHandle);
+				cmdbuf.write(size);
+				cmdbuf.write(_flags);
 
-				m_dynamicIndexBufferAllocator.add(uint64_t(indexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
-				ptr = m_dynamicIndexBufferAllocator.alloc(size);
+				ptr = uint64_t(vertexBufferHandle.idx) << 32;
+			}
+			else
+			{
+				ptr = m_dynIndexBufferAllocator.alloc(size);
+				if (ptr == NonLocalAllocator::invalidBlock)
+				{
+					IndexBufferHandle indexBufferHandle = { m_indexBufferHandle.alloc() };
+					BX_WARN(isValid(indexBufferHandle), "Failed to allocate index buffer handle.");
+					if (!isValid(indexBufferHandle))
+					{
+						return handle;
+					}
+
+					CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
+					cmdbuf.write(indexBufferHandle);
+					cmdbuf.write(BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
+					cmdbuf.write(_flags);
+
+					m_dynIndexBufferAllocator.add(uint64_t(indexBufferHandle.idx) << 32, BGFX_CONFIG_DYNAMIC_INDEX_BUFFER_SIZE);
+					ptr = m_dynIndexBufferAllocator.alloc(size);
+				}
 			}
 
 			handle.idx = m_dynamicIndexBufferHandle.alloc();
@@ -2021,7 +2053,7 @@ namespace bgfx
 
 		BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem) )
 		{
-			DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/2);
+			DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/2, BGFX_BUFFER_COMPUTE_NONE);
 			if (isValid(handle) )
 			{
 				updateDynamicIndexBuffer(handle, _mem);
@@ -2047,7 +2079,7 @@ namespace bgfx
 		void destroyDynamicIndexBufferInternal(DynamicIndexBufferHandle _handle)
 		{
 			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
-			m_dynamicIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset);
+			m_dynIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset);
 			m_dynamicIndexBufferHandle.free(_handle.idx);
 		}
 
@@ -2074,7 +2106,7 @@ namespace bgfx
 			}
 			else
 			{
-				ptr = m_cpuDvbAllocator.alloc(size);
+				ptr = m_dynVertexBufferAllocator.alloc(size);
 				if (ptr == NonLocalAllocator::invalidBlock)
 				{
 					VertexBufferHandle vertexBufferHandle = { m_vertexBufferHandle.alloc() };
@@ -2090,8 +2122,8 @@ namespace bgfx
 					cmdbuf.write(BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
 					cmdbuf.write(_flags);
 
-					m_cpuDvbAllocator.add(uint64_t(vertexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
-					ptr = m_cpuDvbAllocator.alloc(size);
+					m_dynVertexBufferAllocator.add(uint64_t(vertexBufferHandle.idx)<<32, BGFX_CONFIG_DYNAMIC_VERTEX_BUFFER_SIZE);
+					ptr = m_dynVertexBufferAllocator.alloc(size);
 				}
 			}
 
@@ -2116,7 +2148,7 @@ namespace bgfx
 		{
 			uint32_t numVertices = _mem->size/_decl.m_stride;
 			BX_CHECK(numVertices <= UINT16_MAX, "Num vertices exceeds maximum (num %d, max %d).", numVertices, UINT16_MAX);
-			DynamicVertexBufferHandle handle = createDynamicVertexBuffer(uint16_t(numVertices), _decl, false);
+			DynamicVertexBufferHandle handle = createDynamicVertexBuffer(uint16_t(numVertices), _decl, BGFX_BUFFER_COMPUTE_NONE);
 			if (isValid(handle) )
 			{
 				updateDynamicVertexBuffer(handle, _mem);
@@ -2157,7 +2189,7 @@ namespace bgfx
 			}
 			else
 			{
-				m_cpuDvbAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset);
+				m_dynVertexBufferAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset);
 			}
 			m_dynamicVertexBufferHandle.free(_handle.idx);
 		}
@@ -2183,6 +2215,7 @@ namespace bgfx
 				CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateDynamicIndexBuffer);
 				cmdbuf.write(handle);
 				cmdbuf.write(_size);
+				cmdbuf.write(BGFX_BUFFER_COMPUTE_NONE);
 
 				ib = (TransientIndexBuffer*)BX_ALLOC(g_allocator, sizeof(TransientIndexBuffer)+_size);
 				ib->data = (uint8_t*)&ib[1];
@@ -3020,11 +3053,22 @@ namespace bgfx
 			return m_submit->submit(_id, _depth);
 		}
 
+		BGFX_API_FUNC(void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) )
+		{
+			m_submit->setBuffer(_stage, _handle, _access);
+		}
+
 		BGFX_API_FUNC(void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) )
 		{
 			m_submit->setBuffer(_stage, _handle, _access);
 		}
 
+		BGFX_API_FUNC(void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) )
+		{
+			const DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
+			m_submit->setBuffer(_stage, dib.m_handle, _access);
+		}
+
 		BGFX_API_FUNC(void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) )
 		{
 			const DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
@@ -3139,9 +3183,9 @@ namespace bgfx
 		DynamicIndexBufferHandle m_freeDynamicIndexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS];
 		DynamicVertexBufferHandle m_freeDynamicVertexBufferHandle[BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS];
 
-		NonLocalAllocator m_dynamicIndexBufferAllocator;
+		NonLocalAllocator m_dynIndexBufferAllocator;
 		bx::HandleAllocT<BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS> m_dynamicIndexBufferHandle;
-		NonLocalAllocator m_cpuDvbAllocator;
+		NonLocalAllocator m_dynVertexBufferAllocator;
 		bx::HandleAllocT<BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS> m_dynamicVertexBufferHandle;
 
 		bx::HandleAllocT<BGFX_CONFIG_MAX_INDEX_BUFFERS> m_indexBufferHandle;

+ 48 - 79
src/renderer_d3d11.cpp

@@ -548,7 +548,7 @@ namespace bgfx
 			uint32_t flags = 0
 				| D3D11_CREATE_DEVICE_SINGLETHREADED
 				| D3D11_CREATE_DEVICE_BGRA_SUPPORT
-				| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
+//				| (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0)
 				;
 
 			D3D_FEATURE_LEVEL featureLevel;
@@ -764,7 +764,7 @@ namespace bgfx
 
 		void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem) BX_OVERRIDE
 		{
-			m_indexBuffers[_handle.idx].create(_mem->size, _mem->data);
+			m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, BGFX_BUFFER_COMPUTE_NONE);
 		}
 
 		void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE
@@ -793,9 +793,9 @@ namespace bgfx
 			m_vertexBuffers[_handle.idx].destroy();
 		}
 
-		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) BX_OVERRIDE
+		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t _flags) BX_OVERRIDE
 		{
-			m_indexBuffers[_handle.idx].create(_size, NULL);
+			m_indexBuffers[_handle.idx].create(_size, NULL, _flags);
 		}
 
 		void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE
@@ -2235,61 +2235,10 @@ namespace bgfx
 		s_renderD3D11 = NULL;
 	}
 
-	void IndexBufferD3D11::create(uint32_t _size, void* _data)
+	void BufferD3D11::create(uint32_t _size, void* _data, uint8_t _flags, uint16_t _stride, bool _vertex)
 	{
+		m_uav  = NULL;
 		m_size = _size;
-		m_dynamic = NULL == _data;
-
-		D3D11_BUFFER_DESC desc;
-		desc.ByteWidth = _size;
-		desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
-		desc.MiscFlags = 0;
-		desc.StructureByteStride = 0;
-
-		if (m_dynamic)
-		{
-			desc.Usage = D3D11_USAGE_DYNAMIC;
-			desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-
-			DX_CHECK(s_renderD3D11->m_device->CreateBuffer(&desc
-				, NULL
-				, &m_ptr
-				) );
-		}
-		else
-		{
-			desc.Usage = D3D11_USAGE_IMMUTABLE;
-			desc.CPUAccessFlags = 0;
-
-			D3D11_SUBRESOURCE_DATA srd;
-			srd.pSysMem = _data;
-			srd.SysMemPitch = 0;
-			srd.SysMemSlicePitch = 0;
-
-			DX_CHECK(s_renderD3D11->m_device->CreateBuffer(&desc
-				, &srd
-				, &m_ptr
-				) );
-		}
-	}
-
-	void IndexBufferD3D11::update(uint32_t _offset, uint32_t _size, void* _data)
-	{
-		ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
-		BX_CHECK(m_dynamic, "Must be dynamic!");
-
-		D3D11_MAPPED_SUBRESOURCE mapped;
-		D3D11_MAP type = m_dynamic && 0 == _offset && m_size == _size ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE;
-		DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped) );
-		memcpy( (uint8_t*)mapped.pData + _offset, _data, _size);
-		deviceCtx->Unmap(m_ptr, 0);
-	}
-
-	void VertexBufferD3D11::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint8_t _flags)
-	{
-		m_uav = NULL;
-		m_size = _size;
-		m_decl = _declHandle;
 
 		const bool needUav = 0 != (_flags & BGFX_BUFFER_COMPUTE_WRITE);
 		const bool needSrv = 0 != (_flags & BGFX_BUFFER_COMPUTE_READ);
@@ -2298,39 +2247,41 @@ namespace bgfx
 		D3D11_BUFFER_DESC desc;
 		desc.ByteWidth = _size;
 		desc.BindFlags = 0
-			| D3D11_BIND_VERTEX_BUFFER
+			| (_vertex ? D3D11_BIND_VERTEX_BUFFER    : D3D11_BIND_INDEX_BUFFER)
 			| (needUav ? D3D11_BIND_UNORDERED_ACCESS : 0)
 			| (needSrv ? D3D11_BIND_SHADER_RESOURCE  : 0)
 			;
 		desc.MiscFlags = 0;
 		desc.StructureByteStride = 0;
 
+		DXGI_FORMAT format = _vertex
+			? DXGI_FORMAT_R32G32B32A32_FLOAT
+			: DXGI_FORMAT_R16_UINT
+			;
+
 		ID3D11Device* device = s_renderD3D11->m_device;
 
 		if (needUav)
 		{
 			desc.Usage = D3D11_USAGE_DEFAULT;
 			desc.CPUAccessFlags = 0;
-			desc.StructureByteStride = isValid(_declHandle)
-				? s_renderD3D11->m_vertexDecls[_declHandle.idx].m_stride
-				: 0
-				;
+			desc.StructureByteStride = _stride;
 
 			DX_CHECK(device->CreateBuffer(&desc
 				, NULL
 				, &m_ptr
-				) );
+				));
 
 			D3D11_UNORDERED_ACCESS_VIEW_DESC uavd;
-			uavd.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+			uavd.Format = format;
 			uavd.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
 			uavd.Buffer.FirstElement = 0;
-			uavd.Buffer.NumElements  = m_size/16;
+			uavd.Buffer.NumElements = m_size / 16;
 			uavd.Buffer.Flags = 0;
 			DX_CHECK(device->CreateUnorderedAccessView(m_ptr
 				, &uavd
 				, &m_uav
-				) );
+				));
 		}
 		else if (m_dynamic)
 		{
@@ -2340,7 +2291,7 @@ namespace bgfx
 			DX_CHECK(device->CreateBuffer(&desc
 				, NULL
 				, &m_ptr
-				) );
+				));
 		}
 		else
 		{
@@ -2355,35 +2306,49 @@ namespace bgfx
 			DX_CHECK(device->CreateBuffer(&desc
 				, &srd
 				, &m_ptr
-				) );
+				));
 		}
 
 		if (needSrv)
 		{
 			D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
-			srvd.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+			srvd.Format = format;
 			srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
 			srvd.Buffer.FirstElement = 0;
-			srvd.Buffer.NumElements = m_size/16;
+			srvd.Buffer.NumElements = m_size / 16;
 			DX_CHECK(device->CreateShaderResourceView(m_ptr
 				, &srvd
 				, &m_srv
-				) );
+				));
 		}
 	}
 
-	void VertexBufferD3D11::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard)
+	void BufferD3D11::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard)
 	{
 		ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
 		BX_CHECK(m_dynamic, "Must be dynamic!");
 
 		D3D11_MAPPED_SUBRESOURCE mapped;
-		D3D11_MAP type = m_dynamic && ( (0 == _offset && m_size == _size) || _discard) ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE;
-		DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped) );
-		memcpy( (uint8_t*)mapped.pData + _offset, _data, _size);
+		D3D11_MAP type = m_dynamic && ( (0 == _offset && m_size == _size) || _discard)
+			? D3D11_MAP_WRITE_DISCARD
+			: D3D11_MAP_WRITE_NO_OVERWRITE
+			;
+		DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped));
+		memcpy((uint8_t*)mapped.pData + _offset, _data, _size);
 		deviceCtx->Unmap(m_ptr, 0);
 	}
 
+	void VertexBufferD3D11::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint8_t _flags)
+	{
+		m_decl = _declHandle;
+		uint16_t stride = isValid(_declHandle)
+			? s_renderD3D11->m_vertexDecls[_declHandle.idx].m_stride
+			: 0
+			;
+
+		BufferD3D11::create(_size, _data, _flags, stride);
+	}
+
 	void ShaderD3D11::create(const Memory* _mem)
 	{
 		bx::MemoryReader reader(_mem->data, _mem->size);
@@ -3229,16 +3194,20 @@ namespace bgfx
 								}
 								break;
 
-							case ComputeBinding::Buffer:
+							case ComputeBinding::IndexBuffer:
+							case ComputeBinding::VertexBuffer:
 								{
-									const VertexBufferD3D11& vertexBuffer = m_vertexBuffers[bind.m_idx];
+									const BufferD3D11& buffer = ComputeBinding::IndexBuffer == bind.m_type
+										? m_indexBuffers[bind.m_idx]
+										: m_vertexBuffers[bind.m_idx]
+										;
 									if (Access::Read != bind.m_access)
 									{
-										uav[ii] = vertexBuffer.m_uav;
+										uav[ii] = buffer.m_uav;
 									}
 									else
 									{
-										srv[ii] = vertexBuffer.m_srv;
+										srv[ii] = buffer.m_srv;
 									}
 								}
 								break;

+ 15 - 27
src/renderer_d3d11.h

@@ -72,16 +72,18 @@ BX_PRAGMA_DIAGNOSTIC_POP()
 
 namespace bgfx
 {
-	struct IndexBufferD3D11
+	struct BufferD3D11
 	{
-		IndexBufferD3D11()
+		BufferD3D11()
 			: m_ptr(NULL)
+			, m_srv(NULL)
+			, m_uav(NULL)
 			, m_dynamic(false)
 		{
 		}
 
-		void create(uint32_t _size, void* _data);
-		void update(uint32_t _offset, uint32_t _size, void* _data);
+		void create(uint32_t _size, void* _data, uint8_t _flags, uint16_t _stride = 0, bool _vertex = true);
+		void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
 
 		void destroy()
 		{
@@ -90,44 +92,30 @@ namespace bgfx
 				DX_RELEASE(m_ptr, 0);
 				m_dynamic = false;
 			}
+
+			DX_RELEASE(m_srv, 0);
+			DX_RELEASE(m_uav, 0);
 		}
 
 		ID3D11Buffer* m_ptr;
+		ID3D11ShaderResourceView*  m_srv;
+		ID3D11UnorderedAccessView* m_uav;
 		uint32_t m_size;
 		bool m_dynamic;
 	};
 
-	struct VertexBufferD3D11
+	typedef BufferD3D11 IndexBufferD3D11;
+
+	struct VertexBufferD3D11 : public BufferD3D11
 	{
 		VertexBufferD3D11()
-			: m_ptr(NULL)
-			, m_srv(NULL)
-			, m_uav(NULL)
-			, m_dynamic(false)
+			: BufferD3D11()
 		{
 		}
 
 		void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint8_t _flags);
-		void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
-
-		void destroy()
-		{
-			if (NULL != m_ptr)
-			{
-				DX_RELEASE(m_ptr, 0);
-				m_dynamic = false;
-			}
 
-			DX_RELEASE(m_srv, 0);
-			DX_RELEASE(m_uav, 0);
-		}
-
-		ID3D11Buffer* m_ptr;
-		ID3D11ShaderResourceView* m_srv;
-		ID3D11UnorderedAccessView* m_uav;
-		uint32_t m_size;
 		VertexDeclHandle m_decl;
-		bool m_dynamic;
 	};
 
 	struct ShaderD3D11

+ 14 - 14
src/renderer_d3d9.cpp

@@ -189,7 +189,7 @@ namespace bgfx
 
 	static TextureFormatInfo s_textureFormat[] =
 	{
-		{ D3DFMT_DXT1          }, // BC1 
+		{ D3DFMT_DXT1          }, // BC1
 		{ D3DFMT_DXT3          }, // BC2
 		{ D3DFMT_DXT5          }, // BC3
 		{ D3DFMT_UNKNOWN       }, // BC4
@@ -229,11 +229,11 @@ namespace bgfx
 		{ D3DFMT_A2B10G10R10   }, // RGB10A2
 		{ D3DFMT_UNKNOWN       }, // R11G11B10F
 		{ D3DFMT_UNKNOWN       }, // UnknownDepth
-		{ D3DFMT_D16           }, // D16  
-		{ D3DFMT_D24X8         }, // D24  
+		{ D3DFMT_D16           }, // D16
+		{ D3DFMT_D24X8         }, // D24
 		{ D3DFMT_D24S8         }, // D24S8
-		{ D3DFMT_D32           }, // D32  
-		{ D3DFMT_DF16          }, // D16F 
+		{ D3DFMT_D32           }, // D32
+		{ D3DFMT_DF16          }, // D16F
 		{ D3DFMT_DF24          }, // D24F
 		{ D3DFMT_D32F_LOCKABLE }, // D32F
 		{ D3DFMT_S8_LOCKABLE   }, // D0S8
@@ -670,7 +670,7 @@ namespace bgfx
 			m_vertexBuffers[_handle.idx].destroy();
 		}
 
-		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) BX_OVERRIDE
+		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t /*_flags*/) BX_OVERRIDE
 		{
 			m_indexBuffers[_handle.idx].create(_size, NULL);
 		}
@@ -1075,7 +1075,7 @@ namespace bgfx
 
 			HRESULT hr;
 
-			do 
+			do
 			{
 				hr = m_device->Reset(&m_params);
 			} while (FAILED(hr) );
@@ -1122,7 +1122,7 @@ namespace bgfx
 					{
 						do
 						{
-							do 
+							do
 							{
 								hr = m_device->TestCooperativeLevel();
 							}
@@ -1785,7 +1785,7 @@ namespace bgfx
 				, 0
 				, pool
 				, &m_ptr
-				, NULL 
+				, NULL
 				) );
 
 		if (NULL != _data)
@@ -1811,7 +1811,7 @@ namespace bgfx
 					, 0
 					, D3DPOOL_DEFAULT
 					, &m_ptr
-					, NULL 
+					, NULL
 					) );
 		}
 	}
@@ -2458,7 +2458,7 @@ namespace bgfx
 		uint8_t* bits = s_renderD3D9->m_updateTextureBits + _rect.m_y*dstpitch + _rect.m_x*bpp/8;
 
 		const bool convert = m_textureFormat != m_requestedFormat;
-		
+
 		uint8_t* data = _mem->data;
 		uint8_t* temp = NULL;
 
@@ -2955,7 +2955,7 @@ namespace bgfx
 				{
 					bool enable = 0 != newStencil;
 					DX_CHECK(device->SetRenderState(D3DRS_STENCILENABLE, enable) );
-					
+
 					if (0 != newStencil)
 					{
 						uint32_t fstencil = unpackStencil(0, newStencil);
@@ -3027,7 +3027,7 @@ namespace bgfx
 					}
 
 					if (BGFX_STATE_DEPTH_WRITE & changedFlags)
-					{ 
+					{
 						DX_CHECK(device->SetRenderState(D3DRS_ZWRITEENABLE, !!(BGFX_STATE_DEPTH_WRITE & newFlags) ) );
 					}
 
@@ -3139,7 +3139,7 @@ namespace bgfx
 						device->SetPixelShader(program.m_fsh->m_pixelShader);
 					}
 
-					programChanged = 
+					programChanged =
 						constantsChanged = true;
 				}
 

+ 12 - 4
src/renderer_gl.cpp

@@ -1469,7 +1469,7 @@ namespace bgfx
 			m_vertexBuffers[_handle.idx].destroy();
 		}
 
-		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size) BX_OVERRIDE
+		void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint8_t /*_flags*/) BX_OVERRIDE
 		{
 			m_indexBuffers[_handle.idx].create(_size, NULL);
 		}
@@ -4322,10 +4322,18 @@ namespace bgfx
 									}
 									break;
 
-								case ComputeBinding::Buffer:
+								case ComputeBinding::IndexBuffer:
 									{
-										const VertexBufferGL& vertexBuffer = m_vertexBuffers[bind.m_idx];
-										GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, vertexBuffer.m_id) );
+										const IndexBufferGL& buffer = m_indexBuffers[bind.m_idx];
+										GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id));
+										barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
+									}
+									break;
+
+								case ComputeBinding::VertexBuffer:
+									{
+										const VertexBufferGL& buffer = m_vertexBuffers[bind.m_idx];
+										GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ii, buffer.m_id));
 										barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
 									}
 									break;

+ 1 - 1
src/renderer_null.cpp

@@ -57,7 +57,7 @@ namespace bgfx
 		{
 		}
 
-		void createDynamicIndexBuffer(IndexBufferHandle /*_handle*/, uint32_t /*_size*/) BX_OVERRIDE
+		void createDynamicIndexBuffer(IndexBufferHandle /*_handle*/, uint32_t /*_size*/, uint8_t /*_flags*/) BX_OVERRIDE
 		{
 		}