public void CopyTexture(
            Texture source,
            uint srcX, uint srcY, uint srcZ,
            uint srcMipLevel,
            uint srcBaseArrayLayer,
            Texture destination,
            uint dstX, uint dstY, uint dstZ,
            uint dstMipLevel,
            uint dstBaseArrayLayer,
            uint width, uint height, uint depth,
            uint layerCount)
        {
            NoAllocCopyTextureEntry entry = new NoAllocCopyTextureEntry(
                Track(source),
                srcX, srcY, srcZ,
                srcMipLevel,
                srcBaseArrayLayer,
                Track(destination),
                dstX, dstY, dstZ,
                dstMipLevel,
                dstBaseArrayLayer,
                width, height, depth,
                layerCount);

            AddEntry(CopyTextureEntryID, ref entry);
        }
Exemplo n.º 2
0
        private void FreeAllHandles()
        {
            int currentBlockIndex   = 0;
            EntryStorageBlock block = _blocks[currentBlockIndex];
            uint currentOffset      = 0;

            for (uint i = 0; i < _totalEntries; i++)
            {
                if (currentOffset == block.TotalSize)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                }

                uint id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                if (id == 0)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                    id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                }

                Debug.Assert(id != 0);
                currentOffset += 1;
                byte *entryBasePtr = block.BasePtr + currentOffset;
                switch (id)
                {
                case BeginEntryID:
                    currentOffset += BeginEntrySize;
                    break;

                case ClearColorTargetID:
                    currentOffset += ClearColorTargetEntrySize;
                    break;

                case ClearDepthTargetID:
                    currentOffset += ClearDepthTargetEntrySize;
                    break;

                case DrawEntryID:
                    currentOffset += DrawEntrySize;
                    break;

                case DrawIndexedEntryID:
                    currentOffset += DrawIndexedEntrySize;
                    break;

                case DrawIndirectEntryID:
                    ref NoAllocDrawIndirectEntry drawIndirectEntry = ref Unsafe.AsRef <NoAllocDrawIndirectEntry>(entryBasePtr);
                    drawIndirectEntry.IndirectBuffer.Free();
                    currentOffset += DrawIndirectEntrySize;
                    break;

                case DrawIndexedIndirectEntryID:
                    ref NoAllocDrawIndexedIndirectEntry diie = ref Unsafe.AsRef <NoAllocDrawIndexedIndirectEntry>(entryBasePtr);
                    diie.IndirectBuffer.Free();
                    currentOffset += DrawIndexedIndirectEntrySize;
                    break;

                case DispatchEntryID:
                    currentOffset += DispatchEntrySize;
                    break;

                case DispatchIndirectEntryID:
                    ref NoAllocDispatchIndirectEntry dispatchIndirect = ref Unsafe.AsRef <NoAllocDispatchIndirectEntry>(entryBasePtr);
                    dispatchIndirect.IndirectBuffer.Free();
                    currentOffset += DispatchIndirectEntrySize;
                    break;

                case EndEntryID:
                    currentOffset += EndEntrySize;
                    break;

                case SetFramebufferEntryID:
                    ref NoAllocSetFramebufferEntry sfbe = ref Unsafe.AsRef <NoAllocSetFramebufferEntry>(entryBasePtr);
                    sfbe.Framebuffer.Free();
                    currentOffset += SetFramebufferEntrySize;
                    break;

                case SetIndexBufferEntryID:
                    ref NoAllocSetIndexBufferEntry sibe = ref Unsafe.AsRef <NoAllocSetIndexBufferEntry>(entryBasePtr);
                    sibe.Buffer.Free();
                    currentOffset += SetIndexBufferEntrySize;
                    break;

                case SetPipelineEntryID:
                    ref NoAllocSetPipelineEntry spe = ref Unsafe.AsRef <NoAllocSetPipelineEntry>(entryBasePtr);
                    spe.Pipeline.Free();
                    currentOffset += SetPipelineEntrySize;
                    break;

                case SetGraphicsResourceSetEntryID:
                    ref NoAllocSetGraphicsResourceSetEntry sgrse = ref Unsafe.AsRef <NoAllocSetGraphicsResourceSetEntry>(entryBasePtr);
                    sgrse.ResourceSet.Free();
                    currentOffset += SetGraphicsResourceSetEntrySize;
                    break;

                case SetComputeResourceSetEntryID:
                    ref NoAllocSetComputeResourceSetEntry scrse = ref Unsafe.AsRef <NoAllocSetComputeResourceSetEntry>(entryBasePtr);
                    scrse.ResourceSet.Free();
                    currentOffset += SetComputeResourceSetEntrySize;
                    break;

                case SetScissorRectEntryID:
                    currentOffset += SetScissorRectEntrySize;
                    break;

                case SetVertexBufferEntryID:
                    ref NoAllocSetVertexBufferEntry svbe = ref Unsafe.AsRef <NoAllocSetVertexBufferEntry>(entryBasePtr);
                    svbe.Buffer.Free();
                    currentOffset += SetVertexBufferEntrySize;
                    break;

                case SetViewportEntryID:
                    currentOffset += SetViewportEntrySize;
                    break;

                case UpdateBufferEntryID:
                    ref NoAllocUpdateBufferEntry ube = ref Unsafe.AsRef <NoAllocUpdateBufferEntry>(entryBasePtr);
                    ube.Buffer.Free();
                    ube.StagingBlock.GCHandle.Free();
                    currentOffset += UpdateBufferEntrySize;
                    break;

                case CopyBufferEntryID:
                    ref NoAllocCopyBufferEntry cbe = ref Unsafe.AsRef <NoAllocCopyBufferEntry>(entryBasePtr);
                    cbe.Source.Free();
                    cbe.Destination.Free();
                    currentOffset += CopyBufferEntrySize;
                    break;

                case CopyTextureEntryID:
                    ref NoAllocCopyTextureEntry cte = ref Unsafe.AsRef <NoAllocCopyTextureEntry>(entryBasePtr);
                    cte.Source.Free();
                    cte.Destination.Free();
                    currentOffset += CopyTextureEntrySize;
                    break;

                case ResolveTextureEntryID:
                    ref NoAllocResolveTextureEntry rte = ref Unsafe.AsRef <NoAllocResolveTextureEntry>(entryBasePtr);
                    rte.Source.Free();
                    rte.Destination.Free();
                    currentOffset += ResolveTextureEntrySize;
                    break;

                default:
                    throw new InvalidOperationException("Invalid entry ID: " + id);
                }
            }
        }
        public void ExecuteAll(OpenGLCommandExecutor executor)
        {
            int currentBlockIndex   = 0;
            EntryStorageBlock block = _blocks[currentBlockIndex];
            uint currentOffset      = 0;

            for (uint i = 0; i < _totalEntries; i++)
            {
                if (currentOffset == block.TotalSize)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                }

                uint id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                if (id == 0)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                    id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                }

                Debug.Assert(id != 0);
                currentOffset += 1;
                byte *entryBasePtr = block.BasePtr + currentOffset;
                switch (id)
                {
                case BeginEntryID:
                    executor.Begin();
                    currentOffset += BeginEntrySize;
                    break;

                case ClearColorTargetID:
                    NoAllocClearColorTargetEntry ccte = Unsafe.ReadUnaligned <NoAllocClearColorTargetEntry>(entryBasePtr);
                    executor.ClearColorTarget(ccte.Index, ccte.ClearColor);
                    currentOffset += ClearColorTargetEntrySize;
                    break;

                case ClearDepthTargetID:
                    NoAllocClearDepthTargetEntry cdte = Unsafe.ReadUnaligned <NoAllocClearDepthTargetEntry>(entryBasePtr);
                    executor.ClearDepthStencil(cdte.Depth, cdte.Stencil);
                    currentOffset += ClearDepthTargetEntrySize;
                    break;

                case DrawEntryID:
                    NoAllocDrawEntry de = Unsafe.ReadUnaligned <NoAllocDrawEntry>(entryBasePtr);
                    executor.Draw(de.VertexCount, de.InstanceCount, de.VertexStart, de.InstanceStart);
                    currentOffset += DrawEntrySize;
                    break;

                case DrawIndexedEntryID:
                    NoAllocDrawIndexedEntry die = Unsafe.ReadUnaligned <NoAllocDrawIndexedEntry>(entryBasePtr);
                    executor.DrawIndexed(die.IndexCount, die.InstanceCount, die.IndexStart, die.VertexOffset, die.InstanceStart);
                    currentOffset += DrawIndexedEntrySize;
                    break;

                case DrawIndirectEntryID:
                    NoAllocDrawIndirectEntry drawIndirectEntry = Unsafe.ReadUnaligned <NoAllocDrawIndirectEntry>(entryBasePtr);
                    executor.DrawIndirect(
                        drawIndirectEntry.IndirectBuffer.Get(_resourceList),
                        drawIndirectEntry.Offset,
                        drawIndirectEntry.DrawCount,
                        drawIndirectEntry.Stride);
                    currentOffset += DrawIndirectEntrySize;
                    break;

                case DrawIndexedIndirectEntryID:
                    NoAllocDrawIndexedIndirectEntry diie = Unsafe.ReadUnaligned <NoAllocDrawIndexedIndirectEntry>(entryBasePtr);
                    executor.DrawIndexedIndirect(diie.IndirectBuffer.Get(_resourceList), diie.Offset, diie.DrawCount, diie.Stride);
                    currentOffset += DrawIndexedIndirectEntrySize;
                    break;

                case DispatchEntryID:
                    NoAllocDispatchEntry dispatchEntry = Unsafe.ReadUnaligned <NoAllocDispatchEntry>(entryBasePtr);
                    executor.Dispatch(dispatchEntry.GroupCountX, dispatchEntry.GroupCountY, dispatchEntry.GroupCountZ);
                    currentOffset += DispatchEntrySize;
                    break;

                case DispatchIndirectEntryID:
                    NoAllocDispatchIndirectEntry dispatchIndir = Unsafe.ReadUnaligned <NoAllocDispatchIndirectEntry>(entryBasePtr);
                    executor.DispatchIndirect(dispatchIndir.IndirectBuffer.Get(_resourceList), dispatchIndir.Offset);
                    currentOffset += DispatchIndirectEntrySize;
                    break;

                case EndEntryID:
                    executor.End();
                    currentOffset += EndEntrySize;
                    break;

                case SetFramebufferEntryID:
                    NoAllocSetFramebufferEntry sfbe = Unsafe.ReadUnaligned <NoAllocSetFramebufferEntry>(entryBasePtr);
                    executor.SetFramebuffer(sfbe.Framebuffer.Get(_resourceList));
                    currentOffset += SetFramebufferEntrySize;
                    break;

                case SetIndexBufferEntryID:
                    NoAllocSetIndexBufferEntry sibe = Unsafe.ReadUnaligned <NoAllocSetIndexBufferEntry>(entryBasePtr);
                    executor.SetIndexBuffer(sibe.Buffer.Get(_resourceList), sibe.Format, sibe.Offset);
                    currentOffset += SetIndexBufferEntrySize;
                    break;

                case SetPipelineEntryID:
                    NoAllocSetPipelineEntry spe = Unsafe.ReadUnaligned <NoAllocSetPipelineEntry>(entryBasePtr);
                    executor.SetPipeline(spe.Pipeline.Get(_resourceList));
                    currentOffset += SetPipelineEntrySize;
                    break;

                case SetResourceSetEntryID:
                    NoAllocSetResourceSetEntry srse = Unsafe.ReadUnaligned <NoAllocSetResourceSetEntry>(entryBasePtr);
                    ResourceSet rs = srse.ResourceSet.Get(_resourceList);
                    uint *      dynamicOffsetsPtr = srse.DynamicOffsetCount > NoAllocSetResourceSetEntry.MaxInlineDynamicOffsets
                            ? (uint *)srse.DynamicOffsets_Block.Data
                            : srse.DynamicOffsets_Inline;
                    if (srse.IsGraphics)
                    {
                        executor.SetGraphicsResourceSet(
                            srse.Slot,
                            rs,
                            srse.DynamicOffsetCount,
                            ref Unsafe.AsRef <uint>(dynamicOffsetsPtr));
                    }
                    else
                    {
                        executor.SetComputeResourceSet(
                            srse.Slot,
                            rs,
                            srse.DynamicOffsetCount,
                            ref Unsafe.AsRef <uint>(dynamicOffsetsPtr));
                    }
                    currentOffset += SetResourceSetEntrySize;
                    break;

                case SetScissorRectEntryID:
                    NoAllocSetScissorRectEntry ssre = Unsafe.ReadUnaligned <NoAllocSetScissorRectEntry>(entryBasePtr);
                    executor.SetScissorRect(ssre.Index, ssre.X, ssre.Y, ssre.Width, ssre.Height);
                    currentOffset += SetScissorRectEntrySize;
                    break;

                case SetVertexBufferEntryID:
                    NoAllocSetVertexBufferEntry svbe = Unsafe.ReadUnaligned <NoAllocSetVertexBufferEntry>(entryBasePtr);
                    executor.SetVertexBuffer(svbe.Index, svbe.Buffer.Get(_resourceList), svbe.Offset);
                    currentOffset += SetVertexBufferEntrySize;
                    break;

                case SetViewportEntryID:
                    NoAllocSetViewportEntry svpe = Unsafe.ReadUnaligned <NoAllocSetViewportEntry>(entryBasePtr);
                    executor.SetViewport(svpe.Index, ref svpe.Viewport);
                    currentOffset += SetViewportEntrySize;
                    break;

                case UpdateBufferEntryID:
                    NoAllocUpdateBufferEntry ube = Unsafe.ReadUnaligned <NoAllocUpdateBufferEntry>(entryBasePtr);
                    byte *dataPtr = (byte *)ube.StagingBlock.Data;
                    executor.UpdateBuffer(
                        ube.Buffer.Get(_resourceList),
                        ube.BufferOffsetInBytes,
                        (IntPtr)dataPtr, ube.StagingBlockSize);
                    currentOffset += UpdateBufferEntrySize;
                    break;

                case CopyBufferEntryID:
                    NoAllocCopyBufferEntry cbe = Unsafe.ReadUnaligned <NoAllocCopyBufferEntry>(entryBasePtr);
                    executor.CopyBuffer(
                        cbe.Source.Get(_resourceList),
                        cbe.SourceOffset,
                        cbe.Destination.Get(_resourceList),
                        cbe.DestinationOffset,
                        cbe.SizeInBytes);
                    currentOffset += CopyBufferEntrySize;
                    break;

                case CopyTextureEntryID:
                    NoAllocCopyTextureEntry cte = Unsafe.ReadUnaligned <NoAllocCopyTextureEntry>(entryBasePtr);
                    executor.CopyTexture(
                        cte.Source.Get(_resourceList),
                        cte.SrcX, cte.SrcY, cte.SrcZ,
                        cte.SrcMipLevel,
                        cte.SrcBaseArrayLayer,
                        cte.Destination.Get(_resourceList),
                        cte.DstX, cte.DstY, cte.DstZ,
                        cte.DstMipLevel,
                        cte.DstBaseArrayLayer,
                        cte.Width, cte.Height, cte.Depth,
                        cte.LayerCount);
                    currentOffset += CopyTextureEntrySize;
                    break;

                case ResolveTextureEntryID:
                    NoAllocResolveTextureEntry rte = Unsafe.ReadUnaligned <NoAllocResolveTextureEntry>(entryBasePtr);
                    executor.ResolveTexture(rte.Source.Get(_resourceList), rte.Destination.Get(_resourceList));
                    currentOffset += ResolveTextureEntrySize;
                    break;

                case GenerateMipmapsEntryID:
                    NoAllocGenerateMipmapsEntry gme = Unsafe.ReadUnaligned <NoAllocGenerateMipmapsEntry>(entryBasePtr);
                    executor.GenerateMipmaps(gme.Texture.Get(_resourceList));
                    currentOffset += GenerateMipmapsEntrySize;
                    break;

                case PushDebugGroupEntryID:
                    NoAllocPushDebugGroupEntry pdge = Unsafe.ReadUnaligned <NoAllocPushDebugGroupEntry>(entryBasePtr);
                    executor.PushDebugGroup(pdge.Name.Get(_resourceList));
                    currentOffset += PushDebugGroupEntrySize;
                    break;

                case PopDebugGroupEntryID:
                    executor.PopDebugGroup();
                    currentOffset += PopDebugGroupEntrySize;
                    break;

                case InsertDebugMarkerEntryID:
                    NoAllocInsertDebugMarkerEntry idme = Unsafe.ReadUnaligned <NoAllocInsertDebugMarkerEntry>(entryBasePtr);
                    executor.InsertDebugMarker(idme.Name.Get(_resourceList));
                    currentOffset += InsertDebugMarkerEntrySize;
                    break;

                default:
                    throw new InvalidOperationException("Invalid entry ID: " + id);
                }
            }
        }
