Ejemplo n.º 1
0
 private void RecreateAnimations()
 {
     unsafe
     {
         var nonEmpty = InstanceLists.Where(e => e.Value.Count > 0);
         var ptr      = (byte *)AnimationUniform.Map(0, nonEmpty.Count() * Animation.MaxInstructions);
         foreach (var keyList in nonEmpty)
         {
             if (!keyList.Value.Updated)
             {
                 ptr += Animation.SizeStd140;
                 continue;
             }
             var(texture, animation) = ((Texture2D, Animation))keyList.Key;
             if (animation is null)
             {
                 Animation.WriteNullToBuffer(ptr, out ptr);
             }
             else
             {
                 animation.WriteToBuffer(ptr, out ptr);
             }
         }
         AnimationUniform.Unmap();
     }
 }
Ejemplo n.º 2
0
        private void RecreateInstanceBuffers()
        {
            // Create sets
            var listInd = 0;

            foreach (var keyList in InstanceLists.Where(e => e.Value.Count > 0))
            {
                var list = keyList.Value;
                VKBuffer <SpriteInstanceInfo> computeBuffer;
                if (!ComputeInstanceBuffers.TryGetValue(list, out computeBuffer))
                {
                    computeBuffer = VKBuffer <SpriteInstanceInfo> .StorageBuffer(
                        $"{nameof(SpriteEffect)} compute instance buffer for list {list}",
                        Graphics,
                        MaxSprites
                        );

                    ComputeInstanceBuffers.Add(list, computeBuffer);
                }
                VKBuffer <VertexInstance> vertexBuffer;
                if (!VertexInstanceBuffers.TryGetValue(list, out vertexBuffer))
                {
                    vertexBuffer = VKBuffer <VertexInstance> .StorageBuffer(
                        $"{nameof(SpriteEffect)} vertex instance buffer for list {list}",
                        Graphics,
                        MaxSprites
                        );

                    VertexInstanceBuffers.Add(list, vertexBuffer);
                }
                using (var stagingBuffer = VKBuffer <SpriteInstanceInfo> .StagingBuffer(
                           $"{nameof(SpriteEffect)}.{nameof(RecreateInstanceBuffers)} staging buffer",
                           Graphics,
                           list.Count
                           ))
                {
                    unsafe
                    {
                        var ptr = stagingBuffer.Map(0, list.Count);
                        if (list.Updated)
                        {
                            var i = 0;
                            foreach (SpriteInstance inst in list.AllInstances)
                            {
                                if (i > MaxSprites)
                                {
                                    throw new InvalidOperationException("Too many similar sprites; raise the sprite limit on the effect");
                                }
                                *ptr = new SpriteInstanceInfo
                                {
                                    Time          = 0f,
                                    Position      = inst.StoredPosition,
                                    Velocity      = inst.StoredVelocity,
                                    Scale         = inst.StoredScale,
                                    Rotation      = inst.StoredRotation,
                                    ListIndex     = listInd,
                                    Rectangle     = inst.Rectangle,
                                    AnimationTime = inst.AnimationTime
                                };
                                ptr++;
                                i++;
                            }
                        }
                        else
                        {
                            foreach (SpriteInstance inst in list.AllInstances)
                            {
                                (*ptr).ListIndex = listInd;
                                ptr++;
                            }
                        }
                        stagingBuffer.Unmap();
                    }
                    using (var stagingFence = Graphics.Device.CreateFence(new FenceCreateInfo()))
                    {
                        using (var stagingCommands = Graphics.TransferQueueFamily.CreateCommandBuffers(CommandBufferLevel.Primary, 1)[0])
                        {
                            stagingCommands.Begin();
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.TopOfPipe, PipelineStages.Transfer,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    computeBuffer.Buffer,
                                    Accesses.None, Accesses.TransferWrite,
                                    0L, stagingBuffer.Size
                                    )
                            }
                                );
                            stagingCommands.CmdCopyBuffer(
                                stagingBuffer.Buffer,
                                computeBuffer.Buffer,
                                new BufferCopy[] { new BufferCopy(stagingBuffer.Size) }
                                );
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.Transfer, PipelineStages.ComputeShader,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    computeBuffer.Buffer,
                                    Accesses.TransferWrite, Accesses.ShaderRead,
                                    0L, stagingBuffer.Size
                                    )
                            }
                                );
                            stagingCommands.CmdPipelineBarrier(
                                PipelineStages.Transfer, PipelineStages.VertexInput,
                                bufferMemoryBarriers: new BufferMemoryBarrier[]
                            {
                                new BufferMemoryBarrier(
                                    vertexBuffer.Buffer,
                                    Accesses.TransferWrite, Accesses.VertexAttributeRead
                                    )
                            }
                                );
                            stagingCommands.End();

                            Graphics.TransferQueueFamily.HighestPriority.Submit(
                                new SubmitInfo(
                                    commandBuffers: new CommandBuffer[] { stagingCommands }
                                    ),
                                stagingFence
                                );
                            stagingFence.Wait();
                        }
                    }
                }
                listInd++;
            }
        }