protected override void UnmapCore(MappableResource resource, uint subresource)
        {
            MappedResourceCacheKey key = new MappedResourceCacheKey(resource, subresource);
            bool commitUnmap;

            lock (_mappedResourceLock)
            {
                if (!_mappedResources.TryGetValue(key, out MappedResourceInfo info))
                {
                    throw new RendererException($"The given resource ({resource}) is not mapped.");
                }

                info.RefCount -= 1;
                commitUnmap    = info.RefCount == 0;
                if (commitUnmap)
                {
                    lock (_immediateContextLock)
                    {
                        if (resource is D3D11Buffer buffer)
                        {
                            _immediateContext.UnmapSubresource(buffer.Buffer, 0);
                        }
                        else
                        {
                            D3D11Texture texture = Util.AssertSubtype <MappableResource, D3D11Texture>(resource);
                            _immediateContext.UnmapSubresource(texture.DeviceTexture, (int)subresource);
                        }

                        bool result = _mappedResources.Remove(key);
                        Debug.Assert(result);
                    }
                }
            }
        }
Example #2
0
        protected override void ResolveTextureCore(Texture source, Texture destination)
        {
            D3D11Texture d3d11Source      = Util.AssertSubtype <Texture, D3D11Texture>(source);
            D3D11Texture d3d11Destination = Util.AssertSubtype <Texture, D3D11Texture>(destination);

            _context.ResolveSubresource(
                d3d11Source.DeviceTexture,
                0,
                d3d11Destination.DeviceTexture,
                0,
                d3d11Destination.DxgiFormat);
        }
