Gorgon
Show / Hide Table of Contents

Class GorgonBufferCommon

A base class that provides functionality that is common across any buffer type.

Inheritance
object
GorgonGraphicsResource
GorgonBufferCommon
GorgonBuffer
GorgonConstantBuffer
GorgonIndexBuffer
GorgonVertexBuffer
Implements
IGorgonNamedObject
IGorgonGraphicsObject
IGorgonNativeResource
IDisposable
Inherited Members
GorgonGraphicsResource.IsDisposed
GorgonGraphicsResource.Usage
GorgonGraphicsResource.Graphics
GorgonGraphicsResource.EvictionPriority
GorgonGraphicsResource.SizeInBytes
GorgonGraphicsResource.Name
GorgonGraphicsResource.SetApplicationData(Guid, object)
GorgonGraphicsResource.GetApplicationData(Guid)
object.ToString()
object.Equals(object)
object.Equals(object, object)
object.ReferenceEquals(object, object)
object.GetHashCode()
object.GetType()
object.MemberwiseClone()
Namespace: Gorgon.Graphics.Core
Assembly: Gorgon.Graphics.Core.dll
Syntax
public abstract class GorgonBufferCommon : GorgonGraphicsResource, IGorgonNamedObject, IGorgonGraphicsObject, IGorgonNativeResource, IDisposable

Constructors

| Edit this page View Source

GorgonBufferCommon(GorgonGraphics)

Initializes a new instance of the GorgonBufferCommon class.

Declaration
protected GorgonBufferCommon(GorgonGraphics graphics)
Parameters
Type Name Description
GorgonGraphics graphics

The GorgonGraphics object used to create and manipulate the buffer.

Exceptions
Type Condition
ArgumentNullException

Thrown when the graphics parameter is null.

Properties

| Edit this page View Source

IsCpuReadable

Property to return whether or not the buffer is directly readable by the CPU via one of the GetData<T>(int, int?) methods.

Declaration
public abstract bool IsCpuReadable { get; }
Property Value
Type Description
bool
Remarks

Buffers must meet the following criteria in order to qualify for direct CPU read:

  • Must have a Usage of Default (or Staging).
  • Must be bindable to a shader resource view (Default only).

If this value is false, then the buffer can still be read, but it will take a slower path by copying to a staging buffer.

information

Any buffer created with a Usage of Staging will always be directly readable by the CPU. Therefore, this value will always return true in that case.

See Also
GetData<T>(Span<T>, int, int?)
GetData<T>(out T, int)
GetData<T>(int, int?)
| Edit this page View Source

Log

Property to return the log used to log debug messages.

Declaration
protected IGorgonLog Log { get; }
Property Value
Type Description
IGorgonLog
| Edit this page View Source

ResourceType

Property to return the type of data in the resource.

Declaration
public override GraphicsResourceType ResourceType { get; }
Property Value
Type Description
GraphicsResourceType
Overrides
GorgonGraphicsResource.ResourceType

Methods

| Edit this page View Source

CopyTo(GorgonBufferCommon, int, int, int, CopyMode)

Function to copy the contents of this buffer into another buffer.

Declaration
public void CopyTo(GorgonBufferCommon destinationBuffer, int sourceOffset = 0, int byteCount = 0, int destOffset = 0, CopyMode copyMode = CopyMode.None)
Parameters
Type Name Description
GorgonBufferCommon destinationBuffer

The source buffer that will receive the data.

int sourceOffset

[Optional] Starting byte index to start copying from.

int byteCount

[Optional] The number of bytes to copy.

int destOffset

[Optional] The offset, in bytes, within the this buffer to start writing into.

CopyMode copyMode

[Optional] Defines how data should be copied into the texture.

Remarks

Use this method to copy this GorgonBufferCommon to another GorgonBufferCommon.

The sourceOffset, byteCount, and destOffset parameters allow a portion of the buffer to be written to an offset within the destination. If the parameters exceed the size of the destinationBuffer, or this buffer, then the values will be clipped to ensure that no overrun is possible.

