private void RunComputeShader( D3D11ComputeShader pComputeShader, D3D11ShaderResourceView[] pShaderResourceViews, D3D11Buffer pNeverChangesCBCS, D3D11Buffer pCBCS, //T pCSData, //uint dwNumDataBytes, D3D11UnorderedAccessView pUnorderedAccessView, uint x, uint y, uint z) //where T : struct { var d3dContext = this.deviceResources.D3DContext; d3dContext.ComputeShaderSetShader(pComputeShader, null); d3dContext.ComputeShaderSetShaderResources(0, pShaderResourceViews); d3dContext.ComputeShaderSetUnorderedAccessViews(0, new[] { pUnorderedAccessView }, new[] { 0U }); //if (pCBCS != null) //{ // d3dContext.UpdateSubresource(pCBCS, D3D11Utils.CalcSubresource(0, 0, 1), null, pCSData, dwNumDataBytes, dwNumDataBytes); //} if (pNeverChangesCBCS != null && pCBCS != null) { d3dContext.ComputeShaderSetConstantBuffers(0, new[] { pNeverChangesCBCS, pCBCS }); } if (pNeverChangesCBCS != null && pCBCS == null) { d3dContext.ComputeShaderSetConstantBuffers(0, new[] { pNeverChangesCBCS }); } if (pNeverChangesCBCS == null && pCBCS != null) { d3dContext.ComputeShaderSetConstantBuffers(0, new[] { pCBCS }); } d3dContext.Dispatch(x, y, z); d3dContext.ComputeShaderSetUnorderedAccessViews(0, new D3D11UnorderedAccessView[] { null }, new[] { 0U }); d3dContext.ComputeShaderSetShaderResources(0, new D3D11ShaderResourceView[] { null, null, null }); d3dContext.ComputeShaderSetConstantBuffers(0, new D3D11Buffer[] { }); }
static void RunComputeShader( D3D11DeviceContext pd3dImmediateContext, D3D11ComputeShader pComputeShader, D3D11ShaderResourceView[] pShaderResourceViews, D3D11UnorderedAccessView pUnorderedAccessView, uint X, uint Y, uint Z) { pd3dImmediateContext.ComputeShaderSetShader(pComputeShader, null); pd3dImmediateContext.ComputeShaderSetShaderResources(0, pShaderResourceViews); pd3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new[] { pUnorderedAccessView }, new[] { 0U }); pd3dImmediateContext.Dispatch(X, Y, Z); pd3dImmediateContext.ComputeShaderSetShader(null, null); pd3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new D3D11UnorderedAccessView[] { null }, new[] { 0U }); pd3dImmediateContext.ComputeShaderSetShaderResources(0, new D3D11ShaderResourceView[] { null, null }); pd3dImmediateContext.ComputeShaderSetConstantBuffers(0, new D3D11Buffer[] { null }); }
// Both scan input and scanned output are in the buffer resource referred by p0SRV and p0UAV. // The buffer resource referred by p1SRV and p1UAV is used as intermediate result, // and should be as large as the input/output buffer public void Scan( D3D11DeviceContext d3dImmediateContext, // How many elements in the input buffer are to be scanned? uint numToScan, // SRV and UAV of the buffer which contains the input data, // and the scanned result when the function returns D3D11ShaderResourceView p0SRV, D3D11UnorderedAccessView p0UAV, // SRV and UAV of an aux buffer, which must be the same size as the input/output buffer D3D11ShaderResourceView p1SRV, D3D11UnorderedAccessView p1UAV) { // first pass, scan in each bucket { d3dImmediateContext.ComputeShaderSetShader(this.m_pScanCS, null); d3dImmediateContext.ComputeShaderSetShaderResources(0, new[] { p0SRV }); d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new[] { p1UAV }, new[] { 0u }); d3dImmediateContext.Dispatch((uint)Math.Ceiling(numToScan / 128.0f), 1, 1); d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new D3D11UnorderedAccessView[] { null }, new[] { 0u }); } // second pass, record and scan the sum of each bucket { d3dImmediateContext.ComputeShaderSetShader(this.m_pScan2CS, null); d3dImmediateContext.ComputeShaderSetShaderResources(0, new[] { p1SRV }); d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new[] { this.m_pAuxBufUAV }, new[] { 0u }); d3dImmediateContext.Dispatch(1, 1, 1); d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new D3D11UnorderedAccessView[] { null }, new[] { 0u }); } // last pass, add the buckets scanned result to each bucket to get the final result { d3dImmediateContext.ComputeShaderSetShader(this.m_pScan3CS, null); d3dImmediateContext.ComputeShaderSetShaderResources(0, new[] { p1SRV, this.m_pAuxBufRV }); d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new[] { p0UAV }, new[] { 0u }); d3dImmediateContext.Dispatch((uint)Math.Ceiling(numToScan / 128.0f), 1, 1); } // Unbind resources for CS d3dImmediateContext.ComputeShaderSetUnorderedAccessViews(0, new D3D11UnorderedAccessView[] { null }, new[] { 0u }); d3dImmediateContext.ComputeShaderSetShaderResources(0, new D3D11ShaderResourceView[] { null, null }); d3dImmediateContext.ComputeShaderSetConstantBuffers(0, new D3D11Buffer[] { }); }
public void CreateDeviceDependentResources(DeviceResources resources) { var d3dDevice = resources.D3DDevice; this.m_pScanCS = d3dDevice.CreateComputeShader(File.ReadAllBytes("ScanInBucketComputeShader.cso"), null); this.m_pScan2CS = d3dDevice.CreateComputeShader(File.ReadAllBytes("ScanBucketResultComputeShader.cso"), null); this.m_pScan3CS = d3dDevice.CreateComputeShader(File.ReadAllBytes("ScanAddBucketResultComputeShader.cso"), null); this.m_pAuxBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, StructureByteStride = 4 * 2, // If scan types other than uint2, remember change here ByteWidth = 4 * 2 * 128, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); this.m_pAuxBufRV = d3dDevice.CreateShaderResourceView(this.m_pAuxBuf, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = 128 } }); this.m_pAuxBufUAV = d3dDevice.CreateUnorderedAccessView(this.m_pAuxBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = 128 } }); }
public void CreateWindowSizeDependentResources() { uint width = this.deviceResources.BackBufferWidth; uint height = this.deviceResources.BackBufferHeight; // Create fragment count buffer this.fragmentCountBuffer = this.deviceResources.D3DDevice.CreateTexture2D( new D3D11Texture2DDesc( DxgiFormat.R32UInt, width, height, 1, 1, D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource)); // Create prefix sum buffer this.prefixSum = this.deviceResources.D3DDevice.CreateBuffer(new D3D11BufferDesc( width * height * 4, D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource, D3D11Usage.Default, D3D11CpuAccessOptions.None, D3D11ResourceMiscOptions.None, 4)); // Create the deep frame buffer. // This simple allocation scheme for the deep frame buffer allocates space for 8 times the size of the // frame buffer, which means that it can hold an average of 8 fragments per pixel. This will usually waste some // space, and in some cases of high overdraw the buffer could run into problems with overflow. It // may be useful to make the buffer size more intelligent to avoid these problems. this.deepBuffer = this.deviceResources.D3DDevice.CreateBuffer(new D3D11BufferDesc( width * height * 8 * 4, D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource, D3D11Usage.Default, D3D11CpuAccessOptions.None, D3D11ResourceMiscOptions.None, 4)); // Create deep frame buffer for color this.deepBufferColor = this.deviceResources.D3DDevice.CreateBuffer(new D3D11BufferDesc( width * height * 8 * 4 * 1, D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource, D3D11Usage.Default, D3D11CpuAccessOptions.None, D3D11ResourceMiscOptions.None, 4 * 1)); this.fragmentCountRV = this.deviceResources.D3DDevice.CreateShaderResourceView( this.fragmentCountBuffer, new D3D11ShaderResourceViewDesc( D3D11SrvDimension.Texture2D, DxgiFormat.R32UInt, 0, 1)); this.fragmentCountUAV = this.deviceResources.D3DDevice.CreateUnorderedAccessView( this.fragmentCountBuffer, new D3D11UnorderedAccessViewDesc( D3D11UavDimension.Texture2D, DxgiFormat.R32UInt, 0)); this.prefixSumUAV = this.deviceResources.D3DDevice.CreateUnorderedAccessView( this.prefixSum, new D3D11UnorderedAccessViewDesc( D3D11UavDimension.Buffer, DxgiFormat.R32UInt, 0, width * height)); this.deepBufferUAV = this.deviceResources.D3DDevice.CreateUnorderedAccessView( this.deepBuffer, new D3D11UnorderedAccessViewDesc( D3D11UavDimension.Buffer, DxgiFormat.R32Float, 0, width * height * 8)); this.deepBufferColorUAV = this.deviceResources.D3DDevice.CreateUnorderedAccessView( this.deepBufferColor, new D3D11UnorderedAccessViewDesc( D3D11UavDimension.Buffer, DxgiFormat.B8G8R8A8UNorm, 0, width * height * 8)); this.screenTexture = this.deviceResources.D3DDevice.CreateTexture2D( new D3D11Texture2DDesc( DxgiFormat.B8G8R8A8UNorm, width, height, 1, 1, D3D11BindOptions.RenderTarget | D3D11BindOptions.UnorderedAccess)); this.screenTextureRTV = this.deviceResources.D3DDevice.CreateRenderTargetView(this.screenTexture, null); this.screenTextureUAV = this.deviceResources.D3DDevice.CreateUnorderedAccessView(this.screenTexture, new D3D11UnorderedAccessViewDesc(D3D11UavDimension.Texture2D, DxgiFormat.B8G8R8A8UNorm, 0)); }
static void CreateResources() { var d3dDevice = deviceResources.D3DDevice; // Create the Bitonic Sort Compute Shader g_pComputeShaderBitonic = d3dDevice.CreateComputeShader(File.ReadAllBytes("CSSortBitonic.cso"), null); // Create the Matrix Transpose Compute Shader g_pComputeShaderTranspose = d3dDevice.CreateComputeShader(File.ReadAllBytes("CSSortTranspose.cso"), null); // Create the Const Buffer var constantBufferDesc = new D3D11BufferDesc(ConstantBufferData.Size, D3D11BindOptions.ConstantBuffer); g_pCB = d3dDevice.CreateBuffer(constantBufferDesc); // Create the Buffer of Elements // Create 2 buffers for switching between when performing the transpose var bufferDesc = new D3D11BufferDesc( NUM_ELEMENTS * sizeof(uint), D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource, D3D11Usage.Default, D3D11CpuAccessOptions.None, D3D11ResourceMiscOptions.BufferStructured, sizeof(uint)); g_pBuffer1 = d3dDevice.CreateBuffer(bufferDesc); g_pBuffer2 = d3dDevice.CreateBuffer(bufferDesc); // Create the Shader Resource View for the Buffers // This is used for reading the buffer during the transpose var srvbufferDesc = new D3D11ShaderResourceViewDesc(D3D11SrvDimension.Buffer, DxgiFormat.Unknown) { Buffer = new D3D11BufferSrv { ElementWidth = NUM_ELEMENTS } }; g_pBuffer1SRV = d3dDevice.CreateShaderResourceView(g_pBuffer1, srvbufferDesc); g_pBuffer2SRV = d3dDevice.CreateShaderResourceView(g_pBuffer2, srvbufferDesc); // Create the Unordered Access View for the Buffers // This is used for writing the buffer during the sort and transpose var uavbufferDesc = new D3D11UnorderedAccessViewDesc(D3D11UavDimension.Buffer, DxgiFormat.Unknown) { Buffer = new D3D11BufferUav { NumElements = NUM_ELEMENTS } }; g_pBuffer1UAV = d3dDevice.CreateUnorderedAccessView(g_pBuffer1, uavbufferDesc); g_pBuffer2UAV = d3dDevice.CreateUnorderedAccessView(g_pBuffer2, uavbufferDesc); // Create the Readback Buffer // This is used to read the results back to the CPU var readbackBufferDesc = new D3D11BufferDesc( NUM_ELEMENTS * sizeof(uint), D3D11BindOptions.None, D3D11Usage.Staging, D3D11CpuAccessOptions.Read, D3D11ResourceMiscOptions.None, sizeof(uint)); g_pReadBackBuffer = d3dDevice.CreateBuffer(readbackBufferDesc); }
public void PerEdgeTessellation( XMMatrix matWVP, ref D3D11Buffer ppTessedVerticesBuf, ref D3D11Buffer ppTessedIndicesBuf, out uint num_tessed_vertices, out uint num_tessed_indices) { var d3dDevice = this.deviceResources.D3DDevice; var d3dContext = this.deviceResources.D3DContext; // Update per-edge tessellation factors { EdgeFactorConstantBuffer cbCS = default; cbCS.MatWVP = matWVP; cbCS.TessEdgeLengthScale = this.m_tess_edge_len_scale; cbCS.NumTriangles = this.m_nVertices / 3; d3dContext.UpdateSubresource( this.s_pEdgeFactorCSCB, D3D11Utils.CalcSubresource(0, 0, 1), null, cbCS, EdgeFactorConstantBuffer.Size, EdgeFactorConstantBuffer.Size); this.RunComputeShader( this.s_pEdgeFactorCS, new[] { this.m_pBaseVBSRV }, null, this.s_pEdgeFactorCSCB, this.m_pEdgeFactorBufUAV, (uint)Math.Ceiling(this.m_nVertices / 3 / 128.0f), 1U, 1U); } // How many vertices/indices are needed for the tessellated mesh? { uint[] cbCS = new uint[] { this.m_nVertices / 3, 0, 0, 0 }; d3dContext.UpdateSubresource( this.s_pCSCB, D3D11Utils.CalcSubresource(0, 0, 1), null, cbCS, 4 * 4, 4 * 4); this.RunComputeShader( this.s_pNumVerticesIndicesCSs[(int)this.PartitioningMode], new[] { this.m_pEdgeFactorBufSRV }, this.s_pLookupTableCSCB, this.s_pCSCB, this.m_pScanBuf0UAV, (uint)Math.Ceiling(this.m_nVertices / 3 / 128.0f), 1U, 1U); this.s_ScanCS.Scan(d3dContext, this.m_nVertices / 3, this.m_pScanBuf0SRV, this.m_pScanBuf0UAV, this.m_pScanBuf1SRV, this.m_pScanBuf1UAV); // read back the number of vertices/indices for tessellation output D3D11Box box = default; box.Left = 4 * 2 * this.m_nVertices / 3 - 4 * 2; box.Right = 4 * 2 * this.m_nVertices / 3; box.Top = 0; box.Bottom = 1; box.Front = 0; box.Back = 1; d3dContext.CopySubresourceRegion(this.s_pCSReadBackBuf, 0, 0, 0, 0, this.m_pScanBuf0, 0, box); D3D11MappedSubResource mappedResource = d3dContext.Map(this.s_pCSReadBackBuf, 0, D3D11MapCpuPermission.Read, D3D11MapOptions.None); try { num_tessed_vertices = (uint)Marshal.ReadInt32(mappedResource.Data + 4 * 0); num_tessed_indices = (uint)Marshal.ReadInt32(mappedResource.Data + 4 * 1); } finally { d3dContext.Unmap(this.s_pCSReadBackBuf, 0); } } if (num_tessed_vertices == 0 || num_tessed_indices == 0) { return; } // Turn on this and set a breakpoint on the line beginning with "p = " and see what has been written to m_pScanBuf0 if (DebugEnabled) { #pragma warning disable IDE0059 // Assignation inutile d'une valeur var p = this.CreateAndCopyToDebugBuf <(uint v, uint t)>(this.m_pScanBuf0); #pragma warning restore IDE0059 // Assignation inutile d'une valeur } // Generate buffers for scattering TriID and IndexID for both vertex data and index data, // also generate buffers for output tessellated vertex data and index data { if (this.m_pScatterVertexBuf == null || this.m_nCachedTessedVertices < num_tessed_vertices || this.m_nCachedTessedVertices > num_tessed_vertices * 2) { D3D11Utils.DisposeAndNull(ref this.m_pScatterVertexBuf); D3D11Utils.DisposeAndNull(ref this.m_pScatterVertexBufSRV); D3D11Utils.DisposeAndNull(ref this.m_pScatterVertexBufUAV); D3D11Utils.DisposeAndNull(ref ppTessedVerticesBuf); D3D11Utils.DisposeAndNull(ref this.m_pTessedVerticesBufUAV); D3D11Utils.DisposeAndNull(ref this.m_pTessedVerticesBufSRV); this.m_pScatterVertexBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 2 * num_tessed_vertices, StructureByteStride = 4 * 2, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); this.m_pScatterVertexBufSRV = d3dDevice.CreateShaderResourceView(this.m_pScatterVertexBuf, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = num_tessed_vertices } }); this.m_pScatterVertexBufUAV = d3dDevice.CreateUnorderedAccessView(this.m_pScatterVertexBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = num_tessed_vertices } }); // generate the output tessellated vertices buffer ppTessedVerticesBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 3 * num_tessed_vertices, StructureByteStride = 4 * 3, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); this.m_pTessedVerticesBufUAV = d3dDevice.CreateUnorderedAccessView(ppTessedVerticesBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = num_tessed_vertices } }); this.m_pTessedVerticesBufSRV = d3dDevice.CreateShaderResourceView(ppTessedVerticesBuf, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = num_tessed_vertices } }); this.m_nCachedTessedVertices = num_tessed_vertices; } if (this.m_pScatterIndexBuf == null || this.m_nCachedTessedIndices < num_tessed_indices) { D3D11Utils.DisposeAndNull(ref this.m_pScatterIndexBuf); D3D11Utils.DisposeAndNull(ref this.m_pScatterIndexBufSRV); D3D11Utils.DisposeAndNull(ref this.m_pScatterIndexBufUAV); D3D11Utils.DisposeAndNull(ref ppTessedIndicesBuf); D3D11Utils.DisposeAndNull(ref this.m_pTessedIndicesBufUAV); this.m_pScatterIndexBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 2 * num_tessed_indices, StructureByteStride = 4 * 2, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); this.m_pScatterIndexBufSRV = d3dDevice.CreateShaderResourceView(this.m_pScatterIndexBuf, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = num_tessed_indices } }); this.m_pScatterIndexBufUAV = d3dDevice.CreateUnorderedAccessView(this.m_pScatterIndexBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = num_tessed_indices } }); // generate the output tessellated indices buffer ppTessedIndicesBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess | D3D11BindOptions.IndexBuffer, ByteWidth = 4 * num_tessed_indices, MiscOptions = D3D11ResourceMiscOptions.BufferAllowRawViews, Usage = D3D11Usage.Default }); this.m_pTessedIndicesBufUAV = d3dDevice.CreateUnorderedAccessView(ppTessedIndicesBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.R32Typeless, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = num_tessed_indices, Options = D3D11BufferUavOptions.Raw } }); this.m_nCachedTessedIndices = num_tessed_indices; } } // Scatter TriID, IndexID { uint[] cbCS = new uint[] { this.m_nVertices / 3, 0, 0, 0 }; D3D11ShaderResourceView[] aRViews = new[] { this.m_pScanBuf0SRV }; d3dContext.UpdateSubresource( this.s_pCSCB, D3D11Utils.CalcSubresource(0, 0, 1), null, cbCS, 4 * 4, 4 * 4); // Scatter vertex TriID, IndexID this.RunComputeShader( this.s_pScatterVertexTriIDIndexIDCS, aRViews, null, this.s_pCSCB, this.m_pScatterVertexBufUAV, (uint)Math.Ceiling(this.m_nVertices / 3 / 128.0f), 1U, 1U); // Scatter index TriID, IndexID this.RunComputeShader( this.s_pScatterIndexTriIDIndexIDCS, aRViews, null, this.s_pCSCB, this.m_pScatterIndexBufUAV, (uint)Math.Ceiling(this.m_nVertices / 3 / 128.0f), 1U, 1U); } // Turn on this and set a breakpoint on the line beginning with "p = " and see what has been written to m_pScatterVertexBuf if (DebugEnabled) { #pragma warning disable IDE0059 // Assignation inutile d'une valeur var p = this.CreateAndCopyToDebugBuf <(uint v, uint t)>(this.m_pScatterVertexBuf); #pragma warning restore IDE0059 // Assignation inutile d'une valeur } // Tessellate vertex { uint[] cbCS = new uint[] { num_tessed_vertices, 0, 0, 0 }; d3dContext.UpdateSubresource( this.s_pCSCB, D3D11Utils.CalcSubresource(0, 0, 1), null, cbCS, 4 * 4, 4 * 4); this.RunComputeShader( this.s_pTessVerticesCSs[(int)this.PartitioningMode], new[] { this.m_pScatterVertexBufSRV, this.m_pEdgeFactorBufSRV }, this.s_pLookupTableCSCB, this.s_pCSCB, this.m_pTessedVerticesBufUAV, (uint)Math.Ceiling(num_tessed_vertices / 128.0f), 1U, 1U); } // Turn on this and set a breakpoint on the line beginning with "p = " and see what has been written to *ppTessedVerticesBuf if (DebugEnabled) { #pragma warning disable IDE0059 // Assignation inutile d'une valeur var p = this.CreateAndCopyToDebugBuf <(uint id, float u, float v)>(ppTessedVerticesBuf); #pragma warning restore IDE0059 // Assignation inutile d'une valeur } // Tessellate indices { uint[] cbCS = new uint[] { num_tessed_indices, 0, 0, 0 }; d3dContext.UpdateSubresource( this.s_pCSCB, D3D11Utils.CalcSubresource(0, 0, 1), null, cbCS, 4 * 4, 4 * 4); this.RunComputeShader( this.s_pTessIndicesCSs[(int)this.PartitioningMode], new[] { this.m_pScatterIndexBufSRV, this.m_pEdgeFactorBufSRV, this.m_pScanBuf0SRV }, this.s_pLookupTableCSCB, this.s_pCSCB, this.m_pTessedIndicesBufUAV, (uint)Math.Ceiling(num_tessed_indices / 128.0f), 1U, 1U); } // Turn on this and set a breakpoint on the line beginning with "p = " and see what has been written to *ppTessedIndicesBuf if (DebugEnabled) { #pragma warning disable IDE0059 // Assignation inutile d'une valeur var p = this.CreateAndCopyToDebugBuf <int>(ppTessedIndicesBuf); #pragma warning restore IDE0059 // Assignation inutile d'une valeur } }
public void SetBaseMesh(uint nVertices, D3D11Buffer pBaseVB) { var d3dDevice = this.deviceResources.D3DDevice; this.m_nVertices = nVertices; // shader resource view of base mesh vertex data this.m_pBaseVBSRV = d3dDevice.CreateShaderResourceView(pBaseVB, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.R32G32B32A32Float, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = this.m_nVertices } }); // Buffer for edge tessellation factor this.m_pEdgeFactorBuf = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 4 * this.m_nVertices / 3, StructureByteStride = 4 * 4, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); // shader resource view of the buffer above this.m_pEdgeFactorBufSRV = d3dDevice.CreateShaderResourceView(this.m_pEdgeFactorBuf, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); // UAV of the buffer above this.m_pEdgeFactorBufUAV = d3dDevice.CreateUnorderedAccessView(this.m_pEdgeFactorBuf, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); // Buffers for scan this.m_pScanBuf0 = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 2 * this.m_nVertices / 3, StructureByteStride = 4 * 2, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); this.m_pScanBuf1 = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ShaderResource | D3D11BindOptions.UnorderedAccess, ByteWidth = 4 * 2 * this.m_nVertices / 3, StructureByteStride = 4 * 2, MiscOptions = D3D11ResourceMiscOptions.BufferStructured, Usage = D3D11Usage.Default }); // shader resource views of the scan buffers this.m_pScanBuf0SRV = d3dDevice.CreateShaderResourceView(this.m_pScanBuf0, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); this.m_pScanBuf1SRV = d3dDevice.CreateShaderResourceView(this.m_pScanBuf1, new D3D11ShaderResourceViewDesc { ViewDimension = D3D11SrvDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferSrv { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); // UAV of the scan buffers this.m_pScanBuf0UAV = d3dDevice.CreateUnorderedAccessView(this.m_pScanBuf0, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); this.m_pScanBuf1UAV = d3dDevice.CreateUnorderedAccessView(this.m_pScanBuf1, new D3D11UnorderedAccessViewDesc { ViewDimension = D3D11UavDimension.Buffer, Format = DxgiFormat.Unknown, Buffer = new D3D11BufferUav { FirstElement = 0, NumElements = this.m_nVertices / 3 } }); }
private void CreateParticlePosVeloBuffers() { var d3dDevice = this.deviceResources.D3DDevice; // Initialize the data in the buffers Particle[] pData1 = new Particle[MaxParticles]; Random rand = this.Random ?? new Random(0); if (this.DiskGalaxyFormationType == 0) { // Disk Galaxy Formation float fCenterSpread = Spread * 0.50f; LoadParticles( rand, pData1, 0, new XMFloat3(fCenterSpread, 0, 0), new XMFloat4(0, 0, -20, 1 / 10000.0f / 10000.0f), Spread, pData1.Length / 2); LoadParticles( rand, pData1, pData1.Length / 2, new XMFloat3(-fCenterSpread, 0, 0), new XMFloat4(0, 0, 20, 1 / 10000.0f / 10000.0f), Spread, pData1.Length - pData1.Length / 2); } else { // Disk Galaxy Formation with impacting third cluster LoadParticles( rand, pData1, 0, new XMFloat3(Spread, 0, 0), new XMFloat4(0, 0, -8, 1 / 10000.0f / 10000.0f), Spread, pData1.Length / 3); LoadParticles( rand, pData1, pData1.Length / 3, new XMFloat3(-Spread, 0, 0), new XMFloat4(0, 0, 8, 1 / 10000.0f / 10000.0f), Spread, pData1.Length / 3); LoadParticles( rand, pData1, 2 * pData1.Length / 3, new XMFloat3(0, 0, Spread * 15.0f), new XMFloat4(0, 0, -60, 1 / 10000.0f / 10000.0f), Spread, pData1.Length - 2 * pData1.Length / 3); } D3D11BufferDesc desc = D3D11BufferDesc.From(pData1, D3D11BindOptions.UnorderedAccess | D3D11BindOptions.ShaderResource); desc.MiscOptions = D3D11ResourceMiscOptions.BufferStructured; desc.StructureByteStride = Particle.Size; this.g_pParticlePosVelo0 = d3dDevice.CreateBuffer(desc, pData1, 0, 0); this.g_pParticlePosVelo1 = d3dDevice.CreateBuffer(desc, pData1, 0, 0); D3D11ShaderResourceViewDesc DescRV = new D3D11ShaderResourceViewDesc( this.g_pParticlePosVelo0, DxgiFormat.Unknown, 0, desc.ByteWidth / desc.StructureByteStride); this.g_pParticlePosVeloRV0 = d3dDevice.CreateShaderResourceView(this.g_pParticlePosVelo0, DescRV); this.g_pParticlePosVeloRV1 = d3dDevice.CreateShaderResourceView(this.g_pParticlePosVelo1, DescRV); D3D11UnorderedAccessViewDesc DescUAV = new D3D11UnorderedAccessViewDesc( this.g_pParticlePosVelo0, DxgiFormat.Unknown, 0, desc.ByteWidth / desc.StructureByteStride); this.g_pParticlePosVeloUAV0 = d3dDevice.CreateUnorderedAccessView(this.g_pParticlePosVelo0, DescUAV); this.g_pParticlePosVeloUAV1 = d3dDevice.CreateUnorderedAccessView(this.g_pParticlePosVelo1, DescUAV); }
static void Main(string[] args) { try { Console.Write("Creating device..."); CreateComputeDevice(); Console.WriteLine("done"); Console.Write("Creating Compute Shader..."); CreateComputeShader(); Console.WriteLine("done"); Console.Write("Creating buffers and filling them with initial data..."); for (int i = 0; i < NUM_ELEMENTS; ++i) { g_vBuf0[i].i = i; g_vBuf0[i].f = (float)i; #if TEST_DOUBLE g_vBuf0[i].d = (double)i; #endif g_vBuf1[i].i = i; g_vBuf1[i].f = (float)i; #if TEST_DOUBLE g_vBuf1[i].d = (double)i; #endif } #if USE_STRUCTURED_BUFFERS g_pBuf0 = CreateStructuredBuffer(deviceResources.D3DDevice, g_vBuf0); g_pBuf1 = CreateStructuredBuffer(deviceResources.D3DDevice, g_vBuf1); g_pBufResult = CreateStructuredBuffer(deviceResources.D3DDevice, new BufType[NUM_ELEMENTS]); #else g_pBuf0 = CreateRawBuffer(deviceResources.D3DDevice, g_vBuf0); g_pBuf1 = CreateRawBuffer(deviceResources.D3DDevice, g_vBuf1); g_pBufResult = CreateRawBuffer(deviceResources.D3DDevice, new BufType[NUM_ELEMENTS]); #endif #if DEBUG g_pBuf0?.SetDebugName("Buffer0"); g_pBuf1?.SetDebugName("Buffer1"); g_pBufResult?.SetDebugName("Result"); #endif Console.WriteLine("done"); Console.Write("Creating buffer views..."); g_pBuf0SRV = CreateBufferSRV(deviceResources.D3DDevice, g_pBuf0); g_pBuf1SRV = CreateBufferSRV(deviceResources.D3DDevice, g_pBuf1); g_pBufResultUAV = CreateBufferUAV(deviceResources.D3DDevice, g_pBufResult); #if DEBUG g_pBuf0SRV?.SetDebugName("Buffer0 SRV"); g_pBuf1SRV?.SetDebugName("Buffer1 SRV"); g_pBufResultUAV?.SetDebugName("Result UAV"); #endif Console.WriteLine("done"); Console.Write("Running Compute Shader..."); RunComputeShader(deviceResources.D3DContext, g_pCS, new[] { g_pBuf0SRV, g_pBuf1SRV }, g_pBufResultUAV, NUM_ELEMENTS, 1, 1); Console.WriteLine("done"); // Read back the result from GPU, verify its correctness against result computed by CPU D3D11Buffer debugbuf = CreateAndCopyToDebugBuf(deviceResources.D3DDevice, deviceResources.D3DContext, g_pBufResult); try { D3D11MappedSubResource mappedResource = deviceResources.D3DContext.Map(debugbuf, 0, D3D11MapCpuPermission.Read, D3D11MapOptions.None); try { // Set a break point here and put down the expression "p, 1024" in your watch window to see what has been written out by our CS // This is also a common trick to debug CS programs. // Verify that if Compute Shader has done right Console.Write("Verifying against CPU result..."); bool bSuccess = true; for (int i = 0; i < NUM_ELEMENTS; ++i) { BufType p = Marshal.PtrToStructure <BufType>(mappedResource.Data + i * (int)BufType.Size); if ((p.i != g_vBuf0[i].i + g_vBuf1[i].i) || (p.f != g_vBuf0[i].f + g_vBuf1[i].f) #if TEST_DOUBLE || (p.d != g_vBuf0[i].d + g_vBuf1[i].d) #endif ) { Console.WriteLine("failure"); bSuccess = false; break; } } if (bSuccess) { Console.WriteLine("succeeded"); } } finally { deviceResources.D3DContext.Unmap(debugbuf, 0); } } finally { D3D11Utils.ReleaseAndNull(ref debugbuf); } } catch (Exception ex) { Console.WriteLine(ex); } finally { Console.Write("Cleaning up..."); CleanupResources(); Console.WriteLine("done"); } Console.ReadKey(false); }