using System;
using System.Diagnostics;
using UnityEngine.Scripting.APIUpdating;
namespace UnityEngine.Rendering.RenderGraphModule
{
///
/// Graphics Buffer resource handle.
///
[DebuggerDisplay("Buffer ({handle.index})")]
[MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")]
public struct BufferHandle
{
// Minor Warning: This calls the zeroing constructor this means that the embedded ResourceHandle struct will also be zero-ed
// which then means ResourceHandle.type will be set to zero == Texture. As this is an "invalid" bufferhandle I guess setting it
// to type texture just makes it even more properly invalid and not a big issue. But something to keep in mind for tooling/logging.
private static BufferHandle s_NullHandle = new BufferHandle();
///
/// Returns a null graphics buffer handle
///
/// A null graphics buffer handle.
public static BufferHandle nullHandle { get { return s_NullHandle; } }
internal ResourceHandle handle;
internal BufferHandle(in ResourceHandle h) { handle = h; }
internal BufferHandle(int handle, bool shared = false) { this.handle = new ResourceHandle(handle, RenderGraphResourceType.Buffer, shared); }
///
/// Cast to GraphicsBuffer
///
/// Input BufferHandle
/// Resource as a Graphics Buffer.
public static implicit operator GraphicsBuffer(BufferHandle buffer) => buffer.IsValid() ? RenderGraphResourceRegistry.current.GetBuffer(buffer) : null;
///
/// Return true if the handle is valid.
///
/// True if the handle is valid.
public bool IsValid() => handle.IsValid();
}
///
/// Descriptor used to create graphics buffer resources
///
public struct BufferDesc
{
///Number of elements in the buffer..
public int count;
///Size of one element in the buffer. Has to match size of buffer type in the shader.
public int stride;
/// Graphics Buffer name.
public string name;
/// The intended usage of a GraphicsBuffer.
public GraphicsBuffer.Target target;
/// The intended update mode of a GraphicsBuffer.
public GraphicsBuffer.UsageFlags usageFlags;
///
/// BufferDesc constructor.
///
/// Number of elements in the buffer.
/// Size of one element in the buffer.
public BufferDesc(int count, int stride)
: this()
{
this.count = count;
this.stride = stride;
this.target = GraphicsBuffer.Target.Structured;
this.usageFlags = GraphicsBuffer.UsageFlags.None;
}
///
/// BufferDesc constructor.
///
/// Number of elements in the buffer.
/// Size of one element in the buffer.
/// Type of the buffer.
public BufferDesc(int count, int stride, GraphicsBuffer.Target target)
: this()
{
this.count = count;
this.stride = stride;
this.target = target;
this.usageFlags = GraphicsBuffer.UsageFlags.None;
}
///
/// Hash function
///
/// The texture descriptor hash.
public override int GetHashCode()
{
var hashCode = HashFNV1A32.Create();
hashCode.Append(count);
hashCode.Append(stride);
hashCode.Append((int) target);
hashCode.Append((int) usageFlags);
return hashCode.value;
}
}
[DebuggerDisplay("BufferResource ({desc.name})")]
class BufferResource : RenderGraphResource
{
public override string GetName()
{
if (imported)
return "ImportedGraphicsBuffer"; // No getter for graphics buffer name.
else
return desc.name;
}
public override int GetDescHashCode() { return desc.GetHashCode(); }
public override void CreateGraphicsResource()
{
var name = GetName();
graphicsResource = new GraphicsBuffer(desc.target, desc.usageFlags, desc.count, desc.stride);
#if DEVELOPMENT_BUILD || UNITY_EDITOR
graphicsResource.name = name == "" ? $"RenderGraphBuffer_{desc.count}_{desc.stride}_{desc.target}" : name;
#endif
}
public override void UpdateGraphicsResource()
{
if (graphicsResource != null)
graphicsResource.name = GetName();
}
public override void ReleaseGraphicsResource()
{
if (graphicsResource != null)
graphicsResource.Release();
base.ReleaseGraphicsResource();
}
public override void LogCreation(RenderGraphLogger logger)
{
logger.LogLine($"Created GraphicsBuffer: {desc.name}");
}
public override void LogRelease(RenderGraphLogger logger)
{
logger.LogLine($"Released GraphicsBuffer: {desc.name}");
}
}
class BufferPool : RenderGraphResourcePool
{
protected override void ReleaseInternalResource(GraphicsBuffer res)
{
res.Release();
}
protected override string GetResourceName(in GraphicsBuffer res)
{
return "GraphicsBufferNameNotAvailable"; // GraphicsBuffer.name is a setter only :(
}
protected override long GetResourceSize(in GraphicsBuffer res)
{
return res.count * res.stride;
}
override protected string GetResourceTypeName()
{
return "GraphicsBuffer";
}
override protected int GetSortIndex(GraphicsBuffer res)
{
return res.GetHashCode();
}
}
}