private void BindUniformBuffer(D3D11Buffer ub, int slot, ShaderStages stages) { if ((stages & ShaderStages.Vertex) == ShaderStages.Vertex) { bool bind = false; if (slot < MaxCachedUniformBuffers) { if (_vertexBoundUniformBuffers[slot] != ub) { _vertexBoundUniformBuffers[slot] = ub; bind = true; } } else { bind = true; } if (bind) { _context.VertexShader.SetConstantBuffer(slot, ub.Buffer); } } if ((stages & ShaderStages.Geometry) == ShaderStages.Geometry) { _context.GeometryShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.TessellationControl) == ShaderStages.TessellationControl) { _context.HullShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.TessellationEvaluation) == ShaderStages.TessellationEvaluation) { _context.DomainShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.Fragment) == ShaderStages.Fragment) { bool bind = false; if (slot < MaxCachedUniformBuffers) { if (_fragmentBoundUniformBuffers[slot] != ub) { _fragmentBoundUniformBuffers[slot] = ub; bind = true; } } else { bind = true; } if (bind) { _context.PixelShader.SetConstantBuffer(slot, ub.Buffer); } } if ((stages & ShaderStages.Compute) == ShaderStages.Compute) { _context.ComputeShader.SetConstantBuffer(slot, ub.Buffer); } }
protected override void SetIndexBufferCore(DeviceBuffer buffer, IndexFormat format) { if (_ib != buffer) { _ib = buffer; D3D11Buffer d3d11Buffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(buffer); _context.InputAssembler.SetIndexBuffer(d3d11Buffer.Buffer, D3D11Formats.ToDxgiFormat(format), 0); } }
protected override void CopyBufferCore(DeviceBuffer source, uint sourceOffset, DeviceBuffer destination, uint destinationOffset, uint sizeInBytes) { D3D11Buffer srcD3D11Buffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(source); D3D11Buffer dstD3D11Buffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(destination); ResourceRegion region = new ResourceRegion((int)sourceOffset, 0, 0, (int)(sourceOffset + sizeInBytes), 1, 1); _context.CopySubresourceRegion(srcD3D11Buffer.Buffer, 0, region, dstD3D11Buffer.Buffer, 0, (int)destinationOffset, 0, 0); }
protected unsafe override void UpdateBufferCore(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) { D3D11Buffer d3dBuffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(buffer); if (sizeInBytes == 0) { return; } bool useMap = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic || (buffer.Usage & BufferUsage.Staging) == BufferUsage.Staging; if (useMap) { if (bufferOffsetInBytes != 0) { throw new NotImplementedException("bufferOffsetInBytes must be 0 for Dynamic Buffers."); } MappedResource mr = MapCore(buffer, MapMode.Write, 0); if (sizeInBytes < 1024) { Unsafe.CopyBlock(mr.Data.ToPointer(), source.ToPointer(), sizeInBytes); } else { System.Buffer.MemoryCopy(source.ToPointer(), mr.Data.ToPointer(), buffer.SizeInBytes, sizeInBytes); } UnmapCore(buffer, 0); } else { ResourceRegion?subregion = null; if ((d3dBuffer.Buffer.Description.BindFlags & BindFlags.ConstantBuffer) != BindFlags.ConstantBuffer) { // For a shader-constant buffer; set pDstBox to null. It is not possible to use // this method to partially update a shader-constant buffer subregion = new ResourceRegion() { Left = (int)bufferOffsetInBytes, Right = (int)(sizeInBytes + bufferOffsetInBytes), Bottom = 1, Back = 1 }; } lock (_immediateContextLock) { _immediateContext.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0); } } }
private void ActivateResourceSet(uint slot, D3D11ResourceSet d3d11RS, bool graphics) { int cbBase = GetConstantBufferBase(slot, graphics); int uaBase = GetUnorderedAccessBase(slot, graphics); int textureBase = GetTextureBase(slot, graphics); int samplerBase = GetSamplerBase(slot, graphics); D3D11ResourceLayout layout = d3d11RS.Layout; BindableResource[] resources = d3d11RS.Resources; for (int i = 0; i < resources.Length; i++) { BindableResource resource = resources[i]; D3D11ResourceLayout.ResourceBindingInfo rbi = layout.GetDeviceSlotIndex(i); switch (rbi.Kind) { case ResourceKind.UniformBuffer: D3D11Buffer uniformBuffer = Util.AssertSubtype <BindableResource, D3D11Buffer>(resource); BindUniformBuffer(uniformBuffer, cbBase + rbi.Slot, rbi.Stages); break; case ResourceKind.StructuredBufferReadOnly: D3D11Buffer storageBufferRO = Util.AssertSubtype <BindableResource, D3D11Buffer>(resource); BindStorageBufferView(storageBufferRO, textureBase + rbi.Slot, rbi.Stages); break; case ResourceKind.StructuredBufferReadWrite: D3D11Buffer storageBuffer = Util.AssertSubtype <BindableResource, D3D11Buffer>(resource); BindUnorderedAccessView(null, storageBuffer.UnorderedAccessView, uaBase + rbi.Slot, rbi.Stages, slot); break; case ResourceKind.TextureReadOnly: D3D11TextureView texView = Util.AssertSubtype <BindableResource, D3D11TextureView>(resource); UnbindUAVTexture(texView.Target); BindTextureView(texView, textureBase + rbi.Slot, rbi.Stages, slot); break; case ResourceKind.TextureReadWrite: D3D11TextureView rwTexView = Util.AssertSubtype <BindableResource, D3D11TextureView>(resource); UnbindSRVTexture(rwTexView.Target); BindUnorderedAccessView(rwTexView.Target, rwTexView.UnorderedAccessView, uaBase + rbi.Slot, rbi.Stages, slot); break; case ResourceKind.Sampler: D3D11Sampler sampler = Util.AssertSubtype <BindableResource, D3D11Sampler>(resource); BindSampler(sampler, samplerBase + rbi.Slot, rbi.Stages); break; default: throw Illegal.Value <ResourceKind>(); } } }
protected override void DrawIndexedIndirectCore(DeviceBuffer indirectBuffer, uint offset, uint drawCount, uint stride) { PreDrawCommand(); D3D11Buffer d3d11Buffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(indirectBuffer); int currentOffset = (int)offset; for (uint i = 0; i < drawCount; i++) { _context.DrawIndexedInstancedIndirect(d3d11Buffer.Buffer, currentOffset); currentOffset += (int)stride; } }
public unsafe override void UpdateBuffer(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes) { D3D11Buffer d3dBuffer = Util.AssertSubtype <DeviceBuffer, D3D11Buffer>(buffer); if (sizeInBytes == 0) { return; } bool isDynamic = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic; bool isStaging = (buffer.Usage & BufferUsage.Staging) == BufferUsage.Staging; bool useMap = isDynamic || isStaging; if (!useMap) { ResourceRegion?subregion = null; if ((d3dBuffer.Buffer.Description.BindFlags & BindFlags.ConstantBuffer) != BindFlags.ConstantBuffer) { // For a shader-constant buffer; set pDstBox to null. It is not possible to use // this method to partially update a shader-constant buffer subregion = new ResourceRegion() { Left = (int)bufferOffsetInBytes, Right = (int)(sizeInBytes + bufferOffsetInBytes), Bottom = 1, Back = 1 }; } if (bufferOffsetInBytes == 0) { _context.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0); } else { _context1.UpdateSubresource1(d3dBuffer.Buffer, 0, subregion, source, 0, 0, 0); } } else { bool updateFullBuffer = bufferOffsetInBytes == 0 && sizeInBytes == buffer.SizeInBytes; if (updateFullBuffer && isDynamic) { SharpDX.DataBox db = _context.MapSubresource( d3dBuffer.Buffer, 0, SharpDX.Direct3D11.MapMode.WriteDiscard, MapFlags.None); if (sizeInBytes < 1024) { Unsafe.CopyBlock(db.DataPointer.ToPointer(), source.ToPointer(), sizeInBytes); } else { System.Buffer.MemoryCopy(source.ToPointer(), db.DataPointer.ToPointer(), buffer.SizeInBytes, sizeInBytes); } _context.UnmapSubresource(d3dBuffer.Buffer, 0); } else { D3D11Buffer staging = GetFreeStagingBuffer(sizeInBytes); _gd.UpdateBuffer(staging, 0, source, sizeInBytes); CopyBuffer(staging, 0, buffer, bufferOffsetInBytes, sizeInBytes); _submittedStagingBuffers.Add(staging); } } }