Beispiel #1
0
 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);
     }
 }
Beispiel #2
0
        public unsafe override void UpdateBuffer(Buffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes)
        {
            D3D11Buffer d3dBuffer = Util.AssertSubtype <Buffer, D3D11Buffer>(buffer);

            if (sizeInBytes == 0)
            {
                return;
            }

            bool useMap = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic;

            if (useMap)
            {
                if (bufferOffsetInBytes != 0)
                {
                    throw new NotImplementedException("bufferOffsetInBytes must be 0 for Dynamic Buffers.");
                }
                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
            {
                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);
                }
            }
        }
Beispiel #3
0
 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);
     }
 }
Beispiel #4
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);
        }
Beispiel #5
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>();
                }
            }
        }
Beispiel #6
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);
                }
            }
        }
Beispiel #7
0
        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;
            }
        }
Beispiel #8
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 isDynamic            = (buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic;
            bool isStaging            = (buffer.Usage & BufferUsage.Staging) == BufferUsage.Staging;
            bool isUniformBuffer      = (buffer.Usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer;
            bool updateFullBuffer     = bufferOffsetInBytes == 0 && sizeInBytes == buffer.SizeInBytes;
            bool useUpdateSubresource = (!isDynamic && !isStaging) && (!isUniformBuffer || updateFullBuffer);
            bool useMap = (isDynamic && updateFullBuffer) || isStaging;

            if (useUpdateSubresource)
            {
                ResourceRegion?subregion = new ResourceRegion()
                {
                    Left   = (int)bufferOffsetInBytes,
                    Right  = (int)(sizeInBytes + bufferOffsetInBytes),
                    Bottom = 1,
                    Back   = 1
                };

                if (isUniformBuffer)
                {
                    subregion = null;
                }

                lock (_immediateContextLock)
                {
                    _immediateContext.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0);
                }
            }
            else if (useMap)
            {
                MappedResource mr = MapCore(buffer, MapMode.Write, 0);
                if (sizeInBytes < 1024)
                {
                    Unsafe.CopyBlock((byte *)mr.Data + bufferOffsetInBytes, source.ToPointer(), sizeInBytes);
                }
                else
                {
                    System.Buffer.MemoryCopy(
                        source.ToPointer(),
                        (byte *)mr.Data + bufferOffsetInBytes,
                        buffer.SizeInBytes,
                        sizeInBytes);
                }
                UnmapCore(buffer, 0);
            }
            else
            {
                D3D11Buffer staging = GetFreeStagingBuffer(sizeInBytes);
                UpdateBuffer(staging, 0, source, sizeInBytes);
                ResourceRegion sourceRegion = new ResourceRegion(0, 0, 0, (int)sizeInBytes, 1, 1);
                lock (_immediateContextLock)
                {
                    _immediateContext.CopySubresourceRegion(
                        staging.Buffer, 0, sourceRegion,
                        d3dBuffer.Buffer, 0,
                        (int)bufferOffsetInBytes, 0, 0);
                }

                lock (_stagingResourcesLock)
                {
                    _availableStagingBuffers.Add(staging);
                }
            }
        }
Beispiel #9
0
        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);
                }
            }
        }
        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 isUniformBuffer      = (buffer.Usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer;
            bool useMap               = isDynamic;
            bool updateFullBuffer     = bufferOffsetInBytes == 0 && sizeInBytes == buffer.SizeInBytes;
            bool useUpdateSubresource = !isDynamic && !isStaging && (!isUniformBuffer || updateFullBuffer);

            if (useUpdateSubresource)
            {
                ResourceRegion?subregion = new ResourceRegion()
                {
                    Left   = (int)bufferOffsetInBytes,
                    Right  = (int)(sizeInBytes + bufferOffsetInBytes),
                    Bottom = 1,
                    Back   = 1
                };
                if (isUniformBuffer)
                {
                    subregion = null;
                }

                if (bufferOffsetInBytes == 0)
                {
                    _context.UpdateSubresource(d3dBuffer.Buffer, 0, subregion, source, 0, 0);
                }
                else
                {
                    _context1.UpdateSubresource1(d3dBuffer.Buffer, 0, subregion, source, 0, 0, 0);
                }
            }
            else if (useMap && updateFullBuffer) // Can only update full buffer with WriteDiscard.
            {
                SharpDX.DataBox db = _context.MapSubresource(
                    d3dBuffer.Buffer,
                    0,
                    D3D11Formats.VdToD3D11MapMode(isDynamic, MapMode.Write),
                    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);
            }
        }