/// <summary> /// Function to set a constant buffer for a specific shader stage. /// </summary> /// <param name="shaderType">The shader stage to use.</param> /// <param name="constantBuffer">The constant buffer to assign.</param> /// <param name="slot">The slot for the constant buffer.</param> /// <returns>The fluent builder interface.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="slot"/> is less than 0, or greater than/equal to <see cref="GorgonConstantBuffers.MaximumConstantBufferCount"/>.</exception> /// <exception cref="NotSupportedException">Thrown if the <paramref name="shaderType"/> is not valid.</exception> /// <remarks> /// <para> /// <see cref="ShaderType.Compute"/> shaders are not supported in this method will throw an exception. /// </para> /// </remarks> public TB ConstantBuffer(ShaderType shaderType, GorgonConstantBufferView constantBuffer, int slot = 0) { if ((slot < 0) || (slot >= GorgonConstantBuffers.MaximumConstantBufferCount)) { throw new ArgumentOutOfRangeException(nameof(slot), string.Format(Resources.GORGFX_ERR_CBUFFER_SLOT_INVALID, GorgonConstantBuffers.MaximumConstantBufferCount)); } switch (shaderType) { case ShaderType.Pixel: DrawCall.D3DState.PsConstantBuffers[slot] = constantBuffer; break; case ShaderType.Vertex: DrawCall.D3DState.VsConstantBuffers[slot] = constantBuffer; break; case ShaderType.Geometry: DrawCall.D3DState.GsConstantBuffers[slot] = constantBuffer; break; case ShaderType.Domain: DrawCall.D3DState.DsConstantBuffers[slot] = constantBuffer; break; case ShaderType.Hull: DrawCall.D3DState.HsConstantBuffers[slot] = constantBuffer; break; default: throw new NotSupportedException(string.Format(Resources.GORGFX_ERR_SHADER_UNKNOWN_TYPE, shaderType)); } return((TB)this); }
/// <summary> /// Function to retrieve a view of the constant buffer elements to pass to a shader. /// </summary> /// <param name="firstElement">[Optional] The index of the first element in the buffer to view.</param> /// <param name="elementCount">[Optional] The number of elements to view.</param> /// <returns>A new <see cref="GorgonConstantBufferView"/> used to map a portion of a constant buffer to a shader.</returns> /// <remarks> /// <para> /// This will create a view of the buffer so that a shader can access a portion (or all, if the buffer is less than or equal to 4096 constants in size) of a constant buffer. Shaders can only access /// up to 4096 constants in a constant buffer, and this allows us to bind and use a much larger buffer to the shader while still respecting the maximum constant accessibility. /// </para> /// <para> /// A single constant buffer constant is a float4 value (4 floating point values, or 16 bytes). /// </para> /// <para> /// The <paramref name="firstElement"/> parameter must be between 0 and the total element count (minus one) of the buffer. If it is not it will be constrained to those values to ensure there is no /// out of bounds access to the buffer. /// </para> /// <para> /// If the <paramref name="elementCount"/> parameter is omitted (or less than 1), then the remainder of the buffer is mapped to the view up to 256 elements (4096 constants, or 65536 bytes). If it /// is provided, then the number of elements will be mapped to the view, up to a maximum of 256 elements. If the value exceeds 256, then it will be constrained to 256. /// </para> /// <para> /// <note type="important"> /// <para> /// Due to the nature of constant buffers on GPU hardware, these views are not aligned to a constant (which is a float4, or 16 bytes), but rather aligned to 16 constants (16 float4 values, or 256 /// bytes). This requires that your buffer be set up to be a multiple of 256 bytes in its <see cref="IGorgonConstantBufferInfo.SizeInBytes"/>. This makes each element in the view the same as 16 float4 /// values (or 256 bytes). That means when an offset of 2, and a count of 4 is set in the view, it is actually at an offset of 32 float4 values (512 bytes), and covers a range of 64 float4 values /// (1024 bytes). Because of this, care should be taken to ensure the buffer matches this alignment if constant buffer offsets/counts are to be used in your application. /// </para> /// <para> /// If no offsetting into the buffer is required, then the above information is not applicable and the method can be called with its default parameters (i.e. no parameters). /// </para> /// </note> /// </para> /// </remarks> public GorgonConstantBufferView GetView(int firstElement = 0, int elementCount = 0) { var result = new GorgonConstantBufferView(this, firstElement, elementCount); _cbvs.Add(result); return(result); }
/// <summary> /// Function to set a constant buffer for a compute shader stage. /// </summary> /// <param name="constantBuffer">The constant buffer to assign.</param> /// <param name="slot">The slot for the constant buffer.</param> /// <returns>The fluent builder interface.</returns> /// <exception cref="ArgumentNullException">Thrown when the <paramref name="slot"/> is less than 0, or greater than/equal to <see cref="GorgonConstantBuffers.MaximumConstantBufferCount"/>.</exception> public GorgonDispatchCallBuilder ConstantBuffer(GorgonConstantBufferView constantBuffer, int slot = 0) { if ((slot < 0) || (slot >= GorgonConstantBuffers.MaximumConstantBufferCount)) { throw new ArgumentOutOfRangeException(nameof(slot), string.Format(Resources.GORGFX_ERR_CBUFFER_SLOT_INVALID, 0)); } _worker.D3DState.CsConstantBuffers[slot] = constantBuffer; return(this); }