00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
00016 #define BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
00017
00018
00019 #include <windows.h>
00020 #include <crtdbg.h>
00021 #include <d3d11.h>
00022 #include <d3dx11.h>
00023 #include <d3dcompiler.h>
00024
00025 #ifndef SAFE_RELEASE
00026 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
00027 #endif
00028
00032 template <typename ElementType> class btDX11Buffer
00033 {
00034 protected:
00035 ID3D11Device* m_d3dDevice;
00036 ID3D11DeviceContext* m_d3dDeviceContext;
00037
00038 ID3D11Buffer* m_Buffer;
00039 ID3D11ShaderResourceView* m_SRV;
00040 ID3D11UnorderedAccessView* m_UAV;
00041 btAlignedObjectArray< ElementType >* m_CPUBuffer;
00042
00043
00044
00045 ID3D11Buffer* m_readBackBuffer;
00046
00047 int m_gpuSize;
00048 bool m_onGPU;
00049
00050 bool m_readOnlyOnGPU;
00051
00052 bool createBuffer( ID3D11Buffer *preexistingBuffer = 0)
00053 {
00054 HRESULT hr = S_OK;
00055
00056
00057 if( preexistingBuffer )
00058 {
00059 m_Buffer = preexistingBuffer;
00060 } else {
00061 D3D11_BUFFER_DESC buffer_desc;
00062 ZeroMemory(&buffer_desc, sizeof(buffer_desc));
00063 buffer_desc.Usage = D3D11_USAGE_DEFAULT;
00064 if( m_readOnlyOnGPU )
00065 buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
00066 else
00067 buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
00068 buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
00069
00070 buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
00071
00072 if( buffer_desc.ByteWidth == 0 )
00073 buffer_desc.ByteWidth = sizeof(ElementType);
00074 buffer_desc.StructureByteStride = sizeof(ElementType);
00075 hr = m_d3dDevice->CreateBuffer(&buffer_desc, NULL, &m_Buffer);
00076 if( FAILED( hr ) )
00077 return (hr==S_OK);
00078 }
00079
00080 if( m_readOnlyOnGPU )
00081 {
00082 D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
00083 ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
00084 srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
00085 srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
00086
00087 srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
00088 if( srvbuffer_desc.Buffer.ElementWidth == 0 )
00089 srvbuffer_desc.Buffer.ElementWidth = 1;
00090 hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
00091 if( FAILED( hr ) )
00092 return (hr==S_OK);
00093 } else {
00094
00095 D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
00096 ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
00097 srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
00098 srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
00099
00100 srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
00101 if( srvbuffer_desc.Buffer.ElementWidth == 0 )
00102 srvbuffer_desc.Buffer.ElementWidth = 1;
00103 hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
00104 if( FAILED( hr ) )
00105 return (hr==S_OK);
00106
00107
00108 D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc;
00109 ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc));
00110 uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
00111 uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
00112
00113 uavbuffer_desc.Buffer.NumElements = m_CPUBuffer->size();
00114 if( uavbuffer_desc.Buffer.NumElements == 0 )
00115 uavbuffer_desc.Buffer.NumElements = 1;
00116 hr = m_d3dDevice->CreateUnorderedAccessView(m_Buffer, &uavbuffer_desc, &m_UAV);
00117 if( FAILED( hr ) )
00118 return (hr==S_OK);
00119
00120
00121 D3D11_BUFFER_DESC readback_buffer_desc;
00122 ZeroMemory(&readback_buffer_desc, sizeof(readback_buffer_desc));
00123
00124 readback_buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
00125 readback_buffer_desc.Usage = D3D11_USAGE_STAGING;
00126 readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
00127 readback_buffer_desc.StructureByteStride = sizeof(ElementType);
00128 hr = m_d3dDevice->CreateBuffer(&readback_buffer_desc, NULL, &m_readBackBuffer);
00129 if( FAILED( hr ) )
00130 return (hr==S_OK);
00131 }
00132
00133 m_gpuSize = m_CPUBuffer->size();
00134 return true;
00135 }
00136
00137
00138
00139 public:
00140 btDX11Buffer( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext, btAlignedObjectArray< ElementType > *CPUBuffer, bool readOnly )
00141 {
00142 m_d3dDevice = d3dDevice;
00143 m_d3dDeviceContext = d3dDeviceContext;
00144 m_Buffer = 0;
00145 m_SRV = 0;
00146 m_UAV = 0;
00147 m_readBackBuffer = 0;
00148
00149 m_CPUBuffer = CPUBuffer;
00150
00151 m_gpuSize = 0;
00152 m_onGPU = false;
00153
00154 m_readOnlyOnGPU = readOnly;
00155 }
00156
00157 virtual ~btDX11Buffer()
00158 {
00159 SAFE_RELEASE(m_Buffer);
00160 SAFE_RELEASE(m_SRV);
00161 SAFE_RELEASE(m_UAV);
00162 SAFE_RELEASE(m_readBackBuffer);
00163 }
00164
00165 ID3D11ShaderResourceView* &getSRV()
00166 {
00167 return m_SRV;
00168 }
00169
00170 ID3D11UnorderedAccessView* &getUAV()
00171 {
00172 return m_UAV;
00173 }
00174
00175 ID3D11Buffer* &getBuffer()
00176 {
00177 return m_Buffer;
00178 }
00179
00183 bool moveToGPU()
00184 {
00185
00186 if( (m_CPUBuffer->size() > m_gpuSize ) )
00187 m_onGPU = false;
00188 if( !m_onGPU && m_CPUBuffer->size() > 0 )
00189 {
00190
00191
00192 if( !m_Buffer || (m_CPUBuffer->size() != m_gpuSize) )
00193 {
00194 SAFE_RELEASE(m_Buffer);
00195 SAFE_RELEASE(m_SRV);
00196 SAFE_RELEASE(m_UAV);
00197 SAFE_RELEASE(m_readBackBuffer);
00198 if( !createBuffer() )
00199 {
00200 btAssert("Buffer creation failed.");
00201 return false;
00202 }
00203 }
00204
00205 if( m_gpuSize > 0 )
00206 {
00207 D3D11_BOX destRegion;
00208 destRegion.left = 0;
00209 destRegion.front = 0;
00210 destRegion.top = 0;
00211 destRegion.bottom = 1;
00212 destRegion.back = 1;
00213 destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
00214 m_d3dDeviceContext->UpdateSubresource(m_Buffer, 0, &destRegion, &((*m_CPUBuffer)[0]), 0, 0);
00215
00216 m_onGPU = true;
00217 }
00218
00219 }
00220
00221 return true;
00222 }
00223
00227 bool moveFromGPU()
00228 {
00229 if( m_CPUBuffer->size() > 0 )
00230 {
00231 if( m_onGPU && !m_readOnlyOnGPU )
00232 {
00233
00234 D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
00235
00236
00237 D3D11_BOX destRegion;
00238 destRegion.left = 0;
00239 destRegion.front = 0;
00240 destRegion.top = 0;
00241 destRegion.bottom = 1;
00242 destRegion.back = 1;
00243
00244 destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
00245 m_d3dDeviceContext->CopySubresourceRegion(
00246 m_readBackBuffer,
00247 0,
00248 0,
00249 0,
00250 0 ,
00251 m_Buffer,
00252 0,
00253 &destRegion
00254 );
00255
00256 m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
00257
00258 memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
00259 m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
00260
00261 m_onGPU = false;
00262 }
00263 }
00264
00265 return true;
00266 }
00267
00268
00273 bool copyFromGPU()
00274 {
00275 if( m_CPUBuffer->size() > 0 )
00276 {
00277 if( m_onGPU && !m_readOnlyOnGPU )
00278 {
00279
00280 D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
00281
00282 D3D11_BOX destRegion;
00283 destRegion.left = 0;
00284 destRegion.front = 0;
00285 destRegion.top = 0;
00286 destRegion.bottom = 1;
00287 destRegion.back = 1;
00288
00289 destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
00290 m_d3dDeviceContext->CopySubresourceRegion(
00291 m_readBackBuffer,
00292 0,
00293 0,
00294 0,
00295 0 ,
00296 m_Buffer,
00297 0,
00298 &destRegion
00299 );
00300
00301 m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
00302
00303 memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
00304 m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
00305 }
00306 }
00307
00308 return true;
00309 }
00310
00315 virtual void changedOnCPU()
00316 {
00317 m_onGPU = false;
00318 }
00319 };
00320
00321
00322
00323 #endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H