/// <summary> /// Evaluate the range of tracking handles which a view texture overlaps with. /// </summary> /// <param name="texture">The texture to get handles for</param> /// <param name="callback"> /// A function to be called with the base index of the range of handles for the given texture, and the number of handles it covers. /// This can be called for multiple disjoint ranges, if required. /// </param> private void EvaluateRelevantHandles(Texture texture, HandlesCallbackDelegate callback) { if (texture == Storage || !(_hasMipViews || _hasLayerViews)) { callback(0, _handles.Length); return; } EvaluateRelevantHandles(texture.FirstLayer, texture.FirstLevel, texture.Info.GetSlices(), texture.Info.Levels, callback); }
/// <summary> /// Evaluate the range of tracking handles which a view texture overlaps with, /// using the view's position and slice/level counts. /// </summary> /// <param name="firstLayer">The first layer of the texture</param> /// <param name="firstLevel">The first level of the texture</param> /// <param name="slices">The slice count of the texture</param> /// <param name="levels">The level count of the texture</param> /// <param name="callback"> /// A function to be called with the base index of the range of handles for the given texture, and the number of handles it covers. /// This can be called for multiple disjoint ranges, if required. /// </param> private void EvaluateRelevantHandles(int firstLayer, int firstLevel, int slices, int levels, HandlesCallbackDelegate callback) { int targetLayerHandles = _hasLayerViews ? slices : 1; int targetLevelHandles = _hasMipViews ? levels : 1; if (_is3D) { // Future mip levels come after all layers of the last mip level. Each mipmap has less layers (depth) than the last. if (!_hasLayerViews) { // When there are no layer views, the mips are at a consistent offset. callback(firstLevel, targetLevelHandles); } else { (int levelIndex, int layerCount) = Get3DLevelRange(firstLevel); if (levels > 1 && slices < _layers) { // The given texture only covers some of the depth of multiple mips. (a "depth slice") // Callback with each mip's range separately. // Can assume that the group is fully subdivided (both slices and levels > 1 for storage) while (levels-- > 1) { callback(firstLayer + levelIndex, slices); levelIndex += layerCount; layerCount = Math.Max(layerCount >> 1, 1); slices = Math.Max(layerCount >> 1, 1); } } else { int totalSize = Math.Min(layerCount, slices); while (levels-- > 1) { layerCount = Math.Max(layerCount >> 1, 1); totalSize += layerCount; } callback(firstLayer + levelIndex, totalSize); } } } else { // Future layers come after all mipmaps of the last. int levelHandles = _hasMipViews ? _levels : 1; if (slices > 1 && levels < _levels) { // The given texture only covers some of the mipmaps of multiple slices. (a "mip slice") // Callback with each layer's range separately. // Can assume that the group is fully subdivided (both slices and levels > 1 for storage) for (int i = 0; i < slices; i++) { callback(firstLevel + (firstLayer + i) * levelHandles, targetLevelHandles, true); } } else { callback(firstLevel + firstLayer * levelHandles, targetLevelHandles + (targetLayerHandles - 1) * levelHandles); } } }