Ejemplo n.º 1
0
        private unsafe void Deserialize(IntPtr pNativePtr)
        {
            if (pNativePtr == IntPtr.Zero)
            {
                return;
            }

            __Native *pNative = (__Native *)pNativePtr;

            if (pNative->ParameterCount > 0)
            {
                Parameters = new RootParameter[pNative->ParameterCount];
                RootParameter.__Native *rpn = (RootParameter.__Native *)pNative->ParametersPointer;
                for (int i = 0; i < Parameters.Length; ++i)
                {
                    Parameters[i] = new RootParameter();
                    if (rpn[i].ParameterType == RootParameterType.DescriptorTable)
                    {
                        // Marshal descriptor table
                        DescriptorRange[] ranges = null;

                        int rangeCount = rpn[i].Union.DescriptorTable.DescriptorRangeCount;
                        if (rangeCount > 0)
                        {
                            ranges = new DescriptorRange[rangeCount];
                            Utilities.Read(rpn[i].Union.DescriptorTable.DescriptorRangesPointer, ranges, 0, ranges.Length);
                        }

                        Parameters[i] = new RootParameter(rpn[i].ShaderVisibility, ranges);
                    }
                    else
                    {
                        // No need to marshal them when RootParameter don't contain DescriptorTable - simple copy as-is
                        Parameters[i] = new RootParameter {
                            native = *rpn
                        };
                    }
                }
            }

            if (pNative->StaticSamplerCount > 0)
            {
                StaticSamplers = new StaticSamplerDescription[pNative->StaticSamplerCount];
                Utilities.Read(pNative->StaticSamplerPointer, StaticSamplers, 0, StaticSamplers.Length);
            }
        }
Ejemplo n.º 2
0
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } };

            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter = Filter.MinimumMinMagMipPoint,
                AddressU = TextureAddressMode.Border,
                AddressV = TextureAddressMode.Border,
                AddressW = TextureAddressMode.Border,
                MipLODBias = 0,
                MaxAnisotropy = 0,
                ComparisonFunc = Comparison.Never,
                BorderColor = StaticBorderColor.TransparentBlack,
                MinLOD = 0.0f,
                MaxLOD = float.MaxValue,
                ShaderRegister = 0,
                RegisterSpace = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges) };

            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });
            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

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

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                    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).
            GraphicsPipelineStateDescription 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);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                    new Vertex() {position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),uv=new Vector2(0.5f, 0.0f) },
                    new Vertex() {position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(1.0f, 1.0f) },
                    new Vertex() {position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(0.0f, 1.0f) },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

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

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            // 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();

            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
            textureUploadHeap.Dispose();
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1 } };
            RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges);

            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter });
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
            #if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
            #else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
            #endif

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

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

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription 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);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                    new Vertex() {position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),color=new Vector4(1.0f, 0.0f, 0.0f, 1.0f ) },
                    new Vertex() {position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),color=new Vector4(0.0f, 1.0f, 0.0f, 1.0f) },
                    new Vertex() {position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),color=new Vector4(0.0f, 0.0f, 1.0f, 1.0f ) },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // 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.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

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

            // 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.
            ConstantBufferViewDescription 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);

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

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);
        }
        private unsafe void Deserialize(IntPtr pNativePtr)
        {
            if(pNativePtr == IntPtr.Zero)
            {
                return;
            }

            __Native* pNative = (__Native*)pNativePtr;

            if (pNative->ParameterCount > 0)
            {
                Parameters = new RootParameter[pNative->ParameterCount];
                RootParameter.__Native* rpn = (RootParameter.__Native * ) pNative->ParametersPointer;
                for (int i = 0; i < Parameters.Length; ++i)
                {
                    Parameters[i] = new RootParameter();
                    if (rpn[i].ParameterType == RootParameterType.DescriptorTable)
                    {
                        // Marshal descriptor table
                        DescriptorRange[] ranges = null;

                        int rangeCount = rpn[i].Union.DescriptorTable.DescriptorRangeCount;
                        if (rangeCount > 0)
                        {
                            ranges = new DescriptorRange[rangeCount];
                            Utilities.Read(rpn[i].Union.DescriptorTable.DescriptorRangesPointer, ranges, 0, ranges.Length);
                        }

                        Parameters[i] = new RootParameter(rpn[i].ShaderVisibility, ranges);
                    }
                    else
                    {
                        // No need to marshal them when RootParameter don't contain DescriptorTable - simple copy as-is
                        Parameters[i] = new RootParameter {native = *rpn};
                    }
                }
            }
             
            if (pNative->StaticSamplerCount > 0)
            {
                StaticSamplers = new StaticSamplerDescription[pNative->StaticSamplerCount];
                Utilities.Read(pNative->StaticSamplerPointer, StaticSamplers, 0, StaticSamplers.Length);
            }
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 } };
            RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges);

            // Create a root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter });
            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

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

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

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

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

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription 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 = DepthStencilStateDescription.Default(),
                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);

            // 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();

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a cube.

            Vertex[] vertices = new[]
            {
                ////TOP
                new Vertex(new Vector3(-5,5,5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(5,5,5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(5,5,-5),new Vector4(0,1,0,0)),
                new Vertex(new Vector3(-5,5,-5),new Vector4(0,1,0,0)),
                //BOTTOM
                new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(5,-5,5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(1,0,1,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,1,1)),
                //LEFT
                new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,5,5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,5,-5),new Vector4(1,0,0,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,0,1)),
                //RIGHT
                new Vertex(new Vector3(5,-5,5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,5,5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,5,-5),new Vector4(1,1,0,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(1,1,0,1)),
                //FRONT
                new Vertex(new Vector3(-5,5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(5,5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(5,-5,5),new Vector4(0,1,1,1)),
                new Vertex(new Vector3(-5,-5,5),new Vector4(0,1,1,1)),
                //BACK
                new Vertex(new Vector3(-5,5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(5,5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(5,-5,-5),new Vector4(0,0,1,1)),
                new Vertex(new Vector3(-5,-5,-5),new Vector4(0,0,1,1))
            };

            int vertexBufferSize = Utilities.SizeOf(vertices);

            // 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.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, vertices, 0, vertices.Length);
            vertexBuffer.Unmap(0);

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

            //Create Index Buffer
            //Indices
            int[] indices = new int[]
            {
                0,1,2,0,2,3,
                4,6,5,4,7,6,
                8,9,10,8,10,11,
                12,14,13,12,15,14,
                16,18,17,16,19,18,
                20,21,22,20,22,23
            };
            int indexBufferSize = Utilities.SizeOf(indices);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, indices, 0, indices.Length);
            indexBuffer.Unmap(0);

            // Initialize the index buffer view.
            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.Format = Format.R32_UInt;
            indexBufferView.SizeInBytes = indexBufferSize;

            //constant Buffer for each cubes
            constantBufferViewHeap = device.CreateDescriptorHeap(new DescriptorHeapDescription()
            {
                DescriptorCount = NumCubes,
                Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView,
                Flags = DescriptorHeapFlags.ShaderVisible
            });

            int constantBufferSize = (Utilities.SizeOf<Transform>() + 255) & ~255;
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize * NumCubes), ResourceStates.GenericRead);
            constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            //First cube
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = constantBufferSize
            };

            CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart;

            for (int i = 0; i < NumCubes; i++)
            {
                device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart);
                cbvDesc.BufferLocation += Utilities.SizeOf<Transform>();
                cbHandleHeapStart += constantBufferDescriptorSize;
            }

            InitBundles();
        }