1 people like it.

SlimDX static noise compute shader

A compute shader using wang's hash to make a static filled window. Runs at 2000 frames per second on my machine.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
open SlimDX
open SlimDX.D3DCompiler
open SlimDX.Direct3D11
open SlimDX.Windows
open System.Runtime.InteropServices

#nowarn "9" 
[<StructLayout(LayoutKind.Sequential)>]
type Constants = {frame : int32}

// Helper class for handling constants
type ShaderConstants<'a> (device : Device) =
    // NOTE - the buffer size must be a multiple of 16
    let vsConstBuffer = 
        new Buffer(device, 
            new BufferDescription(
                BindFlags = BindFlags.ConstantBuffer,
                SizeInBytes = ((sizeof<'a> + 15) / 16) * 16,
                CpuAccessFlags = CpuAccessFlags.Write,
                Usage = ResourceUsage.Dynamic))

    let context = device.ImmediateContext

    let updateShaderConstants constBuffer sizeInBytes data  = 
        let constData = context.MapSubresource(constBuffer, MapMode.WriteDiscard, MapFlags.None)
        Marshal.StructureToPtr(data, constData.Data.DataPointer, false)
        context.UnmapSubresource(constBuffer, 0)
        
    member this.Update(constants : 'a) =
        updateShaderConstants vsConstBuffer sizeof<'a> constants
        context.ComputeShader.SetConstantBuffers([|vsConstBuffer|], 0, 1)

// Sadly there are some naming conflicts between SlimDX.DXGI and SlimDX.Direct3D11.
open SlimDX.DXGI

[<EntryPoint>]
let main args =
    use form = new RenderForm("Test Window")
    let width, height = 1000, 1000
    do  form.SetBounds(0, 0, width, height)

    let swapChainDescription = 
        SwapChainDescription(
            BufferCount = 1,
            Usage = (Usage.RenderTargetOutput ||| Usage.UnorderedAccess),
            OutputHandle = form.Handle,
            IsWindowed = true,
            ModeDescription = ModeDescription(0, 0, Rational(60, 1), Format.R8G8B8A8_UNorm),
            SampleDescription = SampleDescription(1, 0))

    let result, device, swapChain = 
        Device.CreateWithSwapChain(
            DriverType.Hardware, 
            DeviceCreationFlags.Debug, 
            [|FeatureLevel.Level_11_0|], 
            swapChainDescription)

    use renderTarget = 
        use renderResource = Resource.FromSwapChain<Texture2D>(swapChain, 0)
        new RenderTargetView(device, renderResource)
    
    use computeShader =
        let code = @"
            RWTexture2D<float4> Output;

            int frame;

            uint wang_hash (uint seed) {
                seed = (seed ^ 61) ^ (seed >> 16);
                seed *= 9;
                seed = seed ^ (seed >> 4);
                seed *= 0x27d4eb2d;
                seed = seed ^ (seed >> 15);
                return seed;
            }

            [numthreads(32, 32, 1)]
            void main (uint3 threadID : SV_DispatchThreadID) {
                float noise = wang_hash(threadID.x + threadID.y * 640 + frame) / 4294967296.0;
                Output[threadID.xy] = float4(noise, noise, noise, 1);
            }
        "
        use bytecode = ShaderBytecode.Compile(code, "main", "cs_5_0", ShaderFlags.None, EffectFlags.None) 
        new ComputeShader(device, bytecode)

    use computeResult = new UnorderedAccessView(device, renderTarget.Resource)
    let context = device.ImmediateContext

    context.ComputeShader.Set(computeShader);
    context.ComputeShader.SetUnorderedAccessView(computeResult, 0);

    // set viewport
    context.Rasterizer.SetViewports(Viewport(0.0f, 0.0f, float32 width, float32 height, 0.0f, 1.0f))

    let constants = ShaderConstants<Constants>(device)
    let frame = ref 0

    // runs per frame
    MessagePump.Run(form, MainLoop(fun () ->
        // clear render buffer to black
        context.ClearRenderTargetView(renderTarget, Color4())
        // update shader variables
        constants.Update({frame = !frame})
        // run compute shader
        context.Dispatch(32, 32, 1);
        // copy output buffer to screen
        swapChain.Present(0, PresentFlags.None) |> ignore

        frame := !frame + width * height
    ))

    0 // return an integer exit code
namespace System
namespace System.Runtime
namespace System.Runtime.InteropServices
Multiple items
type StructLayoutAttribute =
  inherit Attribute
  new : layoutKind:LayoutKind -> StructLayoutAttribute + 1 overload
  val Pack : int
  val Size : int
  val CharSet : CharSet
  member Value : LayoutKind

Full name: System.Runtime.InteropServices.StructLayoutAttribute

--------------------
StructLayoutAttribute(layoutKind: LayoutKind) : unit
StructLayoutAttribute(layoutKind: int16) : unit
type LayoutKind =
  | Sequential = 0
  | Explicit = 2
  | Auto = 3

Full name: System.Runtime.InteropServices.LayoutKind
field LayoutKind.Sequential = 0
type Constants =
  {frame: int32;}

Full name: Script.Constants
Constants.frame: int32
Multiple items
val int32 : value:'T -> int32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int32

--------------------
type int32 = System.Int32

Full name: Microsoft.FSharp.Core.int32
Multiple items
type ShaderConstants<'a> =
  new : device:obj -> ShaderConstants<'a>
  member Update : constants:'a -> 'a0

Full name: Script.ShaderConstants<_>

--------------------
new : device:obj -> ShaderConstants<'a>
val device : obj
val vsConstBuffer : obj
val sizeof<'T> : int

Full name: Microsoft.FSharp.Core.Operators.sizeof
val context : obj
val updateShaderConstants : ('a -> 'b -> 'c -> 'd)
val constBuffer : 'a
val sizeInBytes : 'b
val data : 'c
val constData : obj
union case Option.None: Option<'T>
type Marshal =
  static val SystemDefaultCharSize : int
  static val SystemMaxDBCSCharSize : int
  static member AddRef : pUnk:nativeint -> int
  static member AllocCoTaskMem : cb:int -> nativeint
  static member AllocHGlobal : cb:nativeint -> nativeint + 1 overload
  static member AreComObjectsAvailableForCleanup : unit -> bool
  static member BindToMoniker : monikerName:string -> obj
  static member ChangeWrapperHandleStrength : otp:obj * fIsWeak:bool -> unit
  static member CleanupUnusedObjectsInCurrentContext : unit -> unit
  static member Copy : source:int[] * startIndex:int * destination:nativeint * length:int -> unit + 15 overloads
  ...

Full name: System.Runtime.InteropServices.Marshal
Marshal.StructureToPtr(structure: obj, ptr: nativeint, fDeleteOld: bool) : unit
namespace Microsoft.FSharp.Data
val this : ShaderConstants<'a>
member ShaderConstants.Update : constants:'a -> 'a0

Full name: Script.ShaderConstants`1.Update
val constants : 'a
Multiple items
type EntryPointAttribute =
  inherit Attribute
  new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
val main : args:string [] -> int

Full name: Script.main
val args : string []
val form : System.IDisposable
val width : int
val height : int
val swapChainDescription : obj
Multiple items
type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Residue,'Result>

Full name: Microsoft.FSharp.Core.Format<_,_,_,_>

--------------------
type Format<'Printer,'State,'Residue,'Result,'Tuple> = PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>

Full name: Microsoft.FSharp.Core.Format<_,_,_,_,_>
val result : obj
val swapChain : obj
val renderTarget : System.IDisposable
val renderResource : System.IDisposable
val computeShader : System.IDisposable
val code : string
val bytecode : System.IDisposable
val computeResult : System.IDisposable
Multiple items
module Set

from Microsoft.FSharp.Collections

--------------------
type Set<'T (requires comparison)> =
  interface IComparable
  interface IEnumerable
  interface IEnumerable<'T>
  interface ICollection<'T>
  new : elements:seq<'T> -> Set<'T>
  member Add : value:'T -> Set<'T>
  member Contains : value:'T -> bool
  override Equals : obj -> bool
  member IsProperSubsetOf : otherSet:Set<'T> -> bool
  member IsProperSupersetOf : otherSet:Set<'T> -> bool
  ...

Full name: Microsoft.FSharp.Collections.Set<_>

--------------------
new : elements:seq<'T> -> Set<'T>
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
val constants : ShaderConstants<Constants>
val frame : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
member ShaderConstants.Update : constants:'a -> 'a0
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
Raw view Test code New version

More information

Link:http://fssnip.net/gy
Posted:11 years ago
Author:gradbot
Tags: slimdx , directx , compute , shader