You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
5.1 KiB
134 lines
5.1 KiB
using UnityEngine.Experimental.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
class TextureCache2D : TextureCache
|
|
{
|
|
private RenderTexture m_Cache;
|
|
|
|
public TextureCache2D(string cacheName = "")
|
|
: base(cacheName)
|
|
{
|
|
}
|
|
|
|
bool TextureHasMipmaps(Texture texture)
|
|
{
|
|
// Either the texture
|
|
if (texture is Texture2D)
|
|
return ((Texture2D)texture).mipmapCount > 1;
|
|
else
|
|
return ((RenderTexture)texture).useMipMap;
|
|
}
|
|
|
|
override public bool IsCreated()
|
|
{
|
|
return m_Cache.IsCreated();
|
|
}
|
|
|
|
protected override bool TransferToSlice(CommandBuffer cmd, int sliceIndex, Texture[] textureArray)
|
|
{
|
|
// Make sure the array is not null or empty and that the first texture is a render-texture or a texture2D
|
|
if (textureArray == null || textureArray.Length == 0 && (!(textureArray[0] is RenderTexture) && !(textureArray[0] is Texture2D)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// First check here is to check if all the sub-texture have the same size
|
|
for (int texIDx = 1; texIDx < textureArray.Length; ++texIDx)
|
|
{
|
|
// We cannot update if the textures if they don't have the same size or not the right type
|
|
if (textureArray[texIDx].width != textureArray[0].width || textureArray[texIDx].height != textureArray[0].height || (!(textureArray[0] is RenderTexture) && !(textureArray[0] is Texture2D)))
|
|
{
|
|
Debug.LogWarning("All the sub-textures should have the same dimensions to be handled by the texture cache.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Do we have a mismatch ?
|
|
var mismatch = (m_Cache.width != textureArray[0].width) || (m_Cache.height != textureArray[0].height);
|
|
|
|
if (textureArray[0] is Texture2D)
|
|
{
|
|
mismatch |= (m_Cache.graphicsFormat != (textureArray[0] as Texture2D).graphicsFormat);
|
|
}
|
|
|
|
for (int texIDx = 0; texIDx < textureArray.Length; ++texIDx)
|
|
{
|
|
if (!TextureHasMipmaps(textureArray[texIDx]))
|
|
Debug.LogWarning("The texture '" + textureArray[texIDx] + "' should have mipmaps to be handled by the cookie texture array");
|
|
|
|
if (mismatch)
|
|
{
|
|
cmd.Blit(textureArray[texIDx], m_Cache, 0, m_SliceSize * sliceIndex + texIDx);
|
|
}
|
|
else
|
|
{
|
|
cmd.CopyTexture(textureArray[texIDx], 0, m_Cache, m_SliceSize * sliceIndex + texIDx);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override Texture GetTexCache()
|
|
{
|
|
return m_Cache;
|
|
}
|
|
|
|
public bool AllocTextureArray(int numTextures, int width, int height, GraphicsFormat format, bool isMipMapped)
|
|
{
|
|
var res = AllocTextureArray(numTextures);
|
|
m_NumMipLevels = GetNumMips(width, height);
|
|
|
|
var desc = new RenderTextureDescriptor(width, height, format, 0)
|
|
{
|
|
// autoGenerateMips is true by default
|
|
dimension = TextureDimension.Tex2DArray,
|
|
volumeDepth = numTextures,
|
|
useMipMap = isMipMapped,
|
|
msaaSamples = 1,
|
|
};
|
|
|
|
m_Cache = new RenderTexture(desc)
|
|
{
|
|
hideFlags = HideFlags.HideAndDontSave,
|
|
wrapMode = TextureWrapMode.Clamp,
|
|
name = CoreUtils.GetTextureAutoName(width, height, format, TextureDimension.Tex2DArray, depth: numTextures, name: m_CacheName)
|
|
};
|
|
|
|
// We need to clear the content in case it is read on first frame, since on console we have no guarantee that
|
|
// the content won't be NaN
|
|
ClearCache();
|
|
m_Cache.Create();
|
|
|
|
return res;
|
|
}
|
|
|
|
internal void ClearCache()
|
|
{
|
|
var desc = m_Cache.descriptor;
|
|
bool isMipped = desc.useMipMap;
|
|
int mipCount = isMipped ? GetNumMips(desc.width, desc.height) : 1;
|
|
for (int mipIdx = 0; mipIdx < mipCount; ++mipIdx)
|
|
{
|
|
Graphics.SetRenderTarget(m_Cache, mipIdx, CubemapFace.Unknown, -1);
|
|
GL.Clear(false, true, Color.clear);
|
|
}
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
CoreUtils.Destroy(m_Cache);
|
|
}
|
|
|
|
internal static long GetApproxCacheSizeInByte(int nbElement, int resolution, int sliceSize)
|
|
{
|
|
return (long)((long)nbElement * resolution * resolution * k_FP16SizeInByte * k_NbChannel * k_MipmapFactorApprox * sliceSize);
|
|
}
|
|
|
|
internal static int GetMaxCacheSizeForWeightInByte(int weight, int resolution, int sliceSize)
|
|
{
|
|
int theoricalResult = Mathf.FloorToInt(weight / ((long)resolution * resolution * k_FP16SizeInByte * k_NbChannel * k_MipmapFactorApprox * sliceSize));
|
|
return Mathf.Clamp(theoricalResult, 1, k_MaxSupported);
|
|
}
|
|
}
|
|
}
|