Browse Source

Checkin before changing generic buffers

Marko Pintera 13 years ago
parent
commit
a5a4cbc346

+ 7 - 1
CamelotD3D11RenderSystem/Include/CmD3D11GenericBuffer.h

@@ -9,7 +9,7 @@ namespace CamelotEngine
 	class CM_D3D11_EXPORT D3D11GenericBuffer : public GenericBuffer
     {
     public:
-		D3D11GenericBuffer(GenericBufferType type, GpuBufferUsage usage);
+		D3D11GenericBuffer(UINT32 elementCount, UINT32 elementSize, GenericBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
         ~D3D11GenericBuffer();
 
 		/**
@@ -38,5 +38,11 @@ namespace CamelotEngine
 		*/
 		void copyData(GenericBuffer& srcBuffer, UINT32 srcOffset, 
 			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false);
+
+	private:
+		ID3D11Buffer* mBuffer;
+
+		ID3D11ShaderResourceView* createSRV(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements);
+		ID3D11UnorderedAccessView* createUAV(UINT32 firstElement, UINT32 numElements);
     };
 }

+ 172 - 4
CamelotD3D11RenderSystem/Source/CmD3D11GenericBuffer.cpp

@@ -1,13 +1,181 @@
 #include "CmD3D11GenericBuffer.h"
+#include "CmD3D11RenderSystem.h"
+#include "CmD3D11Device.h"
+#include "CmException.h"
 
 namespace CamelotEngine
 {
-	D3D11GenericBuffer::D3D11GenericBuffer(GenericBufferType type, GpuBufferUsage usage) 
-		: GenericBuffer(type, usage)
-	{  }
+	D3D11GenericBuffer::D3D11GenericBuffer(UINT32 elementCount, UINT32 elementSize, GenericBufferType type, GpuBufferUsage usage, bool randomGpuWrite, bool useCounter) 
+		: GenericBuffer(elementCount, elementSize, type, usage, randomGpuWrite, useCounter), mBuffer(nullptr)
+	{  
+		D3D11_BUFFER_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		if(type == GBT_APPENDCONSUME && !randomGpuWrite)
+			CM_EXCEPT(InvalidParametersException, "Append/Consume buffer must be created with randomGpuWrite enabled.");
+
+		if(type != GBT_STRUCTURED && useCounter)
+			CM_EXCEPT(InvalidParametersException, "Counter can only be used with a structured buffer.");
+
+		if(useCounter && !randomGpuWrite)
+			CM_EXCEPT(InvalidParametersException, "Counter can only be used with buffers that have randomGpuWrite enabled.");
+
+		if(type == GBT_STRUCTURED || type == GBT_APPENDCONSUME)
+		{
+			desc.ByteWidth = elementCount * elementSize;
+			desc.StructureByteStride = elementSize;
+			desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
+		}
+		else if(type == GBT_RAW)
+		{
+			desc.ByteWidth = elementCount * elementSize;
+			desc.StructureByteStride = 0;
+			desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
+		}
+		else if(type == GBT_INDIRECTARGUMENT)
+		{
+			desc.ByteWidth = elementCount * elementSize;
+			desc.StructureByteStride = 0;
+			desc.MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
+		}
+
+		if(!randomGpuWrite)
+		{
+			desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+			if(usage == GBU_STATIC)
+			{
+				desc.Usage = D3D11_USAGE_DEFAULT;
+				desc.CPUAccessFlags = 0;
+			}
+			else if(usage == GBU_DYNAMIC)
+			{
+				desc.Usage = D3D11_USAGE_DYNAMIC;
+				desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+			}
+			else
+				CM_EXCEPT(InternalErrorException, "Invalid usage flag: " + toString(usage));
+		}
+		else
+		{
+			desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
+			desc.Usage = D3D11_USAGE_DEFAULT;
+			desc.CPUAccessFlags = 0;
+		}
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateBuffer(&desc, nullptr, &mBuffer);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create D3D11 buffer: " + msg);
+		}
+	}
 
 	D3D11GenericBuffer::~D3D11GenericBuffer() 
