Пример #1
0
        public void UpdateTransferFunctionTexture()
        {
            // TODO: This code is identical with TF loading in the LoadAssets method.
            // Could be extracted to common helper class, perhaps also including
            // volume texture loading. We call nearly-identical code three times in this file.

            // TODO: I suspect the might be another, minor, memory leak here.

            // Load transfer function
            var transferFunctionTextureDesc = ResourceDescription.Texture1D(Format.R8G8B8A8_UNorm, TransferFunctionWidth, 1);

            transferFunctionTexture = device.CreateCommittedResource(new HeapProperties(
                                                                         HeapType.Default),
                                                                     HeapFlags.None,
                                                                     transferFunctionTextureDesc,
                                                                     ResourceStates.CopyDestination);

            long transferFunctionUploadBufferSize = GetRequiredIntermediateSize(this.transferFunctionTexture, 0, 1);

            // Create the GPU upload buffer.
            transferFunctionTextureUploadHeap = device.CreateCommittedResource(new HeapProperties(
                                                                                   CpuPageProperty.WriteBack,
                                                                                   MemoryPool.L0), HeapFlags.None,
                                                                               ResourceDescription.Texture1D(Format.R8G8B8A8_UNorm, TransferFunctionWidth, 1),
                                                                               ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture1D.
            byte[] transferFunctionTextureData = GenerateTransferFunctionTextureData();

            var transferFunctionHandle = GCHandle.Alloc(transferFunctionTextureData, GCHandleType.Pinned);
            var transferFunctionPtr    = Marshal.UnsafeAddrOfPinnedArrayElement(transferFunctionTextureData, 0);

            transferFunctionTextureUploadHeap.WriteToSubresource(0, null, transferFunctionPtr, TransferFunctionWidth, TransferFunctionWidth);

            transferFunctionHandle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(transferFunctionTexture, 0), 0, 0, 0, new TextureCopyLocation(transferFunctionTextureUploadHeap, 0), null);
            commandList.ResourceBarrierTransition(this.transferFunctionTexture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the transfer function texture.
            var transferFunctionSrvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = transferFunctionTextureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture1D,
                Texture1D = { MipLevels = 1 },
            };

            var handleIncrement = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            CpuDescriptorHandle locationDesctiptor = shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + handleIncrement;

            device.CreateShaderResourceView(this.transferFunctionTexture, transferFunctionSrvDesc, locationDesctiptor);
            // End load transfer function data
        }
