public unsafe void Verify_GroupIds(Device device) { using ReadWriteTexture3D <Int4> buffer = device.Get().AllocateReadWriteTexture3D <Int4>(50, 50, 50); device.Get().For(buffer.Width, buffer.Height, buffer.Depth, 4, 4, 4, new GroupIdsShader(buffer)); Int4[,,] data = buffer.ToArray(); int *value = stackalloc int[4]; for (int z = 0; z < 50; z++) { for (int x = 0; x < 50; x++) { for (int y = 0; y < 50; y++) { *(Int4 *)value = data[z, y, x]; Assert.AreEqual(x % 4, value[0]); Assert.AreEqual(y % 4, value[1]); Assert.AreEqual(z % 4, value[2]); Assert.AreEqual(value[2] * 4 * 4 + value[1] * 4 + value[0], value[3]); } } } }
public unsafe void Verify_ThreadIdsNormalized(Device device) { using ReadWriteTexture3D <Float4> buffer = device.Get().AllocateReadWriteTexture3D <Float4>(10, 20, 30); device.Get().For(buffer.Width, buffer.Height, buffer.Depth, new ThreadIdsNormalizedShader(buffer)); Float4[,,] data = buffer.ToArray(); float *value = stackalloc float[4]; for (int z = 0; z < 30; z++) { for (int x = 0; x < 10; x++) { for (int y = 0; y < 20; y++) { *(Float4 *)value = data[z, y, x]; Assert.AreEqual(x / (float)buffer.Width, value[0], 0.000001f); Assert.AreEqual(y / (float)buffer.Height, value[1], 0.000001f); Assert.AreEqual(z / (float)buffer.Depth, value[2], 0.000001f); Assert.AreEqual(x / (float)buffer.Width, value[3], 0.000001f); } } } }
public void Verify_ThreadIds_OutOfRange(Device device, int x, int y, int z) { using ReadWriteTexture3D <Int4> buffer = device.Get().AllocateReadWriteTexture3D <Int4>(50, 50, 50); device.Get().For(x, y, z, new ThreadIdsShader(buffer)); Assert.Fail(); }
public void Verify_GroupIds_OutOfRange(Device device, int x, int y, int z) { using ReadWriteTexture3D <Int4> buffer = device.Get().AllocateReadWriteTexture3D <Int4>(50, 50, 50); device.Get().For(buffer.Width, buffer.Height, buffer.Depth, x, y, z, new GroupIdsShader(buffer)); Assert.Fail(); }
/// <summary> /// Retrieves a wrapping <see cref="IReadOnlyNormalizedTexture3D{TPixel}"/> instance for the input resource. /// </summary> /// <typeparam name="T">The type of items to store in the texture.</typeparam> /// <typeparam name="TPixel">The type of pixels used on the GPU side.</typeparam> /// <param name="texture">The input <see cref="ReadWriteTexture3D{T, TPixel}"/> instance to create a wrapper for.</param> /// <returns>An <see cref="IReadOnlyNormalizedTexture3D{TPixel}"/> instance wrapping the current resource.</returns> /// <remarks> /// <para>The returned instance can be used in a shader to enable texture sampling.</para> /// <para> /// This is an advanced API that can only be used after the current instance has been transitioned to be in a readonly state. To do so, /// use <see cref="ComputeContextExtensions.Transition{T, TPixel}(in ComputeContext, ReadWriteTexture3D{T, TPixel}, ResourceState)"/>, /// and specify <see cref="ResourceState.ReadOnly"/>. After that, this method can be used to get a readonly wrapper for /// the current texture to use in a shader. This instance should not be cached or reused, but just passed directly to a shader /// being dispatched through that same <see cref="ComputeContext"/>, as it will not work if the texture changes state later on. /// Before the end of that list of operations, the texture also needs to be transitioned back to writeable state, using the same /// API as before but specifying <see cref="ResourceState.ReadWrite"/>. Failing to do so results in undefined behavior. /// </para> /// </remarks> /// <exception cref="ObjectDisposedException">Thrown if the current instance or its associated device are disposed.</exception> /// <exception cref="InvalidOperationException">Thrown if the current instance is not in a readonly state.</exception> public static IReadOnlyNormalizedTexture3D <TPixel> AsReadOnly <T, TPixel>(this ReadWriteTexture3D <T, TPixel> texture) where T : unmanaged, IPixel <T, TPixel> where TPixel : unmanaged { Guard.IsNotNull(texture); return(texture.AsReadOnly()); }
public static ulong ValidateAndGetGpuDescriptorHandle <T>(ReadWriteTexture3D <T> texture, GraphicsDevice device) where T : unmanaged { texture.ThrowIfDisposed(); texture.ThrowIfDeviceMismatch(device); return(Unsafe.As <D3D12_GPU_DESCRIPTOR_HANDLE, ulong>(ref Unsafe.AsRef(in texture.D3D12GpuDescriptorHandle))); }
public void Dispatch_NormalizedTexture3D(Device device, Type t, Type tPixel) { if (t == typeof(Bgra32) && tPixel == typeof(Float4)) { using ReadOnlyTexture3D <Bgra32, Float4> source = device.Get().AllocateReadOnlyTexture3D <Bgra32, Float4>(128, 128, 2); using ReadWriteTexture3D <Bgra32, Float4> destination = device.Get().AllocateReadWriteTexture3D <Bgra32, Float4>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_Bgra32_Float4(source, destination)); } if (t == typeof(R16) && tPixel == typeof(float)) { using ReadOnlyTexture3D <R16, float> source = device.Get().AllocateReadOnlyTexture3D <R16, float>(128, 128, 2); using ReadWriteTexture3D <R16, float> destination = device.Get().AllocateReadWriteTexture3D <R16, float>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_R16_float(source, destination)); } if (t == typeof(R8) && tPixel == typeof(float)) { using ReadOnlyTexture3D <R8, float> source = device.Get().AllocateReadOnlyTexture3D <R8, float>(128, 128, 2); using ReadWriteTexture3D <R8, float> destination = device.Get().AllocateReadWriteTexture3D <R8, float>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_R8_float(source, destination)); } if (t == typeof(Rg16) && tPixel == typeof(Float2)) { using ReadOnlyTexture3D <Rg16, Float2> source = device.Get().AllocateReadOnlyTexture3D <Rg16, Float2>(128, 128, 2); using ReadWriteTexture3D <Rg16, Float2> destination = device.Get().AllocateReadWriteTexture3D <Rg16, Float2>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_Rg16_Float2(source, destination)); } if (t == typeof(Rg32) && tPixel == typeof(Float2)) { using ReadOnlyTexture3D <Rg32, Float2> source = device.Get().AllocateReadOnlyTexture3D <Rg32, Float2>(128, 128, 2); using ReadWriteTexture3D <Rg32, Float2> destination = device.Get().AllocateReadWriteTexture3D <Rg32, Float2>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_Rg32_Float2(source, destination)); } if (t == typeof(Rgba32) && tPixel == typeof(Float4)) { using ReadOnlyTexture3D <Rgba32, Float4> source = device.Get().AllocateReadOnlyTexture3D <Rgba32, Float4>(128, 128, 2); using ReadWriteTexture3D <Rgba32, Float4> destination = device.Get().AllocateReadWriteTexture3D <Rgba32, Float4>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_Rgba32_Float4(source, destination)); } if (t == typeof(Rgba64) && tPixel == typeof(Float4)) { using ReadOnlyTexture3D <Rgba64, Float4> source = device.Get().AllocateReadOnlyTexture3D <Rgba64, Float4>(128, 128, 2); using ReadWriteTexture3D <Rgba64, Float4> destination = device.Get().AllocateReadWriteTexture3D <Rgba64, Float4>(128, 128, 2); device.Get().For(128, 128, 2, new Shader_Unorm_Rgba64_Float4(source, destination)); } }
static ReadOnly InitializeWrapper(ReadWriteTexture3D <T> texture) { return(texture.readOnlyWrapper = new(texture)); }
/// <summary> /// Retrieves a wrapping <see cref="IReadOnlyTexture3D{T}"/> instance for the input resource. /// </summary> /// <param name="texture">The input <see cref="ReadWriteTexture3D{T}"/> instance to create a wrapper for.</param> /// <returns>An <see cref="IReadOnlyTexture3D{T}"/> instance wrapping the current resource.</returns> /// <remarks> /// <para>The returned instance can be used in a shader to enable texture sampling.</para> /// <para> /// This is an advanced API that can only be used after the current instance has been transitioned to be in a readonly state. To do so, /// use <see cref="ComputeContextExtensions.Transition(in ComputeContext, ReadWriteTexture3D{Float3}, ResourceState)"/>, /// and specify <see cref="ResourceState.ReadOnly"/>. After that, this method can be used to get a readonly wrapper for /// the current texture to use in a shader. This instance should not be cached or reused, but just passed directly to a shader /// being dispatched through that same <see cref="ComputeContext"/>, as it will not work if the texture changes state later on. /// Before the end of that list of operations, the texture also needs to be transitioned back to writeable state, using the same /// API as before but specifying <see cref="ResourceState.ReadWrite"/>. Failing to do so results in undefined behavior. /// </para> /// </remarks> /// <exception cref="ObjectDisposedException">Thrown if the current instance or its associated device are disposed.</exception> /// <exception cref="InvalidOperationException">Thrown if the current instance is not in a readonly state.</exception> public static IReadOnlyTexture3D <Float3> AsReadOnly(this ReadWriteTexture3D <Float3> texture) { Guard.IsNotNull(texture); return(texture.AsReadOnly()); }