public void Draw(uint vertexCount, uint instanceCount, uint vertexStart, uint instanceStart) { NoAllocDrawEntry entry = new NoAllocDrawEntry(vertexCount, instanceCount, vertexStart, instanceStart); AddEntry(DrawEntryID, ref entry); }
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); } } }
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); } } }
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); } } }