示例#1
0
        public void ExecuteAll(OpenGLCommandExecutor executor)
        {
            foreach (OpenGLCommandEntry entry in _commands)
            {
                switch (entry)
                {
                case BeginEntry be:
                    executor.Begin();
                    break;

                case ClearColorTargetEntry ccte:
                    executor.ClearColorTarget(ccte.Index, ccte.ClearColor);
                    break;

                case ClearDepthTargetEntry cdte:
                    executor.ClearDepthTarget(cdte.Depth);
                    break;

                case DrawEntry de:
                    executor.Draw(de.IndexCount, de.InstanceCount, de.IndexStart, de.VertexOffset, de.InstanceCount);
                    break;

                case EndEntry ee:
                    executor.End();
                    break;

                case SetFramebufferEntry sfbe:
                    executor.SetFramebuffer(sfbe.Framebuffer);
                    break;

                case SetIndexBufferEntry sibe:
                    executor.SetIndexBuffer(sibe.IndexBuffer);
                    break;

                case SetPipelineEntry spe:
                    executor.SetPipeline(spe.Pipeline);
                    break;

                case SetResourceSetEntry srse:
                    executor.SetResourceSet(srse.Slot, srse.ResourceSet);
                    break;

                case SetScissorRectEntry ssre:
                    executor.SetScissorRect(ssre.Index, ssre.X, ssre.Y, ssre.Width, ssre.Height);
                    break;

                case SetVertexBufferEntry svbe:
                    executor.SetVertexBuffer(svbe.Index, svbe.VertexBuffer);
                    break;

                case SetViewportEntry sve:
                    executor.SetViewport(sve.Index, ref sve.Viewport);
                    break;

                case UpdateBufferEntry ube:
                    executor.UpdateBuffer(ube.Buffer, ube.BufferOffsetInBytes, ube.StagingBlock);
                    break;

                case UpdateTextureEntry ute:
                    executor.UpdateTexture(
                        ute.Texture,
                        ute.StagingBlock,
                        ute.X,
                        ute.Y,
                        ute.Z,
                        ute.Width,
                        ute.Height,
                        ute.Depth,
                        ute.MipLevel,
                        ute.ArrayLayer);
                    break;

                case UpdateTextureCubeEntry utce:
                    executor.UpdateTextureCube(
                        utce.TextureCube,
                        utce.StagingBlock,
                        utce.Face,
                        utce.X,
                        utce.Y,
                        utce.Width,
                        utce.Height,
                        utce.MipLevel,
                        utce.ArrayLayer);
                    break;

                default:
                    throw new InvalidOperationException("Command type not handled: " + executor.GetType().Name);
                }
            }
        }
        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.ClearDepthTarget(cdte.Depth);
                    currentOffset += ClearDepthTargetEntrySize;
                    break;

                case DrawEntryID:
                    ref NoAllocDrawEntry de = ref Unsafe.AsRef <NoAllocDrawEntry>(entryBasePtr);
                    executor.Draw(de.IndexCount, de.InstanceCount, de.IndexStart, de.VertexOffset, de.InstanceCount);
                    currentOffset += DrawEntrySize;
                    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.IndexBuffer.Item);
                    currentOffset += SetIndexBufferEntrySize;
                    break;

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

                case SetResourceSetEntryID:
                    ref NoAllocSetResourceSetEntry srse = ref Unsafe.AsRef <NoAllocSetResourceSetEntry>(entryBasePtr);
                    executor.SetResourceSet(srse.Slot, srse.ResourceSet);
                    currentOffset += SetResourceSetEntrySize;
                    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.VertexBuffer.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);
                    executor.UpdateBuffer(
                        ube.Buffer.Item,
                        ube.BufferOffsetInBytes,
                        new StagingBlock(ube.StagingBlock.Array, ube.StagingBlock.SizeInBytes, _memoryPool));
                    currentOffset += UpdateBufferEntrySize;
                    break;

                case UpdateTextureEntryID:
                    ref NoAllocUpdateTextureEntry ute = ref Unsafe.AsRef <NoAllocUpdateTextureEntry>(entryBasePtr);
                    executor.UpdateTexture(
                        ute.Texture,
                        new StagingBlock(ute.StagingBlock.Array, ute.StagingBlock.SizeInBytes, _memoryPool),
                        ute.X,
                        ute.Y,
                        ute.Z,
                        ute.Width,
                        ute.Height,
                        ute.Depth,
                        ute.MipLevel,
                        ute.ArrayLayer);
                    currentOffset += UpdateTextureEntrySize;
                    break;

                case UpdateTextureCubeEntryID:
                    ref NoAllocUpdateTextureCubeEntry utce = ref Unsafe.AsRef <NoAllocUpdateTextureCubeEntry>(entryBasePtr);
                    executor.UpdateTextureCube(
                        utce.Texture,
                        new StagingBlock(utce.StagingBlock.Array, utce.StagingBlock.SizeInBytes, _memoryPool),
                        utce.Face,
                        utce.X,
                        utce.Y,
                        utce.Width,
                        utce.Height,
                        utce.MipLevel,
                        utce.ArrayLayer);
                    currentOffset += UpdateTextureCubeEntrySize;
                    break;

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