Пример #1
0
        private void SetDataStatic(int offset, IntPtr data, int size)
        {
            var uploadBufferAlloc = context.AllocateUploadBuffer((ulong)size, 1);

            GraphicsUtility.CopyMemory(uploadBufferAlloc.Data, data, size);
            context.EndRenderPass();
            context.EnsureCommandBuffer();
            context.CommandBuffer.PipelineBarrier(
                pipelineStageMask, SharpVulkan.PipelineStageFlags.Transfer,
                SharpVulkan.DependencyFlags.None, 0, null, 0, null, 0, null);
            var copyRegion = new SharpVulkan.BufferCopy {
                SourceOffset      = uploadBufferAlloc.BufferOffset,
                DestinationOffset = (ulong)offset,
                Size = (ulong)size
            };

            context.CommandBuffer.CopyBuffer(uploadBufferAlloc.Buffer, backingBuffer.Buffer, 1, &copyRegion);
            var postMemoryBarrier = new SharpVulkan.MemoryBarrier {
                StructureType         = SharpVulkan.StructureType.MemoryBarrier,
                SourceAccessMask      = SharpVulkan.AccessFlags.TransferWrite,
                DestinationAccessMask = accessMask
            };

            context.CommandBuffer.PipelineBarrier(
                SharpVulkan.PipelineStageFlags.Transfer, pipelineStageMask,
                SharpVulkan.DependencyFlags.None, 1, &postMemoryBarrier, 0, null, 0, null);
        }
Пример #2
0
        public void SetUniform(int index, IntPtr data, int elementCount)
        {
            var info = uniformInfos[index];

            if (info.StagingOffset < 0)
            {
                throw new InvalidOperationException();
            }
            elementCount = Math.Min(elementCount, info.ArraySize);
            var dstData = uniformStagingData + info.StagingOffset;

            if (info.ColumnStride == info.ColumnSize)
            {
                GraphicsUtility.CopyMemory(dstData, data, info.ColumnSize * info.ColumnCount * elementCount);
            }
            else
            {
                var totalCols = info.ColumnCount * elementCount;
                for (var i = 0; i < totalCols; i++)
                {
                    GraphicsUtility.CopyMemory(dstData, data, info.ColumnSize);
                    dstData += info.ColumnStride;
                    data    += info.ColumnSize;
                }
            }
            dirtyStageMask |= info.StageMask;
        }
Пример #3
0
        public void SetUniform(int index, IntPtr data, int elementCount)
        {
            var info = uniformInfos[index];

            if (info.StagingDataOffset < 0)
            {
                throw new InvalidOperationException();
            }
            elementCount = Math.Min(elementCount, info.ArraySize);
            GraphicsUtility.CopyMemory(uniformStagingData + info.StagingDataOffset, data, info.ElementSize * elementCount);
            var lastDirtyElementCount = dirtyUniformElementCount[index];

            if (lastDirtyElementCount == 0)
            {
                dirtyUniformIndices[dirtyUniformCount++] = index;
            }
            dirtyUniformElementCount[index] = Math.Max(lastDirtyElementCount, elementCount);
        }
Пример #4
0
        private void SetDataDynamic(int offset, IntPtr data, int size, BufferSetDataMode mode)
        {
            if (mode == BufferSetDataMode.Discard)
            {
                backingBuffer.DiscardSlice(WriteFenceValue);
                WriteFenceValue = 0;
            }
            else
            {
                if (context.NextFenceValue <= WriteFenceValue)
                {
                    context.Flush();
                }
                context.WaitForFence(WriteFenceValue);
            }
            var dstData = backingBuffer.MapSlice() + offset;

            try {
                GraphicsUtility.CopyMemory(dstData, data, size);
            } finally {
                backingBuffer.UnmapSlice();
            }
        }
Пример #5
0
 internal void UpdateUniformBuffers(ulong fenceValue)
 {
     for (var i = 0; i < uniformBuffers.Length; i++)
     {
         var buffer     = uniformBuffers[i];
         var bufferInfo = uniformBufferInfos[i];
         if ((dirtyStageMask & bufferInfo.Stage) == 0)
         {
             continue;
         }
         buffer.DiscardSlice(uniformBufferWriteFenceValue);
         var bufferData = buffer.MapSlice();
         foreach (var templateEntry in bufferInfo.UpdateTemplate)
         {
             var dstData = bufferData + templateEntry.BufferOffset;
             var srcData = uniformStagingData + templateEntry.StagingOffset;
             GraphicsUtility.CopyMemory(dstData, srcData, templateEntry.Size);
         }
         buffer.UnmapSlice();
     }
     uniformBufferWriteFenceValue = fenceValue;
     dirtyStageMask = ShaderStageMask.None;
 }
