From 97e616ab993a6c29e658a0e2288c1e9e27220453 Mon Sep 17 00:00:00 2001 From: Elias Holzer Date: Tue, 30 Oct 2018 01:36:51 +0100 Subject: [PATCH 01/14] [Graphics] When mixing Dispatch and Draw calls in Direct3D11 the set shaders on the native device context got mixed up. (#249) For example effect A sets a hull shader, effect B a compute shader and effect C only vertex and pixel shaders - the hull shader from effect A was now still set on the native device context leading to a broken draw call because when applying effect B the draw shaders were not cleared and follow up comparison when applying C failed. --- .../Direct3D/PipelineState.Direct3D.cs | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs b/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs index 175b3858cf..3dce2f9529 100644 --- a/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs +++ b/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs @@ -71,25 +71,19 @@ internal void Apply(CommandList commandList, PipelineState previousPipeline) } if (effectBytecode != previousPipeline.effectBytecode) - { - if (computeShader != null) - { - if (computeShader != previousPipeline.computeShader) - nativeDeviceContext.ComputeShader.Set(computeShader); - } - else - { - if (vertexShader != previousPipeline.vertexShader) - nativeDeviceContext.VertexShader.Set(vertexShader); - if (pixelShader != previousPipeline.pixelShader) - nativeDeviceContext.PixelShader.Set(pixelShader); - if (hullShader != previousPipeline.hullShader) - nativeDeviceContext.HullShader.Set(hullShader); - if (domainShader != previousPipeline.domainShader) - nativeDeviceContext.DomainShader.Set(domainShader); - if (geometryShader != previousPipeline.geometryShader) - nativeDeviceContext.GeometryShader.Set(geometryShader); - } + { + if (computeShader != previousPipeline.computeShader) + nativeDeviceContext.ComputeShader.Set(computeShader); + if (vertexShader != previousPipeline.vertexShader) + nativeDeviceContext.VertexShader.Set(vertexShader); + if (pixelShader != previousPipeline.pixelShader) + nativeDeviceContext.PixelShader.Set(pixelShader); + if (hullShader != previousPipeline.hullShader) + nativeDeviceContext.HullShader.Set(hullShader); + if (domainShader != previousPipeline.domainShader) + nativeDeviceContext.DomainShader.Set(domainShader); + if (geometryShader != previousPipeline.geometryShader) + nativeDeviceContext.GeometryShader.Set(geometryShader); } if (blendState != previousPipeline.blendState || sampleMask != previousPipeline.sampleMask) From e01292f5be76fa827d0203b289056ecdfb57770b Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Tue, 30 Oct 2018 01:37:39 +0100 Subject: [PATCH 02/14] version bump to 3.0.0.7 (#247) --- Xenko.xkpkg | 2 +- sources/shared/SharedAssemblyInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Xenko.xkpkg b/Xenko.xkpkg index dffb639a2e..0244127a49 100644 --- a/Xenko.xkpkg +++ b/Xenko.xkpkg @@ -3,7 +3,7 @@ Id: cc1bcc78-50b2-4da6-8902-f7a3ae42898b SerializedVersion: {Assets: 0.0.4} Meta: Name: Xenko - Version: 3.0.0.6-dev + Version: 3.0.0.7-dev Owners: - Xenko Authors: diff --git a/sources/shared/SharedAssemblyInfo.cs b/sources/shared/SharedAssemblyInfo.cs index 1c21548ab3..ac0a0e7b1a 100644 --- a/sources/shared/SharedAssemblyInfo.cs +++ b/sources/shared/SharedAssemblyInfo.cs @@ -26,7 +26,7 @@ internal class XenkoVersion /// /// The version used by editor for display purpose. 4th digit needs to be at least 1 if used (due to NuGet special cases). /// - public const string PublicVersion = "3.0.0.6"; + public const string PublicVersion = "3.0.0.7"; /// /// The current assembly version as text, currently same as . From d9a3ba88140c1bf2c9b3f6c0be4a9d2b76d1a8b7 Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Tue, 30 Oct 2018 02:50:53 +0100 Subject: [PATCH 03/14] [Graphics] fixed geometry shader with stream out (#245) * fixed geometry shader with stream out creation and added BufferFlags.StreamOutput * replaced isStreamOutput with bindFlags --- .../engine/Xenko.Graphics/Buffer.Vertex.cs | 9 +++++--- sources/engine/Xenko.Graphics/BufferFlags.cs | 5 +++++ .../Direct3D/Buffer.Direct3D.cs | 3 +++ .../Direct3D/PipelineState.Direct3D.cs | 21 +++++++++++-------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/sources/engine/Xenko.Graphics/Buffer.Vertex.cs b/sources/engine/Xenko.Graphics/Buffer.Vertex.cs index 64edcdbcda..733457b08c 100644 --- a/sources/engine/Xenko.Graphics/Buffer.Vertex.cs +++ b/sources/engine/Xenko.Graphics/Buffer.Vertex.cs @@ -38,10 +38,13 @@ public static class Vertex /// The . /// The size in bytes. /// The usage. - /// A Vertex buffer - public static Buffer New(GraphicsDevice device, int size, GraphicsResourceUsage usage = GraphicsResourceUsage.Default) + /// The bind flags, can be combined with to use the buffer as a stream output target. + /// + /// A Vertex buffer + /// + public static Buffer New(GraphicsDevice device, int size, GraphicsResourceUsage usage = GraphicsResourceUsage.Default, BufferFlags bindFlags = BufferFlags.VertexBuffer) { - return Buffer.New(device, size, BufferFlags.VertexBuffer, usage); + return Buffer.New(device, size, bindFlags, usage); } /// diff --git a/sources/engine/Xenko.Graphics/BufferFlags.cs b/sources/engine/Xenko.Graphics/BufferFlags.cs index e1c9c34852..6a89d202be 100644 --- a/sources/engine/Xenko.Graphics/BufferFlags.cs +++ b/sources/engine/Xenko.Graphics/BufferFlags.cs @@ -71,5 +71,10 @@ public enum BufferFlags /// Creates an indirect arguments buffer. /// ArgumentBuffer = 1024, + + /// + /// Creates a buffer for the geometry shader stream-output stage. + /// + StreamOutput = 2048, } } diff --git a/sources/engine/Xenko.Graphics/Direct3D/Buffer.Direct3D.cs b/sources/engine/Xenko.Graphics/Direct3D/Buffer.Direct3D.cs index 29f291d97e..e91782fe42 100644 --- a/sources/engine/Xenko.Graphics/Direct3D/Buffer.Direct3D.cs +++ b/sources/engine/Xenko.Graphics/Direct3D/Buffer.Direct3D.cs @@ -240,6 +240,9 @@ private static SharpDX.Direct3D11.BufferDescription ConvertToNativeDescription(B if ((bufferFlags & BufferFlags.ArgumentBuffer) == BufferFlags.ArgumentBuffer) desc.OptionFlags |= ResourceOptionFlags.DrawIndirectArguments; + if ((bufferFlags & BufferFlags.StreamOutput) != 0) + desc.BindFlags |= BindFlags.StreamOutput; + return desc; } diff --git a/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs b/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs index 3dce2f9529..4b793b4cb9 100644 --- a/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs +++ b/sources/engine/Xenko.Graphics/Direct3D/PipelineState.Direct3D.cs @@ -190,20 +190,23 @@ private void CreateShaders(DevicePipelineStateCache pipelineStateCache) case ShaderStage.Geometry: if (reflection.ShaderStreamOutputDeclarations != null && reflection.ShaderStreamOutputDeclarations.Count > 0) { - // Calculate the strides - var soStrides = new List(); + // stream out elements + var soElements = new List(); foreach (var streamOutputElement in reflection.ShaderStreamOutputDeclarations) { - for (int i = soStrides.Count; i < (streamOutputElement.Stream + 1); i++) + var soElem = new SharpDX.Direct3D11.StreamOutputElement() { - soStrides.Add(0); - } - - soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float); + Stream = streamOutputElement.Stream, + SemanticIndex = streamOutputElement.SemanticIndex, + SemanticName = streamOutputElement.SemanticName, + StartComponent = streamOutputElement.StartComponent, + ComponentCount = streamOutputElement.ComponentCount, + OutputSlot = streamOutputElement.OutputSlot + }; + soElements.Add(soElem); } - var soElements = new SharpDX.Direct3D11.StreamOutputElement[0]; // TODO CREATE StreamOutputElement from bytecode.Reflection.ShaderStreamOutputDeclarations // TODO GRAPHICS REFACTOR better cache - geometryShader = new SharpDX.Direct3D11.GeometryShader(GraphicsDevice.NativeDevice, shaderBytecode, soElements, soStrides.ToArray(), reflection.StreamOutputRasterizedStream); + geometryShader = new SharpDX.Direct3D11.GeometryShader(GraphicsDevice.NativeDevice, shaderBytecode, soElements.ToArray(), reflection.StreamOutputStrides, reflection.StreamOutputRasterizedStream); } else { From d3cae33a782782d55a8e272d5a859fe9c042d86a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Nov 2018 17:35:32 +0900 Subject: [PATCH 04/14] [Presentation] TextLogViewer: fix Typo (courtesy of Eideren) --- .../Xenko.Core.Presentation/Controls/TextLogViewer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/presentation/Xenko.Core.Presentation/Controls/TextLogViewer.cs b/sources/presentation/Xenko.Core.Presentation/Controls/TextLogViewer.cs index dcd886cf15..28ed3218c7 100644 --- a/sources/presentation/Xenko.Core.Presentation/Controls/TextLogViewer.cs +++ b/sources/presentation/Xenko.Core.Presentation/Controls/TextLogViewer.cs @@ -357,13 +357,13 @@ private void AppendText([NotNull] FlowDocument document, [NotNull] IEnumerable 0) { var c = lineText[tokenIndex - 1]; - if ((c >= 'A' && c <= 'A') || (c >= 'a' && c <= 'z')) + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) acceptResult = false; } if (tokenIndex + searchToken.Length < lineText.Length) { var c = lineText[tokenIndex + searchToken.Length]; - if ((c >= 'A' && c <= 'A') || (c >= 'a' && c <= 'z')) + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) acceptResult = false; } } From 2cb682d25294eb191ec787efb8124e05e7282cdf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 15 Nov 2018 14:28:00 +0900 Subject: [PATCH 05/14] [Audio] Opus: ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size) (fixes #235) --- .../Xenko.Assets/Media/SoundAssetCompiler.cs | 9 ++++++--- sources/engine/Xenko.Audio/Native/Celt.cpp | 5 +++++ sources/engine/Xenko.Audio/Native/Celt.cs | 16 ++++++++++++++++ sources/engine/Xenko.Audio/Sound.cs | 6 +++++- sources/engine/Xenko.Audio/SoundSerializer.cs | 2 ++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sources/engine/Xenko.Assets/Media/SoundAssetCompiler.cs b/sources/engine/Xenko.Assets/Media/SoundAssetCompiler.cs index e0d9df50ee..669705a370 100644 --- a/sources/engine/Xenko.Assets/Media/SoundAssetCompiler.cs +++ b/sources/engine/Xenko.Assets/Media/SoundAssetCompiler.cs @@ -34,6 +34,7 @@ protected class DecodeSoundFileCommand : AssetCommand public DecodeSoundFileCommand(string url, SoundAsset parameters, IAssetFinder assetFinder) : base(url, parameters, assetFinder) { + Version = 1; } /// @@ -105,11 +106,12 @@ protected override async Task DoCommandOverride(ICommandContext co writer.Write((short)len); outputStream.Write(outputBuffer, 0, len); - count = 0; - Array.Clear(buffer, 0, frameSize); - + newSound.Samples += count / channels; newSound.NumberOfPackets++; newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len); + + count = 0; + Array.Clear(buffer, 0, frameSize); } buffer[count] = reader.ReadSingle(); @@ -122,6 +124,7 @@ protected override async Task DoCommandOverride(ICommandContext co writer.Write((short)len); outputStream.Write(outputBuffer, 0, len); + newSound.Samples += count / channels; newSound.NumberOfPackets++; newSound.MaxPacketLength = Math.Max(newSound.MaxPacketLength, len); } diff --git a/sources/engine/Xenko.Audio/Native/Celt.cpp b/sources/engine/Xenko.Audio/Native/Celt.cpp index cb6fb9396a..8cb5639194 100644 --- a/sources/engine/Xenko.Audio/Native/Celt.cpp +++ b/sources/engine/Xenko.Audio/Native/Celt.cpp @@ -46,6 +46,11 @@ extern "C" { delete celt; } + DLL_EXPORT_API int xnCeltGetDecoderSampleDelay(XenkoCelt* celt, int32_t* delay) + { + return opus_custom_decoder_ctl(celt->GetDecoder(), OPUS_GET_LOOKAHEAD(delay)); + } + DLL_EXPORT_API int xnCeltEncodeFloat(XenkoCelt* celt, float* inputSamples, int numberOfInputSamples, uint8_t* outputBuffer, int maxOutputSize) { return opus_custom_encode_float(celt->GetEncoder(), inputSamples, numberOfInputSamples, outputBuffer, maxOutputSize); diff --git a/sources/engine/Xenko.Audio/Native/Celt.cs b/sources/engine/Xenko.Audio/Native/Celt.cs index a48074c275..3b93c88813 100644 --- a/sources/engine/Xenko.Audio/Native/Celt.cs +++ b/sources/engine/Xenko.Audio/Native/Celt.cs @@ -88,6 +88,18 @@ public unsafe int Decode(byte[] inputBuffer, int inputBufferSize, short* outputS } } + /// + /// Gets the delay between encoder and decoder (in number of samples). This should be skipped at the beginning of a decoded stream. + /// + /// + public unsafe int GetDecoderSampleDelay() + { + var delay = 0; + if (xnCeltGetDecoderSampleDelay(celtPtr, ref delay) != 0) + delay = 0; + return delay; + } + /// /// Encode PCM audio into celt compressed format /// @@ -142,6 +154,10 @@ public unsafe int Encode(float[] audioSamples, byte[] outputBuffer) [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] private static extern void xnCeltDestroy(IntPtr celt); + [SuppressUnmanagedCodeSecurity] + [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] + private static extern int xnCeltGetDecoderSampleDelay(IntPtr celt, ref int delay); + [SuppressUnmanagedCodeSecurity] [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] private static extern unsafe int xnCeltEncodeFloat(IntPtr celt, float* inputSamples, int numberOfInputSamples, byte* outputBuffer, int maxOutputSize); diff --git a/sources/engine/Xenko.Audio/Sound.cs b/sources/engine/Xenko.Audio/Sound.cs index b7b88b66c0..1a168b2f61 100644 --- a/sources/engine/Xenko.Audio/Sound.cs +++ b/sources/engine/Xenko.Audio/Sound.cs @@ -31,6 +31,8 @@ public sealed class Sound : SoundBase internal IVirtualFileProvider FileProvider; + internal int Samples { get; set; } + /// /// Create a new sound effect instance of the sound effect. /// The audio data are shared between the instances so that useless memory copies is avoided. @@ -96,7 +98,9 @@ internal void LoadSoundInMemory() offset += samplesDecoded * Channels * sizeof(short); } - AudioLayer.BufferFill(PreloadedBuffer, memory.Pointer, memory.Length * sizeof(short), SampleRate, Channels == 1); + // Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size) + var samplesToSkip = decoder.GetDecoderSampleDelay(); + AudioLayer.BufferFill(PreloadedBuffer, memory.Pointer + samplesToSkip * Channels * sizeof(short), Samples * Channels * sizeof(short), SampleRate, Channels == 1); memory.Dispose(); } } diff --git a/sources/engine/Xenko.Audio/SoundSerializer.cs b/sources/engine/Xenko.Audio/SoundSerializer.cs index 758316b8fc..2434bd3b23 100644 --- a/sources/engine/Xenko.Audio/SoundSerializer.cs +++ b/sources/engine/Xenko.Audio/SoundSerializer.cs @@ -27,6 +27,7 @@ public override void Serialize(ref Sound obj, ArchiveMode mode, SerializationStr obj.Spatialized = stream.ReadBoolean(); obj.NumberOfPackets = stream.ReadInt16(); obj.MaxPacketLength = stream.ReadInt16(); + obj.Samples = stream.ReadInt32(); if (!obj.StreamFromDisk && audioEngine != null && audioEngine.State != AudioEngineState.Invalidated && audioEngine.State != AudioEngineState.Disposed) //immediatelly preload all the data and decode { @@ -47,6 +48,7 @@ public override void Serialize(ref Sound obj, ArchiveMode mode, SerializationStr stream.Write(obj.Spatialized); stream.Write((short)obj.NumberOfPackets); stream.Write((short)obj.MaxPacketLength); + stream.Write(obj.Samples); } } } From 5dfe8775bbc942771f068380a3768e394a7d9366 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 15 Nov 2018 14:37:44 +0900 Subject: [PATCH 06/14] Update BACKERS.md --- BACKERS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BACKERS.md b/BACKERS.md index 0e3000cf3f..7dd7c6bbc0 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -40,6 +40,8 @@ Thank you everybody for your generous contributions! * Beliar * Robert Iadanza * SleepyMode +* Marko Viitanen +* David R Miller ## Mini Backers From 2eb9a6f0b34b182026e7eda7255e86521419dba8 Mon Sep 17 00:00:00 2001 From: SleepyMode Date: Thu, 15 Nov 2018 07:39:02 +0200 Subject: [PATCH 07/14] Update to C# 7.2 (#264) --- build/Xenko.Core.GlobalSettings.Local.targets | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/Xenko.Core.GlobalSettings.Local.targets b/build/Xenko.Core.GlobalSettings.Local.targets index 01e13a75cd..e6ddf0c0c0 100644 --- a/build/Xenko.Core.GlobalSettings.Local.targets +++ b/build/Xenko.Core.GlobalSettings.Local.targets @@ -9,4 +9,8 @@ $(MSBuildThisFileDirectory)..\Bin\$(XenkoBuildDirectory)\ $([System.IO.Path]::GetFullPath('$(XenkoOutputCommonDir)')) + + + 7.2 + \ No newline at end of file From e578ccd7aaa28fa0188d5dd75379451db25c9f50 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 28 Oct 2018 23:05:18 +0900 Subject: [PATCH 08/14] [Assets] Properly report asset compiler errors for runtime dependencies --- .../Analysis/BuildAssetNode.cs | 10 +++++ sources/assets/Xenko.Core.Assets/AssetItem.cs | 2 +- .../Compiler/AssetDependenciesCompiler.cs | 44 ++++++++++++++----- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/sources/assets/Xenko.Core.Assets/Analysis/BuildAssetNode.cs b/sources/assets/Xenko.Core.Assets/Analysis/BuildAssetNode.cs index f9ace5a4b0..d8a43bcc60 100644 --- a/sources/assets/Xenko.Core.Assets/Analysis/BuildAssetNode.cs +++ b/sources/assets/Xenko.Core.Assets/Analysis/BuildAssetNode.cs @@ -93,6 +93,11 @@ public override int GetHashCode() } } + public override string ToString() + { + return $"{DependencyType}: {Source} => {Target}"; + } + /// public static bool operator ==(BuildAssetLink left, BuildAssetLink right) { @@ -235,6 +240,11 @@ private void AddDependencies(AssetItem assetItem, HashSet t } } + public override string ToString() + { + return $"{AssetItem.Location} ({References.Count} refs)"; + } + private class RuntimeDependenciesCollector : AssetVisitorBase { private object visitedRuntimeObject; diff --git a/sources/assets/Xenko.Core.Assets/AssetItem.cs b/sources/assets/Xenko.Core.Assets/AssetItem.cs index a66aca4ece..44e1e32a92 100644 --- a/sources/assets/Xenko.Core.Assets/AssetItem.cs +++ b/sources/assets/Xenko.Core.Assets/AssetItem.cs @@ -232,7 +232,7 @@ public bool IsDirty public override string ToString() { - return $"[{Asset.GetType().Name}] {location} => {Id}"; + return $"[{Asset.GetType().Name}] {location}"; } /// diff --git a/sources/assets/Xenko.Core.Assets/Compiler/AssetDependenciesCompiler.cs b/sources/assets/Xenko.Core.Assets/Compiler/AssetDependenciesCompiler.cs index 14bb756759..6ccc626ccb 100644 --- a/sources/assets/Xenko.Core.Assets/Compiler/AssetDependenciesCompiler.cs +++ b/sources/assets/Xenko.Core.Assets/Compiler/AssetDependenciesCompiler.cs @@ -6,6 +6,10 @@ using Xenko.Core.Assets.Analysis; using Xenko.Core.BuildEngine; using Xenko.Core.Annotations; +using System.Threading.Tasks; +using Xenko.Core.Diagnostics; +using Xenko.Core.Extensions; +using System.Linq; namespace Xenko.Core.Assets.Compiler { @@ -85,19 +89,21 @@ public AssetCompilerResult Prepare(AssetCompilerContext context, AssetItem asset if ((dependencyType & BuildDependencyType.Runtime) == BuildDependencyType.Runtime && compilerResult.HasErrors) //allow Runtime dependencies to fail { - //totally skip this asset but do not propagate errors! - return; + assetBuildSteps = new ErrorBuildStep(assetItem, compilerResult.Messages); } + else + { - assetBuildSteps = compilerResult.BuildSteps; - compiledItems.Add(assetNode.AssetItem.Id, assetBuildSteps); + assetBuildSteps = compilerResult.BuildSteps; + compiledItems.Add(assetNode.AssetItem.Id, assetBuildSteps); - // Copy the log to the final result (note: this does not copy or forward the build steps) - compilerResult.CopyTo(finalResult); - if (compilerResult.HasErrors) - { - finalResult.Error($"Failed to prepare asset {assetItem.Location}"); - return; + // Copy the log to the final result (note: this does not copy or forward the build steps) + compilerResult.CopyTo(finalResult); + if (compilerResult.HasErrors) + { + finalResult.Error($"Failed to prepare asset {assetItem.Location}"); + return; + } } // Add the resulting build steps to the final @@ -126,5 +132,23 @@ public AssetCompilerResult Prepare(AssetCompilerContext context, AssetItem asset if (parentBuildStep != null && assetBuildSteps != null && (dependencyType & BuildDependencyType.CompileContent) == BuildDependencyType.CompileContent) //only if content is required Content.Load BuildStep.LinkBuildSteps(assetBuildSteps, parentBuildStep); } + + private class ErrorBuildStep : AssetBuildStep + { + private readonly List messages; + + public ErrorBuildStep(AssetItem assetItem, IEnumerable messages) + : base(assetItem) + { + this.messages = messages.ToList(); + } + + public override Task Execute(IExecuteContext executeContext, BuilderContext builderContext) + { + foreach (var message in messages) + executeContext.Logger.Log(message); + return Task.FromResult(ResultStatus.Failed); + } + } } } From 6c70b6efcf2d1b037ba3a4844b97d16417149baa Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Thu, 15 Nov 2018 18:55:15 +0100 Subject: [PATCH 09/14] Revert "Update to C# 7.2 (#264)" (#268) This reverts commit 2eb9a6f0b34b182026e7eda7255e86521419dba8. --- build/Xenko.Core.GlobalSettings.Local.targets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build/Xenko.Core.GlobalSettings.Local.targets b/build/Xenko.Core.GlobalSettings.Local.targets index e6ddf0c0c0..01e13a75cd 100644 --- a/build/Xenko.Core.GlobalSettings.Local.targets +++ b/build/Xenko.Core.GlobalSettings.Local.targets @@ -9,8 +9,4 @@ $(MSBuildThisFileDirectory)..\Bin\$(XenkoBuildDirectory)\ $([System.IO.Path]::GetFullPath('$(XenkoOutputCommonDir)')) - - - 7.2 - \ No newline at end of file From 84c7810b9cdf2d1345f1bbbc4ad5f2f0aef3c184 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 16 Nov 2018 04:35:11 +0900 Subject: [PATCH 10/14] [Audio] Opus: also apply encoder delay and reset states on loop for sound streamed from disk (fixes #235) --- .../Xenko.Audio/CompressedSoundSource.cs | 53 +++++++++++-------- sources/engine/Xenko.Audio/Native/Celt.cpp | 5 ++ sources/engine/Xenko.Audio/Native/Celt.cs | 14 ++++- sources/engine/Xenko.Audio/SoundInstance.cs | 2 +- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/sources/engine/Xenko.Audio/CompressedSoundSource.cs b/sources/engine/Xenko.Audio/CompressedSoundSource.cs index 514511b11a..c57f58f182 100644 --- a/sources/engine/Xenko.Audio/CompressedSoundSource.cs +++ b/sources/engine/Xenko.Audio/CompressedSoundSource.cs @@ -39,6 +39,7 @@ internal sealed class CompressedSoundSource : DynamicSoundSource private readonly int channels; private readonly int sampleRate; + private readonly int samples; private readonly int maxCompressedSize; private byte[] compressedBuffer; @@ -50,7 +51,7 @@ internal sealed class CompressedSoundSource : DynamicSoundSource private byte[] byteBuffer = null; private int byteBufferCurrentPosition = 0; - public CompressedSoundSource(SoundInstance instance, byte[] byteBuffer, int numberOfPackets, int sampleRate, int channels, int maxCompressedSize) + public CompressedSoundSource(SoundInstance instance, byte[] byteBuffer, int numberOfPackets, int numberOfSamples, int sampleRate, int channels, int maxCompressedSize) : base(instance, NumberOfBuffers, SamplesPerBuffer * MaxChannels * sizeof(short)) { looped = instance.IsLooping; @@ -60,6 +61,7 @@ public CompressedSoundSource(SoundInstance instance, byte[] byteBuffer, int numb this.byteBuffer = byteBuffer; this.sampleRate = sampleRate; this.numberOfPackets = numberOfPackets; + this.samples = numberOfSamples; playRange = new PlayRange(TimeSpan.Zero, TimeSpan.Zero); NewSources.Add(this); @@ -78,7 +80,7 @@ public CompressedSoundSource(SoundInstance instance, byte[] byteBuffer, int numb /// The sample rate of the compressed data /// The number of channels of the compressed data /// The maximum size of a compressed packet - public CompressedSoundSource(SoundInstance instance, IVirtualFileProvider fileProvider, string soundStreamUrl, int numberOfPackets, int sampleRate, int channels, int maxCompressedSize) + public CompressedSoundSource(SoundInstance instance, IVirtualFileProvider fileProvider, string soundStreamUrl, int numberOfPackets, int numberOfSamples, int sampleRate, int channels, int maxCompressedSize) : base(instance, NumberOfBuffers, SamplesPerBuffer * MaxChannels * sizeof(short)) { looped = instance.IsLooping; @@ -88,6 +90,7 @@ public CompressedSoundSource(SoundInstance instance, IVirtualFileProvider filePr this.soundStreamUrl = soundStreamUrl; this.sampleRate = sampleRate; this.numberOfPackets = numberOfPackets; + this.samples = numberOfSamples; playRange = new PlayRange(TimeSpan.Zero, TimeSpan.Zero); NewSources.Add(this); @@ -153,30 +156,36 @@ protected override void PrepareInternal() range = playRange; } - if (range.Start != TimeSpan.Zero || range.Length != TimeSpan.Zero) - { - var frameSize = SamplesPerFrame * channels; - //ok we need to handle this case properly, this means that the user wants to use a different then full audio stream range... - var sampleStart = sampleRate * (double)channels * range.Start.TotalSeconds; - startPktSampleIndex = (int)Math.Floor(sampleStart) % (frameSize); + // Reset decoder state + decoder.ResetDecoder(); + + // Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size) + var samplesToSkip = decoder.GetDecoderSampleDelay(); - var sampleStop = sampleRate * (double)channels * range.End.TotalSeconds; - endPktSampleIndex = frameSize - (int)Math.Floor(sampleStart) % frameSize; + var frameSize = SamplesPerFrame * channels; + //ok we need to handle this case properly, this means that the user wants to use a different then full audio stream range... + var sampleStart = (channels * samplesToSkip) + (int)Math.Floor(sampleRate * (double)channels * range.Start.TotalSeconds); + startPktSampleIndex = sampleStart % (frameSize); - var skipCounter = startingPacketIndex = (int)Math.Floor(sampleStart / frameSize); - endPacketIndex = (int)Math.Floor(sampleStop / frameSize); + var sampleStop = (channels * samplesToSkip) + + (range.Length != TimeSpan.Zero + ? (int)Math.Floor(sampleRate * (double)channels * range.End.TotalSeconds) + : (channels * samples)); + endPktSampleIndex = frameSize - sampleStop % frameSize; - // skip to the starting packet - if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex < endPacketIndex) + var skipCounter = startingPacketIndex = sampleStart / frameSize; + endPacketIndex = sampleStop / frameSize; + + // skip to the starting packet + if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex < endPacketIndex) + { + //valid offsets.. process it + while (skipCounter-- > 0) { - //valid offsets.. process it - while (skipCounter-- > 0) - { - //skip data to reach starting packet - var len = reader.ReadInt16(); - compressedSoundStream.Position = compressedSoundStream.Position + len; - currentPacketIndex++; - } + //skip data to reach starting packet + var len = reader.ReadInt16(); + compressedSoundStream.Position = compressedSoundStream.Position + len; + currentPacketIndex++; } } } diff --git a/sources/engine/Xenko.Audio/Native/Celt.cpp b/sources/engine/Xenko.Audio/Native/Celt.cpp index 8cb5639194..914589847a 100644 --- a/sources/engine/Xenko.Audio/Native/Celt.cpp +++ b/sources/engine/Xenko.Audio/Native/Celt.cpp @@ -46,6 +46,11 @@ extern "C" { delete celt; } + DLL_EXPORT_API void xnCeltResetDecoder(XenkoCelt* celt) + { + opus_custom_decoder_ctl(celt->GetDecoder(), OPUS_RESET_STATE); + } + DLL_EXPORT_API int xnCeltGetDecoderSampleDelay(XenkoCelt* celt, int32_t* delay) { return opus_custom_decoder_ctl(celt->GetDecoder(), OPUS_GET_LOOKAHEAD(delay)); diff --git a/sources/engine/Xenko.Audio/Native/Celt.cs b/sources/engine/Xenko.Audio/Native/Celt.cs index 3b93c88813..4738a220a9 100644 --- a/sources/engine/Xenko.Audio/Native/Celt.cs +++ b/sources/engine/Xenko.Audio/Native/Celt.cs @@ -88,11 +88,19 @@ public unsafe int Decode(byte[] inputBuffer, int inputBufferSize, short* outputS } } + /// + /// Reset decoder state. + /// + public void ResetDecoder() + { + xnCeltResetDecoder(celtPtr); + } + /// /// Gets the delay between encoder and decoder (in number of samples). This should be skipped at the beginning of a decoded stream. /// /// - public unsafe int GetDecoderSampleDelay() + public int GetDecoderSampleDelay() { var delay = 0; if (xnCeltGetDecoderSampleDelay(celtPtr, ref delay) != 0) @@ -154,6 +162,10 @@ public unsafe int Encode(float[] audioSamples, byte[] outputBuffer) [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] private static extern void xnCeltDestroy(IntPtr celt); + [SuppressUnmanagedCodeSecurity] + [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] + private static extern int xnCeltResetDecoder(IntPtr celt); + [SuppressUnmanagedCodeSecurity] [DllImport(NativeInvoke.Library, CallingConvention = CallingConvention.Cdecl)] private static extern int xnCeltGetDecoderSampleDelay(IntPtr celt, ref int delay); diff --git a/sources/engine/Xenko.Audio/SoundInstance.cs b/sources/engine/Xenko.Audio/SoundInstance.cs index fc0fd07360..5241170142 100644 --- a/sources/engine/Xenko.Audio/SoundInstance.cs +++ b/sources/engine/Xenko.Audio/SoundInstance.cs @@ -81,7 +81,7 @@ internal SoundInstance(Sound staticSound, AudioListener listener, bool forceLoad if (streamed) { - soundSource = new CompressedSoundSource(this, staticSound.FileProvider, staticSound.CompressedDataUrl, staticSound.NumberOfPackets, staticSound.SampleRate, staticSound.Channels, staticSound.MaxPacketLength); + soundSource = new CompressedSoundSource(this, staticSound.FileProvider, staticSound.CompressedDataUrl, staticSound.NumberOfPackets, staticSound.Samples, staticSound.SampleRate, staticSound.Channels, staticSound.MaxPacketLength); } else { From d17e74d6619835219b06776258089af02a1a22fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 19 Nov 2018 10:26:17 +0900 Subject: [PATCH 11/14] [Launcher] Display details if there is an exception during self update --- sources/launcher/Xenko.Launcher/Services/SelfUpdater.cs | 4 ++-- .../launcher/Xenko.Launcher/ViewModels/LauncherViewModel.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/launcher/Xenko.Launcher/Services/SelfUpdater.cs b/sources/launcher/Xenko.Launcher/Services/SelfUpdater.cs index ba7ecadf7f..fe5c1d34d0 100644 --- a/sources/launcher/Xenko.Launcher/Services/SelfUpdater.cs +++ b/sources/launcher/Xenko.Launcher/Services/SelfUpdater.cs @@ -43,10 +43,10 @@ internal static Task SelfUpdate(IViewModelServiceProvider services, NugetStore s { await UpdateLauncherFiles(dispatcher, store, CancellationToken.None); } - catch (Exception) + catch (Exception e) { dispatcher.Invoke(() => selfUpdateWindow?.ForceClose()); - const string message = "An error occurred while updating the launcher. If the problem persists, please reinstall this application."; + string message = $"An error occurred while updating the launcher. If the problem persists, please reinstall this application.{Environment.NewLine}{Environment.NewLine}Details:{Environment.NewLine}{e}"; await services.Get().MessageBox(message, MessageBoxButton.OK, MessageBoxImage.Error); // We do not want our users to use the old launcher when a new one is available. Environment.Exit(1); diff --git a/sources/launcher/Xenko.Launcher/ViewModels/LauncherViewModel.cs b/sources/launcher/Xenko.Launcher/ViewModels/LauncherViewModel.cs index 018bc60557..66d0e5e807 100644 --- a/sources/launcher/Xenko.Launcher/ViewModels/LauncherViewModel.cs +++ b/sources/launcher/Xenko.Launcher/ViewModels/LauncherViewModel.cs @@ -135,7 +135,7 @@ private async Task FetchOnlineData() await Task.Run(async () => { await RetrieveLocalXenkoVersions(); - //await RunLockTask(() => SelfUpdater.SelfUpdate(ServiceProvider, store)); + await RunLockTask(() => SelfUpdater.SelfUpdate(ServiceProvider, store)); await RetrieveServerXenkoVersions(); await VsixPackage.UpdateFromStore(); await CheckForFirstInstall(); From 153505726a82155766d91f3b3695522d907d7b8b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 19 Nov 2018 10:30:32 +0900 Subject: [PATCH 12/14] [Launcher] Bumped version --- sources/launcher/Setup/setup.aip | 6 +++--- sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj | 2 +- sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sources/launcher/Setup/setup.aip b/sources/launcher/Setup/setup.aip index 015f491eaa..6251b3c0fe 100644 --- a/sources/launcher/Setup/setup.aip +++ b/sources/launcher/Setup/setup.aip @@ -28,10 +28,10 @@ - + - + @@ -59,7 +59,7 @@ - + diff --git a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj index e60eaef9ba..c9fefa6cc6 100644 --- a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj +++ b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj @@ -28,7 +28,7 @@ false - 2.0.0 + 2.0.1 AnyCPU diff --git a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec index b7fda357a8..df6d98cbca 100644 --- a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec +++ b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec @@ -2,7 +2,7 @@ Xenko.Launcher - 2.0.0 + 2.0.1 Xenko Xenko http://xenko.com/license.txt From 676757b34c42bf2cb437ca8fad7a7f71a11a3ea7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 20 Nov 2018 00:27:43 +0900 Subject: [PATCH 13/14] [Launcher] Bumped version (again) --- sources/launcher/Setup/setup.aip | 2 +- sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj | 2 +- sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/launcher/Setup/setup.aip b/sources/launcher/Setup/setup.aip index 6251b3c0fe..523914d38f 100644 --- a/sources/launcher/Setup/setup.aip +++ b/sources/launcher/Setup/setup.aip @@ -31,7 +31,7 @@ - + diff --git a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj index c9fefa6cc6..bb6ddc0d04 100644 --- a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj +++ b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.csproj @@ -28,7 +28,7 @@ false - 2.0.1 + 2.0.2 AnyCPU diff --git a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec index df6d98cbca..4800d98087 100644 --- a/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec +++ b/sources/launcher/Xenko.LauncherApp/Xenko.LauncherApp.nuspec @@ -2,7 +2,7 @@ Xenko.Launcher - 2.0.1 + 2.0.2 Xenko Xenko http://xenko.com/license.txt From a7db66dbd94cdc422a956b26543adcaaafd54e92 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Nov 2018 12:53:01 +0900 Subject: [PATCH 14/14] Update BACKERS.md --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index 7dd7c6bbc0..efea0097b4 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -42,6 +42,7 @@ Thank you everybody for your generous contributions! * SleepyMode * Marko Viitanen * David R Miller +* Sven-Bertil Blom ## Mini Backers