Example #3
0
        protected override void CopyTextureCore(
            Texture source,
            uint srcX, uint srcY, uint srcZ,
            uint srcMipLevel,
            uint srcBaseArrayLayer,
            Texture destination,
            uint dstX, uint dstY, uint dstZ,
            uint dstMipLevel,
            uint dstBaseArrayLayer,
            uint width, uint height, uint depth,
            uint layerCount)
        {
            D3D11Texture srcD3D11Texture = Util.AssertSubtype <Texture, D3D11Texture>(source);
            D3D11Texture dstD3D11Texture = Util.AssertSubtype <Texture, D3D11Texture>(destination);

            uint blockSize     = FormatHelpers.IsCompressedFormat(source.Format) ? 4u : 1u;
            uint clampedWidth  = Math.Max(blockSize, width);
            uint clampedHeight = Math.Max(blockSize, height);

            ResourceRegion region = new ResourceRegion(
                (int)srcX,
                (int)srcY,
                (int)srcZ,
                (int)(srcX + clampedWidth),
                (int)(srcY + clampedHeight),
                (int)(srcZ + depth));

            for (uint i = 0; i < layerCount; i++)
            {
                int srcSubresource = D3D11Util.ComputeSubresource(srcMipLevel, source.MipLevels, srcBaseArrayLayer + i);
                int dstSubresource = D3D11Util.ComputeSubresource(dstMipLevel, destination.MipLevels, dstBaseArrayLayer + i);

                _context.CopySubresourceRegion(
                    srcD3D11Texture.DeviceTexture,
                    srcSubresource,
                    region,
                    dstD3D11Texture.DeviceTexture,
                    dstSubresource,
                    (int)dstX,
                    (int)dstY,
                    (int)dstZ);
            }
        }
        protected unsafe override void UpdateTextureCore(
            Texture texture,
            IntPtr source,
            uint sizeInBytes,
            uint x,
            uint y,
            uint z,
            uint width,
            uint height,
            uint depth,
            uint mipLevel,
            uint arrayLayer)
        {
            D3D11Texture d3dTex = Util.AssertSubtype <Texture, D3D11Texture>(texture);
            bool         useMap = (texture.Usage & TextureUsage.Staging) == TextureUsage.Staging;

            if (useMap)
            {
                uint subresource           = texture.CalculateSubresource(mipLevel, arrayLayer);
                MappedResourceCacheKey key = new MappedResourceCacheKey(texture, subresource);
                MappedResource         map = MapCore(texture, MapMode.Write, subresource);

                uint denseRowSize   = FormatHelpers.GetRowPitch(width, texture.Format);
                uint denseSliceSize = FormatHelpers.GetDepthPitch(denseRowSize, height, texture.Format);

                Util.CopyTextureRegion(
                    source.ToPointer(),
                    0, 0, 0,
                    denseRowSize, denseSliceSize,
                    map.Data.ToPointer(),
                    x, y, z,
                    map.RowPitch, map.DepthPitch,
                    width, height, depth,
                    texture.Format);

                UnmapCore(texture, subresource);
            }
            else
            {
                int            subresource    = D3D11Util.ComputeSubresource(mipLevel, texture.MipLevels, arrayLayer);
                ResourceRegion resourceRegion = new ResourceRegion(
                    left: (int)x,
                    right: (int)(x + width),
                    top: (int)y,
                    front: (int)z,
                    bottom: (int)(y + height),
                    back: (int)(z + depth));
                uint srcRowPitch   = FormatHelpers.GetSizeInBytes(texture.Format) * width;
                uint srcDepthPitch = srcRowPitch * depth;
                lock (_immediateContextLock)
                {
                    _immediateContext.UpdateSubresource(
                        d3dTex.DeviceTexture,
                        subresource,
                        resourceRegion,
                        source,
                        (int)srcRowPitch,
                        (int)srcDepthPitch);
                }
            }
        }
        protected override MappedResource MapCore(MappableResource resource, MapMode mode, uint subresource)
        {
            MappedResourceCacheKey key = new MappedResourceCacheKey(resource, subresource);

            lock (_mappedResourceLock)
            {
                if (_mappedResources.TryGetValue(key, out MappedResourceInfo info))
                {
                    if (info.Mode != mode)
                    {
                        throw new RendererException("The given resource was already mapped with a different MapMode.");
                    }

                    info.RefCount        += 1;
                    _mappedResources[key] = info;
                }
                else
                {
                    // No current mapping exists -- create one.

                    if (resource is D3D11Buffer buffer)
                    {
                        lock (_immediateContextLock)
                        {
                            DataBox db = _immediateContext.MapSubresource(
                                buffer.Buffer,
                                0,
                                D3D11Formats.ToD3D11MapMode((buffer.Usage & BufferUsage.Dynamic) == BufferUsage.Dynamic, mode),
                                SharpDX.Direct3D11.MapFlags.None);

                            info.MappedResource = new MappedResource(resource, mode, db.DataPointer, buffer.SizeInBytes);
                            info.RefCount       = 1;
                            info.Mode           = mode;
                            _mappedResources.Add(key, info);
                        }
                    }
                    else
                    {
                        D3D11Texture texture = Util.AssertSubtype <MappableResource, D3D11Texture>(resource);
                        lock (_immediateContextLock)
                        {
                            DataBox db = _immediateContext.MapSubresource(
                                texture.DeviceTexture,
                                (int)subresource,
                                D3D11Formats.ToD3D11MapMode(false, mode),
                                SharpDX.Direct3D11.MapFlags.None,
                                out DataStream ds);

                            info.MappedResource = new MappedResource(
                                resource,
                                mode,
                                db.DataPointer,
                                (uint)ds.Length,
                                subresource,
                                (uint)db.RowPitch,
                                (uint)db.SlicePitch);
                            info.RefCount = 1;
                            info.Mode     = mode;
                            _mappedResources.Add(key, info);
                        }
                    }
                }

                return(info.MappedResource);
            }
        }
        public D3D11Framebuffer(Device device, ref FramebufferDescription description)
            : base(description.DepthTarget, description.ColorTargets)
        {
            if (description.DepthTarget != null)
            {
                D3D11Texture d3dDepthTarget         = Util.AssertSubtype <Texture, D3D11Texture>(description.DepthTarget.Value.Target);
                DepthStencilViewDescription dsvDesc = new DepthStencilViewDescription()
                {
                    Format = D3D11Formats.GetDepthFormat(d3dDepthTarget.Format),
                };
                if (d3dDepthTarget.ArrayLayers == 1)
                {
                    if (d3dDepthTarget.SampleCount == TextureSampleCount.Count1)
                    {
                        dsvDesc.Dimension = DepthStencilViewDimension.Texture2D;
                    }
                    else
                    {
                        dsvDesc.Dimension = DepthStencilViewDimension.Texture2DMultisampled;
                    }
                }
                else
                {
                    if (d3dDepthTarget.SampleCount == TextureSampleCount.Count1)
                    {
                        dsvDesc.Dimension = DepthStencilViewDimension.Texture2DArray;
                        dsvDesc.Texture2DArray.FirstArraySlice = (int)description.DepthTarget.Value.ArrayLayer;
                        dsvDesc.Texture2DArray.ArraySize       = 1;
                    }
                    else
                    {
                        dsvDesc.Dimension = DepthStencilViewDimension.Texture2DMultisampledArray;
                        dsvDesc.Texture2DMSArray.FirstArraySlice = (int)description.DepthTarget.Value.ArrayLayer;
                        dsvDesc.Texture2DMSArray.ArraySize       = 1;
                    }
                }

                DepthStencilView = new DepthStencilView(device, d3dDepthTarget.DeviceTexture, dsvDesc);
            }

            if (description.ColorTargets != null && description.ColorTargets.Length > 0)
            {
                RenderTargetViews = new RenderTargetView[description.ColorTargets.Length];
                for (int i = 0; i < RenderTargetViews.Length; i++)
                {
                    D3D11Texture d3dColorTarget         = Util.AssertSubtype <Texture, D3D11Texture>(description.ColorTargets[i].Target);
                    RenderTargetViewDescription rtvDesc = new RenderTargetViewDescription
                    {
                        Format = D3D11Formats.ToDxgiFormat(d3dColorTarget.Format, false),
                    };
                    if (d3dColorTarget.ArrayLayers == 1)
                    {
                        if (d3dColorTarget.SampleCount == TextureSampleCount.Count1)
                        {
                            rtvDesc.Dimension = RenderTargetViewDimension.Texture2D;
                        }
                        else
                        {
                            rtvDesc.Dimension = RenderTargetViewDimension.Texture2DMultisampled;
                        }
                    }
                    else
                    {
                        if (d3dColorTarget.SampleCount == TextureSampleCount.Count1)
                        {
                            rtvDesc.Dimension      = RenderTargetViewDimension.Texture2DArray;
                            rtvDesc.Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource
                            {
                                ArraySize       = 1,
                                FirstArraySlice = (int)description.ColorTargets[i].ArrayLayer
                            };
                        }
                        else
                        {
                            rtvDesc.Dimension        = RenderTargetViewDimension.Texture2DMultisampledArray;
                            rtvDesc.Texture2DMSArray = new RenderTargetViewDescription.Texture2DMultisampledArrayResource
                            {
                                ArraySize       = 1,
                                FirstArraySlice = (int)description.ColorTargets[i].ArrayLayer
                            };
                        }
                    }
                    RenderTargetViews[i] = new RenderTargetView(device, d3dColorTarget.DeviceTexture, rtvDesc);
                }
            }
            else
            {
                RenderTargetViews = Array.Empty <RenderTargetView>();
            }
        }
        public D3D11TextureView(Device device, ref TextureViewDescription description)
            : base(ref description)
        {
            D3D11Texture d3dTex = Util.AssertSubtype <Texture, D3D11Texture>(description.Target);
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription();

            srvDesc.Format = D3D11Formats.GetViewFormat(d3dTex.DxgiFormat);

            if ((d3dTex.Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap)
            {
                if (d3dTex.ArrayLayers == 1)
                {
                    srvDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCube;
                    srvDesc.TextureCube.MostDetailedMip = (int)description.BaseMipLevel;
                    srvDesc.TextureCube.MipLevels       = (int)description.MipLevels;
                }
                else
                {
                    srvDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCubeArray;
                    srvDesc.TextureCubeArray.MostDetailedMip  = (int)description.BaseMipLevel;
                    srvDesc.TextureCubeArray.MipLevels        = (int)description.MipLevels;
                    srvDesc.TextureCubeArray.First2DArrayFace = (int)description.BaseArrayLayer;
                    srvDesc.TextureCubeArray.CubeCount        = (int)d3dTex.ArrayLayers;
                }
            }
            else if (d3dTex.Depth == 1)
            {
                if (d3dTex.ArrayLayers == 1)
                {
                    srvDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D;
                    srvDesc.Texture2D.MostDetailedMip = (int)description.BaseMipLevel;
                    srvDesc.Texture2D.MipLevels       = (int)description.MipLevels;
                }
                else
                {
                    srvDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DArray;
                    srvDesc.Texture2DArray.MostDetailedMip = (int)description.BaseMipLevel;
                    srvDesc.Texture2DArray.MipLevels       = (int)description.MipLevels;
                    srvDesc.Texture2DArray.FirstArraySlice = (int)description.BaseArrayLayer;
                    srvDesc.Texture2DArray.ArraySize       = (int)description.ArrayLayers;
                }
            }
            else
            {
                srvDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture3D;
                srvDesc.Texture3D.MostDetailedMip = (int)description.BaseMipLevel;
                srvDesc.Texture3D.MipLevels       = (int)description.MipLevels;
            }

            ShaderResourceView = new ShaderResourceView(device, d3dTex.DeviceTexture, srvDesc);

            if ((d3dTex.Usage & TextureUsage.Storage) == TextureUsage.Storage)
            {
                UnorderedAccessViewDescription uavDesc = new UnorderedAccessViewDescription();
                uavDesc.Format = D3D11Formats.GetViewFormat(d3dTex.DxgiFormat);

                if ((d3dTex.Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap)
                {
                    throw new NotSupportedException();
                }
                else if (d3dTex.Depth == 1)
                {
                    if (d3dTex.ArrayLayers == 1)
                    {
                        uavDesc.Dimension          = UnorderedAccessViewDimension.Texture2D;
                        uavDesc.Texture2D.MipSlice = (int)description.BaseMipLevel;
                    }
                    else
                    {
                        uavDesc.Dimension = UnorderedAccessViewDimension.Texture2DArray;
                        uavDesc.Texture2DArray.MipSlice        = (int)description.BaseMipLevel;
                        uavDesc.Texture2DArray.FirstArraySlice = (int)description.BaseArrayLayer;
                        uavDesc.Texture2DArray.ArraySize       = (int)description.ArrayLayers;
                    }
                }
                else
                {
                    uavDesc.Dimension             = UnorderedAccessViewDimension.Texture3D;
                    uavDesc.Texture3D.MipSlice    = (int)description.BaseMipLevel;
                    uavDesc.Texture3D.FirstWSlice = (int)description.BaseArrayLayer;
                    uavDesc.Texture3D.WSize       = (int)description.ArrayLayers;
                }

                UnorderedAccessView = new UnorderedAccessView(device, d3dTex.DeviceTexture, uavDesc);
            }
        }