Пример #6
0
        internal void GetData(Format dstFormat, int level, int x, int y, int width, int height, IntPtr data)
        {
            if (IsPvrtc1Format(Format))
            {
                throw new NotImplementedException();
            }
            var dataSize = GraphicsUtility.CalculateImageDataSize(Format, width, height);

            context.EnsureReadbackBuffer((ulong)dataSize);
            context.EndRenderPass();
            context.EnsureCommandBuffer();
            var preMemoryBarrier = new SharpVulkan.ImageMemoryBarrier {
                StructureType         = SharpVulkan.StructureType.ImageMemoryBarrier,
                Image                 = image,
                OldLayout             = SharpVulkan.ImageLayout.ShaderReadOnlyOptimal,
                NewLayout             = SharpVulkan.ImageLayout.TransferSourceOptimal,
                SourceAccessMask      = SharpVulkan.AccessFlags.ShaderRead,
                DestinationAccessMask = SharpVulkan.AccessFlags.TransferRead,
                SubresourceRange      = new SharpVulkan.ImageSubresourceRange(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level, 1)
            };

            context.CommandBuffer.PipelineBarrier(
                SharpVulkan.PipelineStageFlags.VertexShader | SharpVulkan.PipelineStageFlags.FragmentShader,
                SharpVulkan.PipelineStageFlags.Transfer, SharpVulkan.DependencyFlags.None,
                0, null, 0, null, 1, &preMemoryBarrier);
            var copyRegion = new SharpVulkan.BufferImageCopy {
                BufferOffset      = 0,
                BufferRowLength   = (uint)width,
                BufferImageHeight = (uint)height,
                ImageOffset       = new SharpVulkan.Offset3D(x, y, 0),
                ImageExtent       = new SharpVulkan.Extent3D((uint)width, (uint)height, 1),
                ImageSubresource  = new SharpVulkan.ImageSubresourceLayers(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level)
            };

            context.CommandBuffer.CopyImageToBuffer(
                image, SharpVulkan.ImageLayout.TransferSourceOptimal, context.ReadbackBuffer, 1, &copyRegion);
            var postMemoryBarrier = new SharpVulkan.ImageMemoryBarrier {
                StructureType         = SharpVulkan.StructureType.ImageMemoryBarrier,
                Image                 = image,
                OldLayout             = SharpVulkan.ImageLayout.TransferSourceOptimal,
                NewLayout             = SharpVulkan.ImageLayout.ShaderReadOnlyOptimal,
                SourceAccessMask      = SharpVulkan.AccessFlags.TransferRead,
                DestinationAccessMask = SharpVulkan.AccessFlags.ShaderRead,
                SubresourceRange      = new SharpVulkan.ImageSubresourceRange(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level, 1)
            };

            context.CommandBuffer.PipelineBarrier(
                SharpVulkan.PipelineStageFlags.Transfer,
                SharpVulkan.PipelineStageFlags.VertexShader | SharpVulkan.PipelineStageFlags.FragmentShader,
                SharpVulkan.DependencyFlags.None, 0, null, 0, null, 1, &postMemoryBarrier);
            context.Finish();
            var readbackBufferMemory       = context.ReadbackBufferMemory;
            var readbackBufferMappedMemory = context.MemoryAllocator.Map(readbackBufferMemory);

            try {
                context.MemoryAllocator.InvalidateMappedMemoryRange(readbackBufferMemory, 0, (ulong)dataSize);
                if (dstFormat == Format)
                {
                    GraphicsUtility.CopyMemory(data, readbackBufferMappedMemory, Format.GetSize() * width * height);
                }
                else
                {
                    var decoder      = FormatConverter.GetDecoder(Format);
                    var encoder      = FormatConverter.GetEncoder(dstFormat);
                    var srcTexelSize = Format.GetSize();
                    var dstTexelSize = dstFormat.GetSize();
                    var srcData      = readbackBufferMappedMemory;
                    var dstData      = data;
                    var texelCount   = width * height;
                    while (texelCount-- > 0)
                    {
                        encoder(dstData, decoder(srcData));
                        srcData += srcTexelSize;
                        dstData += dstTexelSize;
                    }
                }
            } finally {
                context.MemoryAllocator.Unmap(readbackBufferMemory);
            }
        }