Exemplo n.º 4
0
        public void ExecuteAll(OpenGLCommandExecutor executor)
        {
            int currentBlockIndex   = 0;
            EntryStorageBlock block = _blocks[currentBlockIndex];
            uint currentOffset      = 0;

            for (uint i = 0; i < _totalEntries; i++)
            {
                if (currentOffset == block.TotalSize)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                }

                uint id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                if (id == 0)
                {
                    currentBlockIndex += 1;
                    block              = _blocks[currentBlockIndex];
                    currentOffset      = 0;
                    id = Unsafe.Read <byte>(block.BasePtr + currentOffset);
                }

                Debug.Assert(id != 0);
                currentOffset += 1;
                byte *entryBasePtr = block.BasePtr + currentOffset;
                switch (id)
                {
                case BeginEntryID:
                    executor.Begin();
                    currentOffset += BeginEntrySize;
                    break;

                case ClearColorTargetID:
                    ref NoAllocClearColorTargetEntry ccte = ref Unsafe.AsRef <NoAllocClearColorTargetEntry>(entryBasePtr);
                    executor.ClearColorTarget(ccte.Index, ccte.ClearColor);
                    currentOffset += ClearColorTargetEntrySize;
                    break;

                case ClearDepthTargetID:
                    ref NoAllocClearDepthTargetEntry cdte = ref Unsafe.AsRef <NoAllocClearDepthTargetEntry>(entryBasePtr);
                    executor.ClearDepthStencil(cdte.Depth, cdte.Stencil);
                    currentOffset += ClearDepthTargetEntrySize;
                    break;

                case DrawEntryID:
                    ref NoAllocDrawEntry de = ref Unsafe.AsRef <NoAllocDrawEntry>(entryBasePtr);
                    executor.Draw(de.VertexCount, de.InstanceCount, de.VertexStart, de.InstanceStart);
                    currentOffset += DrawEntrySize;
                    break;

                case DrawIndexedEntryID:
                    ref NoAllocDrawIndexedEntry die = ref Unsafe.AsRef <NoAllocDrawIndexedEntry>(entryBasePtr);
                    executor.DrawIndexed(die.IndexCount, die.InstanceCount, die.IndexStart, die.VertexOffset, die.InstanceCount);
                    currentOffset += DrawIndexedEntrySize;
                    break;

                case DrawIndirectEntryID:
                    ref NoAllocDrawIndirectEntry drawIndirectEntry = ref Unsafe.AsRef <NoAllocDrawIndirectEntry>(entryBasePtr);
                    executor.DrawIndirect(
                        drawIndirectEntry.IndirectBuffer,
                        drawIndirectEntry.Offset,
                        drawIndirectEntry.DrawCount,
                        drawIndirectEntry.Stride);
                    currentOffset += DrawIndirectEntrySize;
                    break;

                case DrawIndexedIndirectEntryID:
                    ref NoAllocDrawIndexedIndirectEntry diie = ref Unsafe.AsRef <NoAllocDrawIndexedIndirectEntry>(entryBasePtr);
                    executor.DrawIndexedIndirect(diie.IndirectBuffer, diie.Offset, diie.DrawCount, diie.Stride);
                    currentOffset += DrawIndexedIndirectEntrySize;
                    break;

                case DispatchEntryID:
                    ref NoAllocDispatchEntry dispatchEntry = ref Unsafe.AsRef <NoAllocDispatchEntry>(entryBasePtr);
                    executor.Dispatch(dispatchEntry.GroupCountX, dispatchEntry.GroupCountY, dispatchEntry.GroupCountZ);
                    currentOffset += DispatchEntrySize;
                    break;

                case DispatchIndirectEntryID:
                    ref NoAllocDispatchIndirectEntry dispatchIndir = ref Unsafe.AsRef <NoAllocDispatchIndirectEntry>(entryBasePtr);
                    executor.DispatchIndirect(dispatchIndir.IndirectBuffer, dispatchIndir.Offset);
                    currentOffset += DispatchIndirectEntrySize;
                    break;

                case EndEntryID:
                    executor.End();
                    currentOffset += EndEntrySize;
                    break;

                case SetFramebufferEntryID:
                    ref NoAllocSetFramebufferEntry sfbe = ref Unsafe.AsRef <NoAllocSetFramebufferEntry>(entryBasePtr);
                    executor.SetFramebuffer(sfbe.Framebuffer);
                    currentOffset += SetFramebufferEntrySize;
                    break;

                case SetIndexBufferEntryID:
                    ref NoAllocSetIndexBufferEntry sibe = ref Unsafe.AsRef <NoAllocSetIndexBufferEntry>(entryBasePtr);
                    executor.SetIndexBuffer(sibe.Buffer.Item, sibe.Format);
                    currentOffset += SetIndexBufferEntrySize;
                    break;

                case SetPipelineEntryID:
                    ref NoAllocSetPipelineEntry spe = ref Unsafe.AsRef <NoAllocSetPipelineEntry>(entryBasePtr);
                    executor.SetPipeline(spe.Pipeline);
                    currentOffset += SetPipelineEntrySize;
                    break;

                case SetGraphicsResourceSetEntryID:
                    ref NoAllocSetGraphicsResourceSetEntry sgrse = ref Unsafe.AsRef <NoAllocSetGraphicsResourceSetEntry>(entryBasePtr);
                    executor.SetGraphicsResourceSet(sgrse.Slot, sgrse.ResourceSet);
                    currentOffset += SetGraphicsResourceSetEntrySize;
                    break;

                case SetComputeResourceSetEntryID:
                    ref NoAllocSetComputeResourceSetEntry scrse = ref Unsafe.AsRef <NoAllocSetComputeResourceSetEntry>(entryBasePtr);
                    executor.SetComputeResourceSet(scrse.Slot, scrse.ResourceSet);
                    currentOffset += SetComputeResourceSetEntrySize;
                    break;

                case SetScissorRectEntryID:
                    ref NoAllocSetScissorRectEntry ssre = ref Unsafe.AsRef <NoAllocSetScissorRectEntry>(entryBasePtr);
                    executor.SetScissorRect(ssre.Index, ssre.X, ssre.Y, ssre.Width, ssre.Height);
                    currentOffset += SetScissorRectEntrySize;
                    break;

                case SetVertexBufferEntryID:
                    ref NoAllocSetVertexBufferEntry svbe = ref Unsafe.AsRef <NoAllocSetVertexBufferEntry>(entryBasePtr);
                    executor.SetVertexBuffer(svbe.Index, svbe.Buffer.Item);
                    currentOffset += SetVertexBufferEntrySize;
                    break;

                case SetViewportEntryID:
                    ref NoAllocSetViewportEntry svpe = ref Unsafe.AsRef <NoAllocSetViewportEntry>(entryBasePtr);
                    executor.SetViewport(svpe.Index, ref svpe.Viewport);
                    currentOffset += SetViewportEntrySize;
                    break;

                case UpdateBufferEntryID:
                    ref NoAllocUpdateBufferEntry ube = ref Unsafe.AsRef <NoAllocUpdateBufferEntry>(entryBasePtr);
                    fixed(byte *dataPtr = &ube.StagingBlock.Array[0])
                    {
                        executor.UpdateBuffer(
                            ube.Buffer.Item,
                            ube.BufferOffsetInBytes,
                            (IntPtr)dataPtr, ube.StagingBlock.SizeInBytes);
                    }

                    currentOffset += UpdateBufferEntrySize;
                    break;

                case CopyBufferEntryID:
                    ref NoAllocCopyBufferEntry cbe = ref Unsafe.AsRef <NoAllocCopyBufferEntry>(entryBasePtr);
                    executor.CopyBuffer(
                        cbe.Source,
                        cbe.SourceOffset,
                        cbe.Destination,
                        cbe.DestinationOffset,
                        cbe.SizeInBytes);
                    currentOffset += CopyBufferEntrySize;
                    break;

                case CopyTextureEntryID:
                    ref NoAllocCopyTextureEntry cte = ref Unsafe.AsRef <NoAllocCopyTextureEntry>(entryBasePtr);
                    executor.CopyTexture(
                        cte.Source,
                        cte.SrcX, cte.SrcY, cte.SrcZ,
                        cte.SrcMipLevel,
                        cte.SrcBaseArrayLayer,
                        cte.Destination,
                        cte.DstX, cte.DstY, cte.DstZ,
                        cte.DstMipLevel,
                        cte.DstBaseArrayLayer,
                        cte.Width, cte.Height, cte.Depth,
                        cte.LayerCount);
                    currentOffset += CopyTextureEntrySize;
                    break;

                case ResolveTextureEntryID:
                    ref NoAllocResolveTextureEntry rte = ref Unsafe.AsRef <NoAllocResolveTextureEntry>(entryBasePtr);
                    executor.ResolveTexture(rte.Source.Item, rte.Destination.Item);
                    currentOffset += ResolveTextureEntrySize;
                    break;

                default:
                    throw new InvalidOperationException("Invalid entry ID: " + id);
                }
            }
        }