-	{ }
+	{
+		SAFE_RELEASE(mBuffer);
+	}
+
+	ID3D11ShaderResourceView* D3D11GenericBuffer::createSRV(UINT32 firstElement, UINT32 elementWidth, UINT32 numElements)
+	{
+		if(mType == GBT_APPENDCONSUME)
+			CM_EXCEPT(InvalidParametersException, "Cannot create ShaderResourceView for an append/consume buffer.");
+
+		D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		if(mType == GBT_STRUCTURED)
+		{
+			desc.Format = DXGI_FORMAT_UNKNOWN;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+			desc.Buffer.ElementOffset = firstElement * elementWidth;
+			desc.Buffer.ElementWidth = elementWidth;
+		}
+		else if(mType == GBT_RAW)
+		{
+			desc.Format = DXGI_FORMAT_R32_TYPELESS;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
+			desc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW;
+			desc.BufferEx.FirstElement = firstElement;
+			desc.BufferEx.NumElements = numElements;
+		}
+		else if(mType == GBT_INDIRECTARGUMENT)
+		{
+			desc.Format = DXGI_FORMAT_R32_UINT;
+			desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+			desc.Buffer.ElementOffset = firstElement * elementWidth;
+			desc.Buffer.ElementWidth = elementWidth;
+		}
+
+		ID3D11ShaderResourceView* srv = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateShaderResourceView(mBuffer, &desc, &srv);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create ShaderResourceView: " + msg);
+		}
+
+		return srv;
+	}
+
+	ID3D11UnorderedAccessView* D3D11GenericBuffer::createUAV(UINT32 firstElement, UINT32 numElements)
+	{
+		D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
+		ZeroMemory(&desc, sizeof(desc));
+
+		desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
+
+		if(mType == GBT_STRUCTURED)
+		{
+			desc.Format = DXGI_FORMAT_UNKNOWN;
+			desc.Buffer.FirstElement = firstElement;
+			desc.Buffer.NumElements = numElements;
+
+			if(mUseCounter)
+				desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_COUNTER;
+			else
+				desc.Buffer.Flags = 0;
+		}
+		else if(mType == GBT_RAW)
+		{
+			desc.Format = DXGI_FORMAT_R32_TYPELESS;
+			desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
+			desc.Buffer.FirstElement = firstElement;
+			desc.Buffer.NumElements = numElements;
+		}
+		else if(mType == GBT_INDIRECTARGUMENT)
+		{
+			desc.Format = DXGI_FORMAT_R32_UINT;
+			desc.Buffer.Flags = 0;
+			desc.Buffer.FirstElement = firstElement;
+			desc.Buffer.NumElements = numElements;
+		}
+		else if(mType == GBT_APPENDCONSUME)
+		{
+			desc.Format = DXGI_FORMAT_UNKNOWN;
+			desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND;
+			desc.Buffer.FirstElement = firstElement;
+			desc.Buffer.NumElements = numElements;
+		}
+
+		ID3D11UnorderedAccessView* uav = nullptr;
+
+		D3D11RenderSystem* d3d11rs = static_cast<D3D11RenderSystem*>(D3D11RenderSystem::instancePtr());
+		HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateUnorderedAccessView(mBuffer, &desc, &uav);
+
+		if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError())
+		{
+			String msg = d3d11rs->getPrimaryDevice().getErrorDescription();
+			CM_EXCEPT(RenderingAPIException, "Cannot create UnorderedAccessView: " + msg);
+		}
+
+		return uav;
+	}
 
 	void* D3D11GenericBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
 	{

+ 4 - 2
CamelotD3D11RenderSystem/Source/CmD3D11HardwareBuffer.cpp

@@ -15,6 +15,9 @@ namespace CamelotEngine
 		mBufferType(btype),
 		mDevice(device)
 	{
+		if(streamOut && btype != VERTEX_BUFFER)
+			CM_EXCEPT(InvalidParametersException, "Stream out flag is only supported on vertex buffers");
+
 		mSizeInBytes = sizeBytes;
 		mDesc.ByteWidth = static_cast<UINT>(sizeBytes);
 		
@@ -23,7 +26,6 @@ namespace CamelotEngine
 		if (useSystemMemory)
 		{
 			mDesc.Usage = D3D11_USAGE_STAGING;
-			//A D3D11_USAGE_STAGING Resource cannot be bound to any parts of the graphics pipeline, so therefore cannot have any BindFlags bits set.
 			mDesc.BindFlags = 0;
 			mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ ;// A D3D11_USAGE_STAGING Resource must have at least one CPUAccessFlag bit set.
 
@@ -38,7 +40,7 @@ namespace CamelotEngine
 		}
 
 		// Check of stream out flag
-		if (streamOut && btype != CONSTANT_BUFFER)
+		if (streamOut)
 		{
 			mDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT;
 		}

+ 7 - 4
CamelotRenderer/Include/CmGenericBuffer.h

@@ -16,12 +16,11 @@ namespace CamelotEngine
 	class CM_EXPORT GenericBuffer
     {
     public:
-        GenericBuffer(GenericBufferType type, GpuBufferUsage usage)
-			:mType(type), mUsage(usage)
+        GenericBuffer(UINT32 elementCount, UINT32 elementSize, GenericBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false)
+			:mElementCount(elementCount), mElementSize(elementSize), mType(type), mUsage(usage), mRandomGpuWrite(randomGpuWrite), mUseCounter(useCounter)
         {  }
         virtual ~GenericBuffer() {}
 
-
 		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
 		virtual void unlock() = 0;
 
@@ -31,8 +30,12 @@ namespace CamelotEngine
 		virtual void copyData(GenericBuffer& srcBuffer, UINT32 srcOffset, 
 			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false) = 0;
 
-	private:
+	protected:
 		GenericBufferType mType;
 		GpuBufferUsage mUsage;
+		bool mRandomGpuWrite;
+		bool mUseCounter;
+		UINT32 mElementCount;
+		UINT32 mElementSize;
     };
 }