Пример #1
0
        public void BuildResources(GraphicsCommandList cmdList)
        {
            // All the textures for the wave simulation will be bound as a shader resource and
            // unordered access view at some point since we ping-pong the buffers.

            var texDesc = new ResourceDescription
            {
                Dimension         = ResourceDimension.Texture2D,
                Alignment         = 0,
                Width             = ColumnCount,
                Height            = RowCount,
                DepthOrArraySize  = 1,
                MipLevels         = 1,
                Format            = Format.R32_Float,
                SampleDescription = new SampleDescription(1, 0),
                Layout            = TextureLayout.Unknown,
                Flags             = ResourceFlags.AllowUnorderedAccess
            };

            _prevSol = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.Common);
            _currSol = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.Common);
            _nextSol = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                texDesc,
                ResourceStates.Common);

            //
            // In order to copy CPU memory data into our default buffer, we need to create
            // an intermediate upload heap.
            //

            int  num2DSubresources = texDesc.DepthOrArraySize * texDesc.MipLevels;
            long uploadBufferSize;

            _device.GetCopyableFootprints(ref texDesc, 0, num2DSubresources, 0, null, null, null, out uploadBufferSize);

            _prevUploadBuffer = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(uploadBufferSize),
                ResourceStates.GenericRead);
            _currUploadBuffer = _device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(uploadBufferSize),
                ResourceStates.GenericRead);

            //
            // Schedule to copy the data to the default resource, and change states.
            // Note that mCurrSol is put in the GENERIC_READ state so it can be
            // read by a shader.
            //

            cmdList.ResourceBarrierTransition(_prevSol, ResourceStates.Common, ResourceStates.CopyDestination);
            cmdList.CopyResource(_prevSol, _prevUploadBuffer);
            cmdList.ResourceBarrierTransition(_prevSol, ResourceStates.CopyDestination, ResourceStates.UnorderedAccess);

            cmdList.ResourceBarrierTransition(_currSol, ResourceStates.Common, ResourceStates.CopyDestination);
            cmdList.CopyResource(_currSol, _currUploadBuffer);
            cmdList.ResourceBarrierTransition(_currSol, ResourceStates.CopyDestination, ResourceStates.GenericRead);

            cmdList.ResourceBarrierTransition(_nextSol, ResourceStates.Common, ResourceStates.UnorderedAccess);
        }
Пример #2
0
        public override ImageCapture CaptureRenderTarget(RenderTarget surface)
        {
            IntPtr texNativePtr = RenderDeviceD3D11.GetTextureNativePointer(surface.Texture);

            SharpDX.Direct3D12.Resource            texture = new SharpDX.Direct3D12.Resource(texNativePtr);
            SharpDX.Direct3D12.ResourceDescription texDesc = texture.Description;

            // Transition PIXEL_SHADER_RESOURCE -> COPY_SOURCE
            SharpDX.Direct3D12.ResourceBarrier barrier = new SharpDX.Direct3D12.ResourceBarrier();
            barrier.Type       = SharpDX.Direct3D12.ResourceBarrierType.Transition;
            barrier.Flags      = SharpDX.Direct3D12.ResourceBarrierFlags.None;
            barrier.Transition = new SharpDX.Direct3D12.ResourceTransitionBarrier(texture,
                                                                                  SharpDX.Direct3D12.ResourceStates.PixelShaderResource,
                                                                                  SharpDX.Direct3D12.ResourceStates.CopySource)
            {
                Subresource = 0
            };

            _commands.ResourceBarrier(barrier);

            long totalBytes;

            long[] rowSize = { 0 };
            _dev.GetCopyableFootprints(ref texDesc, 0, 1, 0, null, null, rowSize, out totalBytes);
            long pitch = (rowSize[0] + 255) & ~255;

            // Create staging texture
            SharpDX.Direct3D12.HeapProperties heap;
            heap.Type                 = SharpDX.Direct3D12.HeapType.Readback;
            heap.CPUPageProperty      = SharpDX.Direct3D12.CpuPageProperty.Unknown;
            heap.MemoryPoolPreference = SharpDX.Direct3D12.MemoryPool.Unknown;
            heap.CreationNodeMask     = 0;
            heap.VisibleNodeMask      = 0;

            SharpDX.Direct3D12.ResourceDescription desc;
            desc.Dimension         = SharpDX.Direct3D12.ResourceDimension.Buffer;
            desc.Alignment         = 0;
            desc.Width             = pitch * texDesc.Height * 4;
            desc.Height            = 1;
            desc.DepthOrArraySize  = 1;
            desc.MipLevels         = 1;
            desc.Format            = SharpDX.DXGI.Format.Unknown;
            desc.SampleDescription = new SampleDescription {
                Count = 1, Quality = 0
            };
            desc.Layout = SharpDX.Direct3D12.TextureLayout.RowMajor;
            desc.Flags  = SharpDX.Direct3D12.ResourceFlags.None;

            SharpDX.Direct3D12.Resource stagingTex = _dev.CreateCommittedResource(heap, SharpDX.Direct3D12.HeapFlags.None,
                                                                                  desc, SharpDX.Direct3D12.ResourceStates.CopyDestination, null);

            SharpDX.Direct3D12.TextureCopyLocation copySrc = new SharpDX.Direct3D12.TextureCopyLocation(texture, 0);
            SharpDX.Direct3D12.TextureCopyLocation copyDst = new SharpDX.Direct3D12.TextureCopyLocation(texture,
                                                                                                        new SharpDX.Direct3D12.PlacedSubResourceFootprint
            {
                Offset    = 0,
                Footprint = new SharpDX.Direct3D12.SubResourceFootprint
                {
                    Width    = (int)texDesc.Width,
                    Height   = (int)texDesc.Height,
                    Depth    = 1,
                    RowPitch = (int)pitch,
                    Format   = texDesc.Format
                }
            });

            // Wait GPU completion
            _commands.CopyTextureRegion(copyDst, 0, 0, 0, copySrc, null);
            _commands.Close();
            _queue.ExecuteCommandList(_commands);
            WaitForGpu();

            // Ensure image capture object is created with the appropriate size
            if (_imageCapture == null || _imageCapture.Width != desc.Width || _imageCapture.Height != desc.Height)
            {
                _imageCapture = new ImageCapture((uint)desc.Width, (uint)desc.Height);
            }

            // Map and copy to image
            byte[] dst = _imageCapture.Pixels;
            IntPtr src = stagingTex.Map(0);

            for (int i = 0; i < desc.Height; ++i)
            {
                int dstRow = i * (int)_imageCapture.Stride;
                int srcRow = i * (int)pitch;

                for (int j = 0; j < desc.Width; j++)
                {
                    // RGBA -> BGRA
                    dst[dstRow + 4 * j + 2] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 0);
                    dst[dstRow + 4 * j + 1] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 1);
                    dst[dstRow + 4 * j + 0] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 2);
                    dst[dstRow + 4 * j + 3] = Noesis.Marshal.ReadByte(src, srcRow + 4 * j + 3);
                }
            }

            stagingTex.Unmap(0);

            return(_imageCapture);
        }