The destination buffer must not have a Usage of Immutable.

The copyMode parameter defines how the copy will be performed. If the buffer has a Usage of Dynamic or Default and the copyMode is set to Discard then the contents of the buffer are discarded before updating, if it is set to NoOverwrite, then the data will be copied to the destination if we know the GPU is not using the portion being updated. If the copyMode is set to None, then Discard is used. For buffers created with a Usage of Staging, the CopyMode will be ignored and act as though None were passed.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

| Edit this page View Source

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Declaration
public override void Dispose()
Overrides
GorgonGraphicsResource.Dispose()
Remarks

Objects that override this method should be sure to call this base method or else a memory leak may occur.

| Edit this page View Source

GetData<T>(int, int?)

Function to return the contents of this buffer into an array.

Declaration
public T[] GetData<T>(int sourceOffset = 0, int? size = null) where T : unmanaged
Parameters
Type Name Description
int sourceOffset

The offset, in bytes, within this buffer to start reading from.

int? size

The number of bytes to read from this buffer.

Returns
Type Description
T[]

An array with a copy of the data in this buffer.

Type Parameters
Name Description
T

The type of data in the array, must be an unmanaged value type.

Remarks

This will retrieve the data from this buffer and copy it into an array which is returned back to the caller as the type specified by T. If the IsCpuReadable flag is set to true, then the data in the buffer can be read directly from the CPU. If not, then the data will be copied to a staging buffer and then transferred (which, obviously, is not as performant).

Some buffers will allow the user to directly set the IsCpuReadable flag via their corresponding info object upon creation. The purpose of this is to tell the GPU where to best locate the memory for the buffer. If the user decides to not allow direct CPU read, then the buffer will be located in memory that is much faster to access for the GPU, while allowing direct CPU read will put the buffer into an area where the CPU and GPU can access the data, which is in typically less performant memory ranges. Buffers must meet the following criteria in order to qualify for direct CPU read:

  • Must have a Usage of Default (or Staging).
  • Must be bindable to a shader resource view (Default only).

If the user supplies a one of the sourceOffset, or size parameters, then a portion of the data will be copied from the buffer at the index provided by sourceOffset.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

Examples

The following is an example showing how to upload vertices into a vertex buffer using different techniques:

// Our vertex, with a position and color component.
[StructLayout(LayoutKind = LayoutKind.Sequential)] 
struct MyVertex
{
	public Vector4 Position;
	public Vector4 Color;
}

GorgonGraphics graphics;
MyVertex[] _vertices = new MyVertex[100];
GorgonVertexBuffer _vertexBuffer;

void InitializeVertexBuffer()
{
	_vertices = ... // Fill your vertex array here.

	// Create the vertex buffer large enough so that it'll hold 100 vertices.
	_vertexBuffer = new GorgonVertexBuffer(graphics, GorgonVertexBufferInfo.CreateFromType<MyVertex>(_vertices.Length, Usage.Default));

	// Copy our data to the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan());

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, and 25 vertices.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25));

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, 25 vertices, and storing at index 2 in the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

    // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
    _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

    // Copy our data from a GorgonNativeBuffer.
    using (GorgonNativeBuffer<MyVertex> vertices = new GorgonNativeBuffer<MyVertex>(100))
    {
       // Copy vertices into the native buffer here....

       // Copy everything.
       _vertexBuffer.SetData(vertices);

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

       // Get the data back out from the buffer, using index 5 and up to 10 vertices, storing at index 2 of the native buffer.
       _vertexBuffer.GetData<MyVertex>(vertices.ToSpan(2), 5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>()); 
    }

    // Get the data back out from the buffer.
    MyVertex[] readBack = _vertexBuffer.GetData<MyVertex>();

    // Get the data back out from the buffer, starting at index 5 and a count of 10 vertices.
    readBack = _vertexBuffer.GetData<MyVertex>(5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>());
}
Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the sourceOffset, or the size parameter is less than zero.

ArgumentException

