anchor.diff:          use app = new HeadlessVulkanApplication(false)
           let device = app.Device
           
  +        let dct = device |> ComputeShader.ofFunction JpegGPU.dct
  +        let input = ComputeShader.newInputBinding dct app.Runtime.DescriptorPool
           
  -        let shader = device |> ComputeShader.ofFunction JpegGPU.compact
  -        let input = ComputeShader.newInputBinding shader app.Runtime.DescriptorPool
  -
  -
  -        let data = device.CreateBuffer<V4f>(Array.init 64 (fun i -> if i % 3 = 0 then V4f(i,i,i,i) else V4f.Zero))
  -        let counts = device.CreateBuffer<int>(1L)
  -        let b = device.CreateBuffer<uint32>(64L)
  +        let rand = RandomSystem()
  +
  +        let image = PixImage<byte>(Col.Format.RGBA, V2i(32,32))
  +        image.GetMatrix<C4b>().SetByCoord(fun (c : V2l) ->
  +            rand.UniformC3f().ToC4b()
  +        ) |> ignore
  +
  +        let alignedSize = V2i(next image.Size.X 8, next image.Size.Y 8)
  +
  +        let sourceData = device.CreateImage(PixTexture2d(PixImageMipMap [| image :> PixImage|], TextureParams.empty))
  +        let targetBuffer = device.CreateBuffer<V4f>(int64 alignedSize.X * int64 alignedSize.Y)
  +
  +        input.["size"] <- alignedSize
  +        input.["target"] <- targetBuffer
  +        input.["InputImage"] <- sourceData
  +        input.Flush()
  +
  +        device.perform {
  +            do! Command.Bind dct
  +            do! Command.SetInputs input
  +            do! Command.Dispatch (alignedSize / V2i(8,8))
  +            do! Command.Sync(targetBuffer, VkAccessFlags.ShaderWriteBit, VkAccessFlags.TransferReadBit)
  +        }
  +
  +
  +        let encode = device |> ComputeShader.ofFunction JpegGPU.compact
  +        let input = ComputeShader.newInputBinding encode app.Runtime.DescriptorPool
  +
  +
  +        //let data = device.CreateBuffer<V4f>(Array.init 64 (fun i -> if i % 3 = 0 then V4f(i,i,i,i) else V4f.Zero))
  +        let blocks = (alignedSize.X * alignedSize.Y) / 64
  +        let ranges = device.CreateBuffer<V2i>(int64 blocks)
  +        let b = device.CreateBuffer<uint32>(64L * int64 blocks)
  +        let counter = device.CreateBuffer<int>(Array.zeroCreate 1)
  +
           input.["channel"] <- 0
  -        input.["data"] <- data
  -        input.["counts"] <- counts
  +        input.["data"] <- targetBuffer
  +        input.["ranges"] <- ranges
  +        input.["counter"] <- counter
           input.["mask"] <- b
           input.Flush()
           
           device.perform {
  -            do! Command.Bind shader
  +            do! Command.Bind encode
               do! Command.SetInputs input
  -            do! Command.Dispatch 1
  +            do! Command.Dispatch blocks
           }
   
  -        let arr = Array.zeroCreate 64
  -        b.Download(arr)
  -
  -        let arr2 = 
  -            arr |> Array.map (fun v ->
  -                let lz = (v >>> 16) &&& 0xFFFFu |> int
  -                let v = int (v &&& 0xFFFFu) - 32768
  -                (lz,v)
  -            )
  -
  -        let cnts = Array.zeroCreate 1
  -        counts.Download(cnts)
  +        let cnt = Array.zeroCreate 1
  +        counter.Download(cnt)
  +
  +        let arr = Array.zeroCreate cnt.[0]
  +        b.Download(0L, arr, 0L, arr.LongLength)
  +
  +        let r = Array.zeroCreate blocks
  +        ranges.Download(r)
      
  -        printfn "%A (%A)" arr2.[0] cnts.[0]
  -
  -
  -        let shader = device |> ComputeShader.ofFunction JpegGPU.dct
  -        let input = ComputeShader.newInputBinding shader app.Runtime.DescriptorPool
  +
  +        printfn "%A (%A) %A" arr.[0] r.[0] cnt.[0]
  +
  +
           
  -        let rand = RandomSystem()
  -
  -        let image = PixImage<byte>(Col.Format.RGBA, V2i(8,8))
  -        image.GetMatrix<C4b>().SetByCoord(fun (c : V2l) ->
  -            rand.UniformC3f().ToC4b()
  -        ) |> ignore
  -
  -        let alignedSize = V2i(next image.Size.X 8, next image.Size.Y 8)
  -
  -        let sourceData = device.CreateImage(PixTexture2d(PixImageMipMap [| image :> PixImage|], TextureParams.empty))
  -        let targetBuffer = device.CreateBuffer<V4f>(int64 alignedSize.X * int64 alignedSize.Y)
  -
  -        input.["size"] <- alignedSize
  -        input.["target"] <- targetBuffer
  -        input.["InputImage"] <- sourceData
  -        input.Flush()
  -
  -        device.perform {
  -            do! Command.Bind shader
  -            do! Command.SetInputs input
  -            do! Command.Dispatch (alignedSize / V2i(8,8))
  -            do! Command.Sync(targetBuffer, VkAccessFlags.ShaderWriteBit, VkAccessFlags.TransferReadBit)
  -        }
   
           let arr = Array.zeroCreate (alignedSize.X * alignedSize.Y)
           targetBuffer.Download(arr)
  
positive.code: 
  
                  if rnz then
                      let rSize, rc = encode rlid (rlz % 16) rv
                      rCode <- rc
                      rLength <- rSize
                  elif rlz > 0 && rlz % 16 = 0 then
  
negative.code:             word <<< cnt
  
          [<LocalSize(X = 32)>]
          let compact (channel : int) (counter : int[]) (data : float[]) (ranges : V2i[]) (mask : uint32[]) =
              compute {
                  let mem = allocateShared 64
                  let temp = allocateShared 64
                  let offsetStore = allocateShared 1
  
                  let offset = getWorkGroupId().X * 64
  
  