public void Dispose()
        {
            if (constantBuffers != null)
            {
                Marshal.FreeHGlobal((IntPtr)constantBuffers);
                constantBuffers = null;
            }

            if (textures != null)
            {
                Marshal.FreeHGlobal((IntPtr)textures);
                textures = null;
            }

            if (textureDepthStencils != null)
            {
                Marshal.FreeHGlobal((IntPtr)textureDepthStencils);
                textureDepthStencils = null;
            }

            if (randomAccessTypes != null)
            {
                Marshal.FreeHGlobal((IntPtr)randomAccessTypes);
                randomAccessTypes = null;
            }
        }
        public ComputeStateDesc_NativeInterop(ref ComputeStateDesc desc)
        {
            computeShader = ((ComputeShader)desc.computeShader).handle;

            if (desc.constantBuffers != null)
            {
                constantBufferCount = desc.constantBuffers.Length;
                constantBuffers     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * constantBufferCount);
                for (int i = 0; i != constantBufferCount; ++i)
                {
                    constantBuffers[i] = ((ConstantBuffer)desc.constantBuffers[i]).handle;
                }
            }
            else
            {
                constantBufferCount = 0;
                constantBuffers     = null;
            }

            if (desc.textures != null)
            {
                textureCount = desc.textures.Length;
                textures     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * textureCount);
                for (int i = 0; i != textureCount; ++i)
                {
                    textures[i] = desc.textures[i].GetHandle();
                }
            }
            else
            {
                textureCount = 0;
                textures     = null;
            }

            if (desc.textureDepthStencils != null)
            {
                textureDepthStencilCount = desc.textureDepthStencils.Length;
                textureDepthStencils     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * textureDepthStencilCount);
                for (int i = 0; i != textureDepthStencilCount; ++i)
                {
                    textureDepthStencils[i] = desc.textureDepthStencils[i].GetHandle();
                }
            }
            else
            {
                textureDepthStencilCount = 0;
                textureDepthStencils     = null;
            }

            if (desc.randomAccessBuffers != null)
            {
                randomAccessBufferCount = desc.randomAccessBuffers.Length;
                randomAccessBuffers     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * randomAccessBufferCount);
                randomAccessTypes       = (RandomAccessBufferType *)Marshal.AllocHGlobal(sizeof(RandomAccessBufferType) * randomAccessBufferCount);
                for (int i = 0; i != randomAccessBufferCount; ++i)
                {
                    var buffer = desc.randomAccessBuffers[i];
                    var type   = buffer.GetType();
                    if (typeof(Texture2DBase).IsAssignableFrom(type))
                    {
                        randomAccessBuffers[i] = ((Texture2DBase)buffer).GetHandle();
                        randomAccessTypes[i]   = RandomAccessBufferType.Texture;
                    }
                    else
                    {
                        throw new NotSupportedException("Unsupported ComputeShader random access buffer type: " + type.ToString());
                    }
                }
            }
            else
            {
                randomAccessBufferCount = 0;
                randomAccessBuffers     = null;
                randomAccessTypes       = null;
            }
        }
        public RenderStateDesc_NativeInterop(ref RenderStateDesc desc)
        {
            renderPass   = ((RenderPass)desc.renderPass).handle;
            shaderEffect = ((ShaderEffect)desc.shaderEffect).handle;

            if (desc.constantBuffers != null)
            {
                constantBufferCount = desc.constantBuffers.Length;
                constantBuffers     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * constantBufferCount);
                for (int i = 0; i != constantBufferCount; ++i)
                {
                    constantBuffers[i] = ((ConstantBuffer)desc.constantBuffers[i]).handle;
                }
            }
            else
            {
                constantBufferCount = 0;
                constantBuffers     = null;
            }

            if (desc.textures != null)
            {
                textureCount = desc.textures.Length;
                textures     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * textureCount);
                for (int i = 0; i != textureCount; ++i)
                {
                    textures[i] = desc.textures[i].GetHandle();
                }
            }
            else
            {
                textureCount = 0;
                textures     = null;
            }

            if (desc.textureDepthStencils != null)
            {
                textureDepthStencilCount = desc.textureDepthStencils.Length;
                textureDepthStencils     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * textureDepthStencilCount);
                for (int i = 0; i != textureDepthStencilCount; ++i)
                {
                    textureDepthStencils[i] = desc.textureDepthStencils[i].GetHandle();
                }
            }
            else
            {
                textureDepthStencilCount = 0;
                textureDepthStencils     = null;
            }

            if (desc.randomAccessBuffers != null)
            {
                randomAccessBufferCount = desc.randomAccessBuffers.Length;
                randomAccessBuffers     = (IntPtr *)Marshal.AllocHGlobal(Marshal.SizeOf <IntPtr>() * randomAccessBufferCount);
                randomAccessTypes       = (RandomAccessBufferType *)Marshal.AllocHGlobal(sizeof(RandomAccessBufferType) * randomAccessBufferCount);
                for (int i = 0; i != randomAccessBufferCount; ++i)
                {
                    var buffer = desc.randomAccessBuffers[i];
                    var type   = buffer.GetType();
                    if (typeof(Texture2DBase).IsAssignableFrom(type))
                    {
                        randomAccessBuffers[i] = ((Texture2DBase)buffer).GetHandle();
                        randomAccessTypes[i]   = RandomAccessBufferType.Texture;
                    }
                    else
                    {
                        throw new NotSupportedException("Unsupported ComputeShader random access buffer type: " + type.ToString());
                    }
                }
            }
            else
            {
                randomAccessBufferCount = 0;
                randomAccessBuffers     = null;
                randomAccessTypes       = null;
            }

            vertexBufferTopology = desc.vertexBufferTopology;
            vertexBufferStreamer = ((VertexBufferStreamer)desc.vertexBufferStreamer).handle;
            if (desc.indexBuffer != null)
            {
                indexBuffer = ((IndexBuffer)desc.indexBuffer).handle;
            }
            else
            {
                indexBuffer = IntPtr.Zero;
            }
            triangleCulling  = desc.triangleCulling;
            triangleFillMode = desc.triangleFillMode;
            blendDesc        = new BlendDesc_NativeInterop(ref desc.blendDesc);
            depthStencilDesc = new DepthStencilDesc_NativeInterop(ref desc.depthStencilDesc);
        }