Thrown when the sourceOffset + size exceeds the size of this buffer.

See Also
IsCpuReadable
| Edit this page View Source

GetData<T>(Span<T>, int, int?)

Function to return the contents of this buffer into the specified span.

Declaration
public void GetData<T>(Span<T> destination, int sourceOffset = 0, int? size = null) where T : unmanaged
Parameters
Type Name Description
Span<T> destination

The span that will receive the data.

int sourceOffset

The offset, in bytes, within this buffer to start reading from.

int? size

The number of bytes to read from this buffer.

Type Parameters
Name Description
T

The type of data in the span, must be an unmanaged value type.

Remarks

This will retrieve the data from this buffer and copy it into the destination span. If the IsCpuReadable flag is set to true, then the data in the buffer can be read directly from the CPU. If not, then the data will be copied to a staging buffer and then transferred (which, obviously, is not as performant).

Some buffers will allow the user to directly set the IsCpuReadable flag via their corresponding info object upon creation. The purpose of this is to tell the GPU where to best locate the memory for the buffer. If the user decides to not allow direct CPU read, then the buffer will be located in memory that is much faster to access for the GPU, while allowing direct CPU read will put the buffer into an area where the CPU and GPU can access the data, which is in typically less performant memory ranges. Buffers must meet the following criteria in order to qualify for direct CPU read:

  • Must have a Usage of Default (or Staging).
  • Must be bindable to a shader resource view (Default only).

If the user supplies a one of the sourceOffset, or size parameters, then a portion of the data will be copied from the buffer at the index provided by sourceOffset, and written into the beginning of the span.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

Examples

The following is an example showing how to upload vertices into a vertex buffer using different techniques:

// Our vertex, with a position and color component.
[StructLayout(LayoutKind = LayoutKind.Sequential)] 
struct MyVertex
{
	public Vector4 Position;
	public Vector4 Color;
}

GorgonGraphics graphics;
MyVertex[] _vertices = new MyVertex[100];
GorgonVertexBuffer _vertexBuffer;

void InitializeVertexBuffer()
{
	_vertices = ... // Fill your vertex array here.

	// Create the vertex buffer large enough so that it'll hold 100 vertices.
	_vertexBuffer = new GorgonVertexBuffer(graphics, GorgonVertexBufferInfo.CreateFromType<MyVertex>(_vertices.Length, Usage.Default));

	// Copy our data to the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan());

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, and 25 vertices.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25));

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, 25 vertices, and storing at index 2 in the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

    // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
    _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

    // Copy our data from a GorgonNativeBuffer.
    using (GorgonNativeBuffer<MyVertex> vertices = new GorgonNativeBuffer<MyVertex>(100))
    {
       // Copy vertices into the native buffer here....

       // Copy everything.
       _vertexBuffer.SetData(vertices);

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

       // Get the data back out from the buffer, using index 5 and up to 10 vertices, storing at index 2 of the native buffer.
       _vertexBuffer.GetData<MyVertex>(vertices.ToSpan(2), 5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>()); 
    }

    // Get the data back out from the buffer.
    MyVertex[] readBack = _vertexBuffer.GetData<MyVertex>();

    // Get the data back out from the buffer, starting at index 5 and a count of 10 vertices.
    readBack = _vertexBuffer.GetData<MyVertex>(5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>());
}
Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the sourceOffset, or the size parameter is less than zero.

ArgumentException

Thrown when the sourceOffset + size exceeds the size of this buffer.

See Also
IsCpuReadable
| Edit this page View Source

GetData<T>(out T, int)

Function to read a single value from the buffer.

Declaration
public void GetData<T>(out T value, int sourceOffset = 0) where T : unmanaged
Parameters
Type Name Description
T value

The value to write.

int sourceOffset

[Optional] The offset, in bytes, from the beginning in the buffer to start reading from.

Type Parameters
Name Description
T

The type of value, must be an unmanaged value type.

Remarks

