Skip to content
Permalink
Browse files

[Streaming] Load a few initial mipmaps for streamed texture (otherwis…

…e they start as completely uninitialized: bad for rendering, and causes crash on Vulkan)
  • Loading branch information
xen2 committed Sep 5, 2019
1 parent b5b6450 commit 1ca201f6f689f954f38b2ce17dfd90534e54d3fb
@@ -85,9 +85,23 @@ internal static void Serialize(ArchiveMode mode, SerializationStream stream, Tex
// Request texture loading (should be fully loaded)
texturesStreamingProvider.FullyLoadTexture(texture, ref imageDescription, ref storageHeader);
}

// Load initial texture (with limited number of mipmaps)
using (var textureData = Image.Load(stream.NativeStream))
{
if (texture.GraphicsDevice != null)
texture.OnDestroyed(); //Allows fast reloading todo review maybe?

texture.InitializeFrom(textureData.Description, new TextureViewDescription(), textureData.ToDataBox());
}
}
else
{
// Load initial texture and discard it (we are going to load the full chunk texture right after)
using (var textureData = Image.Load(stream.NativeStream))
{
}

// Deserialize whole texture without streaming feature
var contentSerializerContext = stream.Context.Get(ContentSerializerContext.ContentSerializerContextProperty);
DeserializeTexture(contentSerializerContext.ContentManager, texture, ref imageDescription, ref storageHeader);
@@ -1,6 +1,7 @@
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
#pragma warning disable SA1405 // Debug.Assert must provide message text
using System;
using System.Diagnostics;
using Xenko.Core.Annotations;
using Xenko.Core.Serialization;
@@ -13,7 +14,13 @@ namespace Xenko.Graphics.Data
/// </summary>
public sealed class TextureSerializationData
{
internal const int Version = 4;
internal const int Version = 5;

/// <summary>
/// Texture with a mip map count equal or less than this won't use streaming.
/// Also, those levels will be load during initial load, only lower levels will be streamed.
/// </summary>
internal const int InitialNonStreamedMipCount = 6;

/// <summary>
/// The texture image.
@@ -59,15 +66,44 @@ public TextureSerializationData([NotNull] Image image, bool enableStreaming, Con
/// <param name="stream">The destination stream.</param>
public void Write(SerializationStream stream)
{
stream.Write(EnableStreaming);
if (EnableStreaming)
var enableStreaming = EnableStreaming && Image.Description.MipLevels > InitialNonStreamedMipCount;

stream.Write(enableStreaming);
if (enableStreaming)
{
// Write image header
ImageHelper.ImageDescriptionSerializer.Serialize(ref Image.Description, ArchiveMode.Serialize, stream);

// Write storage header
Debug.Assert(!string.IsNullOrEmpty(StorageHeader.DataUrl));
StorageHeader.Write(stream);

// Note: in this scenario, we serialize only SkipStreamingMipCount (we know number is strictly higher than this due to previous check)
var newDesc = Image.Description;
newDesc.MipLevels = InitialNonStreamedMipCount;
var pixelBuffers = new PixelBuffer[Image.Description.ArraySize * InitialNonStreamedMipCount];

// Count number of mip maps that won't be part of initial load (they will be available through streaming)
int skippedMipCount = Image.Description.MipLevels - InitialNonStreamedMipCount;
for (uint item = 0; item < Image.Description.ArraySize; ++item)
{
for (uint level = 0; level < InitialNonStreamedMipCount; ++level)
{
pixelBuffers[item * InitialNonStreamedMipCount + level] = Image.PixelBuffers[item * Image.Description.MipLevels + level + skippedMipCount];
}
}

// Adjust new Width/Height
newDesc.Width = pixelBuffers[0].Width;
newDesc.Height = pixelBuffers[0].Height;

var initialImage = new Image
{
Description = newDesc,
PixelBuffers = pixelBuffers,
};
// TODO: We end up duplicating some of the texture data; we could find a way to avoid that by saving only the chunks of higher level mips?
initialImage.Save(stream.NativeStream, ImageFileType.Xenko);
}
else
{

0 comments on commit 1ca201f

Please sign in to comment.
You can’t perform that action at this time.