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

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

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

            if (randomAccessBuffers != null)
            {
                Marshal.FreeHGlobal((IntPtr)randomAccessBuffers);
                randomAccessBuffers = null;
            }
        }
        public ComputeShaderDesc_NativeInterop(ref ComputeShaderDesc desc)
        {
            // init defaults
            constantBufferCount     = 0;
            textureCount            = 0;
            samplersCount           = 0;
            randomAccessBufferCount = 0;
            constantBuffers         = null;
            textures            = null;
            samplers            = null;
            randomAccessBuffers = null;

            // allocate constant buffer heaps
            if (desc.constantBuffers != null)
            {
                constantBufferCount = desc.constantBuffers.Length;
                constantBuffers     = (ComputeShaderConstantBuffer_NativeInterop *)Marshal.AllocHGlobal(Marshal.SizeOf <ComputeShaderConstantBuffer_NativeInterop>() * constantBufferCount);
                for (int i = 0; i != constantBufferCount; ++i)
                {
                    constantBuffers[i] = new ComputeShaderConstantBuffer_NativeInterop(ref desc.constantBuffers[i]);
                }
            }

            // allocate texture heaps
            if (desc.textures != null)
            {
                textureCount = desc.textures.Length;
                textures     = (ComputeShaderTexture_NativeInterop *)Marshal.AllocHGlobal(Marshal.SizeOf <ComputeShaderTexture_NativeInterop>() * textureCount);
                for (int i = 0; i != textureCount; ++i)
                {
                    textures[i] = new ComputeShaderTexture_NativeInterop(ref desc.textures[i]);
                }
            }

            // allocate sampler heaps
            if (desc.samplers != null)
            {
                samplersCount = desc.samplers.Length;
                samplers      = (ComputeShaderSampler_NativeInterop *)Marshal.AllocHGlobal(Marshal.SizeOf <ComputeShaderSampler_NativeInterop>() * samplersCount);
                for (int i = 0; i != samplersCount; ++i)
                {
                    samplers[i] = new ComputeShaderSampler_NativeInterop(ref desc.samplers[i]);
                }
            }

            // allocate read-write-buffer heaps
            if (desc.randomAccessBuffers != null)
            {
                randomAccessBufferCount = desc.randomAccessBuffers.Length;
                randomAccessBuffers     = (ComputeShaderRandomAccessBuffer_NativeInterop *)Marshal.AllocHGlobal(Marshal.SizeOf <ComputeShaderRandomAccessBuffer_NativeInterop>() * randomAccessBufferCount);
                for (int i = 0; i != randomAccessBufferCount; ++i)
                {
                    randomAccessBuffers[i] = new ComputeShaderRandomAccessBuffer_NativeInterop(ref desc.randomAccessBuffers[i]);
                }
            }
        }