This will upload the specified value to this buffer. The method will determine how to best upload the data depending on the Usage of the buffer. For example, if the buffer has a Usage of Default, then internally, this method will update to the GPU directly. Otherwise, if it is Dynamic, or Staging, it will use a locking pattern which uses the CPU to write data to the buffer. The latter pattern is good if the buffer has to change one or more times per frame, otherwise, the former is better where the buffer is updated less than once per frame (i.e. Dynamic is good for multiple times per frame, Default is good for once per frame or less).

If the user supplies a sourceOffset the data will be copied to the buffer at the offset provided by sourceOffset.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

Examples

The following is an example showing how to upload vertices into a vertex buffer using different techniques:

// Our vertex, with a position and color component.
[StructLayout(LayoutKind = LayoutKind.Sequential)] 
struct MyVertex
{
	public Vector4 Position;
	public Vector4 Color;
}

GorgonGraphics graphics;
MyVertex[] _vertices = new MyVertex[100];
GorgonVertexBuffer _vertexBuffer;

void InitializeVertexBuffer()
{
	_vertices = ... // Fill your vertex array here.

	// Create the vertex buffer large enough so that it'll hold 100 vertices.
	_vertexBuffer = new GorgonVertexBuffer(graphics, GorgonVertexBufferInfo.CreateFromType<MyVertex>(_vertices.Length, Usage.Default));

	// Copy our data to the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices);

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, and 25 vertices.
    _vertexBuffer.SetData<MyVertex>(_vertices, 5, 25);

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, 25 vertices, and storing at index 2 in the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices, 5, 25, 2 * Unsafe.SizeOf<MyVertex>());

    // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
    _vertexBuffer.SetData(vertices, 5, 25, 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

    // Copy our data from a GorgonNativeBuffer.
    using (GorgonNativeBuffer<MyVertex> vertices = new GorgonNativeBuffer<MyVertex>(100))
    {
       // Copy vertices into the native buffer here....

       // Copy everything.
       _vertexBuffer.SetData(vertices);

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer.
       _vertexBuffer.SetData(vertices, 5, 25, 2 * Unsafe.SizeOf<MyVertex>());

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
       _vertexBuffer.SetData(vertices, 5, 25, 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

       // Get the data back out from the buffer, using index 5 and up to 10 vertices, storing at index 2 of the native buffer.
       _vertexBuffer.GetData<MyVertex>(vertices, 5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>(), 2); 
    }

    // Get the data back out from the buffer.
    MyVertex[] readBack = _vertexBuffer.GetData<MyVertex>();

    // Get the data back out from the buffer, starting at index 5 and a count of 10 vertices.
    readBack = _vertexBuffer.GetData<MyVertex>(5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>());

    // Get the data back out from the buffer, using index 5 and up to 10 vertices, storing at index 2.
    _vertexBuffer.GetData<MyVertex>(readBack, 5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>(), 2);
}
Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the sourceOffset parameter is less than zero.

ArgumentException

Thrown when the sourceOffset + size of T (in bytes) exceeds the size of the destination buffer.

| Edit this page View Source

GetStagingInternal()

Function to retrieve a copy of this buffer as a staging resource.

Declaration
protected abstract GorgonBufferCommon GetStagingInternal()
Returns
Type Description
GorgonBufferCommon

The staging buffer to retrieve.

| Edit this page View Source

GetTotalElementCount(GorgonFormatInfo)

Function to retrieve the total number of elements that can be placed in the buffer.

Declaration
protected int GetTotalElementCount(GorgonFormatInfo info)
Parameters
Type Name Description
GorgonFormatInfo info

Information about the element format.

Returns
Type Description
int

The number of elements in the buffer.

| Edit this page View Source

SetData<T>(ReadOnlySpan<T>, int, CopyMode)

Function to write data into the buffer from a read only span.

Declaration
public void SetData<T>(ReadOnlySpan<T> data, int destOffset = 0, CopyMode copyMode = CopyMode.None) where T : unmanaged
Parameters
Type Name Description
ReadOnlySpan<T> data

The read only span containing the data to upload into the buffer.

int destOffset

[Optional] The offset, in bytes, within this buffer to start copying into.

CopyMode copyMode

[Optional] Flags to indicate how to copy the data.

Type Parameters
Name Description
T

The type of element in the source span. Must be an unmanaged value type.

Remarks

This will upload data from an read only span to this buffer. The method will determine how to best upload the data depending on the Usage of the buffer. For example, if the buffer has a Usage of Default, then internally, this method will update to the GPU directly. Otherwise, if it is Dynamic, or Staging, it will use a locking pattern which uses the CPU to write data to the buffer. The latter pattern is good if the buffer has to change one or more times per frame, otherwise, the former is better where the buffer is updated less than once per frame (i.e. Dynamic is good for multiple times per frame, Default is good for once per frame or less).

If the user supplies a destOffset, then a portion of the data will be copied to the buffer at the offset provided by destOffset.

The copyMode parameter defines how the copy will be performed. If the buffer has a Usage of Dynamic or Default and the copyMode is set to Discard then the contents of the buffer are discarded before updating, if it is set to NoOverwrite, then the data will be copied to the destination if we know the GPU is not using the portion being updated. If the copyMode is set to None, then Discard is used. For buffers created with a Usage of Staging, the CopyMode will be ignored and act as though None were passed. If the mode is set to None, then the destOffset parameter is ignored.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

Examples

The following is an example showing how to upload vertices into a vertex buffer using different techniques:

// Our vertex, with a position and color component.
[StructLayout(LayoutKind = LayoutKind.Sequential)] 
struct MyVertex
{
	public Vector4 Position;
	public Vector4 Color;
}

GorgonGraphics graphics;
MyVertex[] _vertices = new MyVertex[100];
GorgonVertexBuffer _vertexBuffer;

void InitializeVertexBuffer()
{
	_vertices = ... // Fill your vertex array here.

	// Create the vertex buffer large enough so that it'll hold 100 vertices.
	_vertexBuffer = new GorgonVertexBuffer(graphics, GorgonVertexBufferInfo.CreateFromType<MyVertex>(_vertices.Length, Usage.Default));

	// Copy our data to the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan());

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, and 25 vertices.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25));

	// Copy our data to the vertex buffer, using the 5th index in the vertex array, 25 vertices, and storing at index 2 in the vertex buffer.
    _vertexBuffer.SetData<MyVertex>(_vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

    // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
    _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

    // Copy our data from a GorgonNativeBuffer.
    using (GorgonNativeBuffer<MyVertex> vertices = new GorgonNativeBuffer<MyVertex>(100))
    {
       // Copy vertices into the native buffer here....

       // Copy everything.
       _vertexBuffer.SetData(vertices);

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>());

       // Copy our data to the vertex buffer, using the 5th index in the native buffer, 25 vertices, and storing at index 2 in the vertex buffer, using a copy mode.
       _vertexBuffer.SetData(vertices.ToReadOnlySpan(), vertices.ToReadOnlySpan(5, 25), 2 * Unsafe.SizeOf<MyVertex>(), CopyMode.NoOverWrite);

       // Get the data back out from the buffer, using index 5 and up to 10 vertices, storing at index 2 of the native buffer.
       _vertexBuffer.GetData<MyVertex>(vertices.ToSpan(2), 5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>()); 
    }

    // Get the data back out from the buffer.
    MyVertex[] readBack = _vertexBuffer.GetData<MyVertex>();

    // Get the data back out from the buffer, starting at index 5 and a count of 10 vertices.
    readBack = _vertexBuffer.GetData<MyVertex>(5 * Unsafe.SizeOf<MyVertex>(), 10 * Unsafe.SizeOf<MyVertex>());
}
Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the destOffset parameter is less than zero.