Пример #2
0
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout,
                                                                 // Root Parameters
                                                                 new[]
            {
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ShaderResourceView,
                    DescriptorCount = 3,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType          = DescriptorRangeType.ConstantBufferView,
                    DescriptorCount    = 1,
                    BaseShaderRegister = 0,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                })
            },
                                                                 // Samplers
                                                                 new[]
            {
                new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
                {
                    //Filter = Filter.MinimumMinMagMipPoint,
                    Filter     = Filter.ComparisonMinLinearMagPointMipLinear,
                    AddressUVW = TextureAddressMode.Border,
                }
            });

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

            var vertexShaderPath = Utils.GetVertexShaderPath();
            var pixelShaderPath  = Utils.GetPixelShaderForRenderingMode(VolViz.Configuration.RenderingMode.Dvr);

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(vertexShaderPath, "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(vertexShaderPath, "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(pixelShaderPath, "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile(pixelShaderPath, "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            var inputElementDescs = new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = rootSignature,
                VertexShader       = vertexShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Define the geometry for a square consisting of two triangles.
            var squareVertexes = new[]
            {
                new Vertex()
                {
                    Position = new Vector3(-1.0f, 1.0f, 0.0f), TexCoord = new Vector2(0.0f, 0.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1.0f, 1.0f, 0.0f), TexCoord = new Vector2(1.0f, 0.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1.0f, -1.0f, 0.0f), TexCoord = new Vector2(0.0f, 1.0f)
                },

                new Vertex()
                {
                    Position = new Vector3(1.0f, 1.0f, 0.0f), TexCoord = new Vector2(1.0f, 0.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1.0f, -1.0f, 0.0f), TexCoord = new Vector2(1.0f, 1.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1.0f, -1.0f, 0.0f), TexCoord = new Vector2(0.0f, 1.0f)
                },
            };

            // Create the vertex buffer.
            int vertexBufferSize = Utilities.SizeOf(squareVertexes);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            var pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, squareVertexes, 0, squareVertexes.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            // Load volume data
            var volumeTextureDesc = ResourceDescription.Texture3D(Format.R8G8B8A8_UNorm, VolumeTextureWidth, VolumeTextureHeight, VolumeTextureDepth, 1);
            volumeTexture = device.CreateCommittedResource(new HeapProperties(
                                                               HeapType.Default),
                                                           HeapFlags.None,
                                                           volumeTextureDesc,
                                                           ResourceStates.CopyDestination);

            long volumeUploadBufferSize = GetRequiredIntermediateSize(this.volumeTexture, 0, 1);

            // Create the GPU upload buffer.
            var volumeTextureUploadHeap = device.CreateCommittedResource(new HeapProperties(
                                                                             CpuPageProperty.WriteBack,
                                                                             MemoryPool.L0), HeapFlags.None,
                                                                         ResourceDescription.Texture3D(Format.R8G8B8A8_UNorm, VolumeTextureWidth, VolumeTextureHeight, VolumeTextureDepth, 1),
                                                                         ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture3D.
            byte[] volumeTextureData = GenerateVolumeTextureData();

            var volumeHandle = GCHandle.Alloc(volumeTextureData, GCHandleType.Pinned);
            var volumePtr    = Marshal.UnsafeAddrOfPinnedArrayElement(volumeTextureData, 0);

            volumeTextureUploadHeap.WriteToSubresource(0, null, volumePtr, TexturePixelSize * VolumeTextureWidth, TexturePixelSize * VolumeTextureWidth * VolumeTextureHeight);

            volumeHandle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(volumeTexture, 0), 0, 0, 0, new TextureCopyLocation(volumeTextureUploadHeap, 0), null);
            commandList.ResourceBarrierTransition(this.volumeTexture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the volume texture.
            var volumeSrvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = volumeTextureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture3D,
                Texture3D = { MipLevels = 1 },
            };

            device.CreateShaderResourceView(this.volumeTexture, volumeSrvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);
            // End load volume data

            // Load transfer function
            var transferFunctionTextureDesc = ResourceDescription.Texture1D(Format.R8G8B8A8_UNorm, TransferFunctionWidth, 1);
            transferFunctionTexture = device.CreateCommittedResource(new HeapProperties(
                                                                         HeapType.Default),
                                                                     HeapFlags.None,
                                                                     transferFunctionTextureDesc,
                                                                     ResourceStates.CopyDestination);

            long transferFunctionUploadBufferSize = GetRequiredIntermediateSize(this.transferFunctionTexture, 0, 1);

            // Create the GPU upload buffer.
            var transferFunctionTextureUploadHeap = device.CreateCommittedResource(new HeapProperties(
                                                                                       CpuPageProperty.WriteBack,
                                                                                       MemoryPool.L0), HeapFlags.None,
                                                                                   ResourceDescription.Texture1D(Format.R8G8B8A8_UNorm, TransferFunctionWidth, 1),
                                                                                   ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture1D.
            byte[] transferFunctionTextureData = GenerateTransferFunctionTextureData();

            var transferFunctionHandle = GCHandle.Alloc(transferFunctionTextureData, GCHandleType.Pinned);
            var transferFunctionPtr    = Marshal.UnsafeAddrOfPinnedArrayElement(transferFunctionTextureData, 0);

            transferFunctionTextureUploadHeap.WriteToSubresource(0, null, transferFunctionPtr, TransferFunctionWidth, TransferFunctionWidth);

            transferFunctionHandle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(transferFunctionTexture, 0), 0, 0, 0, new TextureCopyLocation(transferFunctionTextureUploadHeap, 0), null);
            commandList.ResourceBarrierTransition(this.transferFunctionTexture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the transfer function texture.
            var transferFunctionSrvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = transferFunctionTextureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture1D,
                Texture1D = { MipLevels = 1 },
            };

            var transferFunctionHandleIncrement = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            CpuDescriptorHandle transferFunctionLocationDesctiptor = shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + transferFunctionHandleIncrement;
            device.CreateShaderResourceView(this.transferFunctionTexture, transferFunctionSrvDesc, transferFunctionLocationDesctiptor);
            // End load transfer function data

            // Load gradients data
            var gradientsTextureDesc = ResourceDescription.Texture3D(Format.R8G8B8A8_UNorm, VolumeTextureWidth, VolumeTextureHeight, VolumeTextureDepth, 1);
            gradientsTexture = device.CreateCommittedResource(new HeapProperties(
                                                                  HeapType.Default),
                                                              HeapFlags.None,
                                                              gradientsTextureDesc,
                                                              ResourceStates.CopyDestination);

            long gradientsUploadBufferSize = GetRequiredIntermediateSize(this.gradientsTexture, 0, 1);

            // Create the GPU upload buffer.
            var gradientsTextureUploadHeap = device.CreateCommittedResource(new HeapProperties(
                                                                                CpuPageProperty.WriteBack,
                                                                                MemoryPool.L0), HeapFlags.None,
                                                                            ResourceDescription.Texture3D(Format.R8G8B8A8_UNorm, VolumeTextureWidth, VolumeTextureHeight, VolumeTextureDepth, 1),
                                                                            ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture3D.
            byte[] gradientsTextureData = GenerateGradientsTextureData();

            var gradientsHandle = GCHandle.Alloc(gradientsTextureData, GCHandleType.Pinned);
            var gradientsPtr    = Marshal.UnsafeAddrOfPinnedArrayElement(gradientsTextureData, 0);

            gradientsTextureUploadHeap.WriteToSubresource(0, null, gradientsPtr, TexturePixelSize * VolumeTextureWidth, TexturePixelSize * VolumeTextureWidth * VolumeTextureHeight);

            gradientsHandle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(gradientsTexture, 0), 0, 0, 0, new TextureCopyLocation(gradientsTextureUploadHeap, 0), null);
            commandList.ResourceBarrierTransition(this.gradientsTexture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the gradients texture.
            var gradientsSrvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = gradientsTextureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture3D,
                Texture3D = { MipLevels = 1 },
            };

            var gradientsHandleIncrement = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            CpuDescriptorHandle gradientsLocationDesctiptor = shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + gradientsHandleIncrement * 2;
            device.CreateShaderResourceView(this.gradientsTexture, gradientsSrvDesc, gradientsLocationDesctiptor);
            // End load gradients data

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            var cbvDesc = new ConstantBufferViewDescription
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255
            };

            device.CreateConstantBufferView(cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            commandQueue.ExecuteCommandList(commandList);

            // Create synchronization objects.
            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);

            WaitForPreviousFrame();

            //release temp texture
            volumeTextureUploadHeap.Dispose();
            transferFunctionTextureUploadHeap.Dispose();
            gradientsTextureUploadHeap.Dispose();
        }