Пример #7
0
        public void SetData(int level, int x, int y, int width, int height, IntPtr data)
        {
            var dataSize = GraphicsUtility.CalculateImageDataSize(Format, width, height);

            if (IsPvrtc1Format(Format))
            {
                if (x != 0 || y != 0 || width != Width || height != Height)
                {
                    throw new NotSupportedException();
                }
                if (context.NextFenceValue <= WriteFenceValue)
                {
                    context.Flush();
                }
                context.WaitForFence(WriteFenceValue);
                var dstData = Context.MemoryAllocator.Map(memory);
                try {
                    GraphicsUtility.CopyMemory(dstData, data, dataSize);
                } finally {
                    Context.MemoryAllocator.Unmap(memory);
                }
            }
            else
            {
                ulong bufferOffsetAlignment = 4;
                bufferOffsetAlignment = GraphicsUtility.CombineAlignment(bufferOffsetAlignment, (ulong)Format.GetSize());
                bufferOffsetAlignment = GraphicsUtility.CombineAlignment(bufferOffsetAlignment, context.PhysicalDeviceLimits.OptimalBufferCopyOffsetAlignment);
                var uploadBufferAlloc = context.AllocateUploadBuffer((ulong)dataSize, bufferOffsetAlignment);
                GraphicsUtility.CopyMemory(uploadBufferAlloc.Data, data, dataSize);
                context.EndRenderPass();
                context.EnsureCommandBuffer();
                var preMemoryBarrier = new SharpVulkan.ImageMemoryBarrier {
                    StructureType         = SharpVulkan.StructureType.ImageMemoryBarrier,
                    Image                 = image,
                    OldLayout             = SharpVulkan.ImageLayout.ShaderReadOnlyOptimal,
                    NewLayout             = SharpVulkan.ImageLayout.TransferDestinationOptimal,
                    SourceAccessMask      = SharpVulkan.AccessFlags.ShaderRead,
                    DestinationAccessMask = SharpVulkan.AccessFlags.TransferWrite,
                    SubresourceRange      = new SharpVulkan.ImageSubresourceRange(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level, 1)
                };
                context.CommandBuffer.PipelineBarrier(
                    SharpVulkan.PipelineStageFlags.VertexShader | SharpVulkan.PipelineStageFlags.FragmentShader,
                    SharpVulkan.PipelineStageFlags.Transfer, SharpVulkan.DependencyFlags.None,
                    0, null, 0, null, 1, &preMemoryBarrier);
                var copyRegion = new SharpVulkan.BufferImageCopy {
                    BufferOffset      = uploadBufferAlloc.BufferOffset,
                    BufferRowLength   = (uint)width,
                    BufferImageHeight = (uint)height,
                    ImageOffset       = new SharpVulkan.Offset3D(x, y, 0),
                    ImageExtent       = new SharpVulkan.Extent3D((uint)width, (uint)height, 1),
                    ImageSubresource  = new SharpVulkan.ImageSubresourceLayers(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level)
                };
                context.CommandBuffer.CopyBufferToImage(
                    uploadBufferAlloc.Buffer, image, SharpVulkan.ImageLayout.TransferDestinationOptimal, 1, &copyRegion);
                var postMemoryBarrier = new SharpVulkan.ImageMemoryBarrier {
                    StructureType         = SharpVulkan.StructureType.ImageMemoryBarrier,
                    Image                 = image,
                    OldLayout             = SharpVulkan.ImageLayout.TransferDestinationOptimal,
                    NewLayout             = SharpVulkan.ImageLayout.ShaderReadOnlyOptimal,
                    SourceAccessMask      = SharpVulkan.AccessFlags.TransferWrite,
                    DestinationAccessMask = SharpVulkan.AccessFlags.ShaderRead,
                    SubresourceRange      = new SharpVulkan.ImageSubresourceRange(SharpVulkan.ImageAspectFlags.Color, 0, 1, (uint)level, 1)
                };
                context.CommandBuffer.PipelineBarrier(
                    SharpVulkan.PipelineStageFlags.Transfer,
                    SharpVulkan.PipelineStageFlags.VertexShader | SharpVulkan.PipelineStageFlags.FragmentShader,
                    SharpVulkan.DependencyFlags.None, 0, null, 0, null, 1, &postMemoryBarrier);
            }
        }