ArgumentException

Thrown when the destOffset + span length exceeds the size of the destination buffer.

| Edit this page View Source

SetData<T>(in T, int, CopyMode)

Function to write a single value into the buffer.

Declaration
public void SetData<T>(in T value, int destOffset = 0, CopyMode copyMode = CopyMode.None) where T : unmanaged
Parameters
Type Name Description
T value

The value to write.

int destOffset

[Optional] The offset, in bytes, from the beginning in the buffer to start writing into.

CopyMode copyMode

[Optional] Flags to indicate how to copy the data.

Type Parameters
Name Description
T

The type of value, must be an unmanaged value type.

Remarks

This will upload the specified value to this buffer. The method will determine how to best upload the data depending on the Usage of the buffer. For example, if the buffer has a Usage of Default, then internally, this method will update to the GPU directly. Otherwise, if it is Dynamic, or Staging, it will use a locking pattern which uses the CPU to write data to the buffer. The latter pattern is good if the buffer has to change one or more times per frame, otherwise, the former is better where the buffer is updated less than once per frame (i.e. Dynamic is good for multiple times per frame, Default is good for once per frame or less).

If the user supplies a destOffset the data will be copied to the buffer at the offset provided by destOffset.

The copyMode parameter defines how the copy will be performed. If the buffer has a Usage of Dynamic or Default and the copyMode is set to Discard then the contents of the buffer are discarded before updating, if it is set to NoOverwrite, then the data will be copied to the destination if we know the GPU is not using the portion being updated. If the copyMode is set to None, then Discard is used. For buffers created with a Usage of Staging, the CopyMode will be ignored and act as though None were passed. If the mode is set to None, then the destOffset parameter is ignored.

caution

For performance reasons, any exceptions thrown from this method will only be thrown when Gorgon is compiled as DEBUG.

Examples

The following is an example showing how to upload data into a constant buffer using different techniques:

// Our constant buffer data.  A matrix and a 4 component vector.
[StructLayout(LayoutKind = LayoutKind.Sequential)] 
struct MyCBData
{
	public Matrix ConstantValue1;
	public Vector4 ConstantValue2;
}

GorgonGraphics graphics;
MyCBData _cbData;
GorgonConstantBuffer _constantBuffer;

void InitializeConstantBuffer()
{
	_cbData = new MyCBData
    {
        ConstantValue1 = WorldMatrix,
        ConstantValue2 = AVector4
    };

    // Create the constant buffer.
	_constantBuffer = new GorgonConstantBuffer(graphics, GorgonConstantBufferInfo.CreateFromType<MyCBData>(count: 4));

	// Copy our data to the constant buffer.
    _constantBuffer.SetData<MyCBData>(in _cbData);

    _cbData = new MyCBData
    {
        ConstantValue1 = ProjectionMatrix,
        ConstantValue2 = Vector4.One
    };

    // Write these constants to the 2nd index.  
    _constantBuffer.SetData<MyCBData>(in _cbData, 2 * Unsafe.SizeOf<MyCBData>());
}
Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the destOffset parameter is less than zero.

ArgumentException

Thrown when the destOffset + size of T (in bytes) exceeds the size of the destination buffer.

| Edit this page View Source

ValidateBufferBindings(ResourceUsage, BufferBinding, int)

Function to validate the bindings for a given buffer.

Declaration
protected static void ValidateBufferBindings(ResourceUsage usage, BufferBinding binding, int structureSize)
Parameters
Type Name Description
ResourceUsage usage

The usage flags for the buffer.

BufferBinding binding

The bindings to apply to the buffer, pass null to skip usage and binding check.

int structureSize

The size of a structure within the buffer, in bytes.

Implements

IGorgonNamedObject
IGorgonGraphicsObject
IGorgonNativeResource
IDisposable

Extension Methods

GorgonDebugExtensions.ValidateObject<T>(T, string)
GorgonNullExtensions.AsNullable<T>(object)
GorgonNullExtensions.IfNull<T>(object, T)
GorgonNullExtensions.IsNull(object)
  • Edit this page
  • View Source
In this article
Back to top Copyright 2023 - Licensed under the MIT license by Michael Winsor (Tape_Worm).
Send comments on this topic to the author