// RUN: %empty-directory(%t)
// RUN: %target-build-swift %s -o %t/a.out4 -swift-version 4 && %target-codesign %t/a.out4 && %target-run %t/a.out4
// REQUIRES: objc_interop
// UNSUPPORTED: OS=watchos

// REQUIRES: executable_test

// Requires swift-version 4
// UNSUPPORTED: swift_test_mode_optimize_none_with_implicit_dynamic

import StdlibUnittest

import Metal

var MetalTests = TestSuite("Metal")

if #available(OSX 10.13, iOS 11.0, tvOS 11.0, *) {

  // Call each overlay to ensure nothing explodes

  MetalTests.test("MTLArgumentEncoder") {
    func apiAvailabilityTest() {
      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      let buf = device.makeBuffer(
        length: 64, options: MTLResourceOptions.storageModeShared)!
      let texDesc = MTLTextureDescriptor()
      texDesc.usage = MTLTextureUsage.renderTarget
      let tex = device.makeTexture(descriptor: texDesc)!
      let smplr = device.makeSamplerState(descriptor: MTLSamplerDescriptor())

      var arguments = [MTLArgumentDescriptor]()
      arguments.append(MTLArgumentDescriptor())
      arguments.append(MTLArgumentDescriptor())
      arguments.append(MTLArgumentDescriptor())
      arguments[0].dataType = MTLDataType.pointer
      arguments[0].index = 0
      arguments[1].dataType = MTLDataType.texture
      arguments[1].index = 1
      arguments[2].dataType = MTLDataType.sampler
      arguments[2].index = 2
      if #available(OSX 10.14, iOS 12.0, tvOS 12.0, *){
        arguments.append(MTLArgumentDescriptor())
        arguments[3].dataType = MTLDataType.indirectCommandBuffer
        arguments[3].index = 3
      }

      /* Call APIs */

      let argEncoder = device.makeArgumentEncoder(arguments: arguments)!
      argEncoder.setArgumentBuffer(buf, offset: 0)
      argEncoder.setBuffers([buf], offsets: [0], range: 0..<1)
      argEncoder.setTextures([tex], range: 1..<2)
      argEncoder.setSamplerStates([smplr], range: 2..<3)

      if #available(OSX 10.14, iOS 12.0, tvOS 12.0, *){
        let icbDesc = MTLIndirectCommandBufferDescriptor()
        icbDesc.commandTypes = [.draw, .drawIndexed]
        icbDesc.inheritBuffers = false
        icbDesc.maxVertexBufferBindCount = 1
        icbDesc.maxFragmentBufferBindCount = 1
        let icb = device.makeIndirectCommandBuffer (descriptor: icbDesc, maxCommandCount: 1, options: MTLResourceOptions.storageModeShared )!
        argEncoder.setIndirectCommandBuffers([icb], range: 3..<4)
      }
    }
  }

  MetalTests.test("MTLBlitCommandEncoder") {
    func apiAvailabilityTest() {

      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      let queue = device.makeCommandQueue()!
      let cmdBuf = queue.makeCommandBuffer()!
      let bltCmdEncdr = cmdBuf.makeBlitCommandEncoder()!

      /* Call APIs */

      let buf = device.makeBuffer(length: 4, options: MTLResourceOptions())!
      bltCmdEncdr.fill(buffer: buf, range: 0..<buf.length, value: 0)

      if #available(OSX 10.14, iOS 12.0, tvOS 12.0, *){
        let icbDesc = MTLIndirectCommandBufferDescriptor()
        icbDesc.commandTypes = [.draw, .drawIndexed]
        icbDesc.inheritBuffers = false
        icbDesc.maxVertexBufferBindCount = 1
        icbDesc.maxFragmentBufferBindCount = 1
        let icb1 = device.makeIndirectCommandBuffer (descriptor: icbDesc, maxCommandCount: 4, options: MTLResourceOptions.storageModeShared )!
        let icb2 = device.makeIndirectCommandBuffer (descriptor: icbDesc, maxCommandCount: 4, options: MTLResourceOptions.storageModeShared )!
        bltCmdEncdr.resetCommandsInBuffer (icb1, range:0..<5)
        bltCmdEncdr.resetCommandsInBuffer (icb2, range:0..<5)
        bltCmdEncdr.copyIndirectCommandBuffer (icb1, sourceRange: 0..<5, destination: icb2, destinationIndex:0)
        bltCmdEncdr.optimizeIndirectCommandBuffer (icb1, range:0..<5)
      }

      bltCmdEncdr.endEncoding()
    }
  }

if #available(OSX 10.14, iOS 12.0, tvOS 12.0, *){
  MetalTests.test("MTLIndirectCommandBuffer"){
    func apiAvailabilityTest() {

      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      let queue = device.makeCommandQueue()!
      let cmdBuf = queue.makeCommandBuffer()!
      let texDesc = MTLTextureDescriptor()
      texDesc.usage = MTLTextureUsage.renderTarget
      let tex = device.makeTexture(descriptor: texDesc)!
      let rpDesc = MTLRenderPassDescriptor()
      rpDesc.colorAttachments[0].texture = tex

      let buf = device.makeBuffer(length: 4, options: MTLResourceOptions.storageModeShared)!
      let icbDesc = MTLIndirectCommandBufferDescriptor()
      icbDesc.commandTypes = [.draw, .drawIndexed]
      icbDesc.inheritBuffers = false
      icbDesc.maxVertexBufferBindCount = 1
      icbDesc.maxFragmentBufferBindCount = 1
      let icb = device.makeIndirectCommandBuffer(descriptor: icbDesc, maxCommandCount: 4, options: MTLResourceOptions.storageModeShared )!

      /* Call APIs */

      let encoder = cmdBuf.makeRenderCommandEncoder(descriptor: rpDesc)!
      let cmd = icb.indirectRenderCommandAt(0)
      cmd.setVertexBuffer(buf, offset: 0, at: 0)
      cmd.setFragmentBuffer(buf, offset: 0, at: 0)
      cmd.drawPrimitives(MTLPrimitiveType.triangle, vertexStart: 0, vertexCount: 0, instanceCount: 0, baseInstance: 0)
      let cmd2 = icb.indirectRenderCommandAt(1)
      cmd2.drawIndexedPrimitives(MTLPrimitiveType.triangle, indexCount: 0, indexType: MTLIndexType.uint16, indexBuffer: buf, indexBufferOffset: 0, instanceCount: 0, baseVertex: 0, baseInstance: 0)
      let cmd3 = icb.indirectRenderCommandAt(2)
      cmd3.reset()
      icb.reset(0..<5)
      encoder.executeCommandsInBuffer(icb, range:0..<5)
      encoder.endEncoding()
    }

  }
}

  MetalTests.test("MTLBuffer") {
    func apiAvailabilityTest() {

      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      #if os(macOS)
        let options = MTLResourceOptions.storageModeManaged
      #else
        let options = MTLResourceOptions.storageModePrivate
      #endif
      let buf = device.makeBuffer(length: 4, options: options)!

      /* Call APIs */

      #if os(macOS)
        buf.didModifyRange(0..<4)
      #endif
      buf.addDebugMarker("test marker", range: 0..<4)
    }
  }

  MetalTests.test("MTLComputeCommandEncoder") {
    func apiAvailabilityTest(heapDesc: MTLHeapDescriptor) {

      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      let queue = device.makeCommandQueue()!
      let cmdBuf = queue.makeCommandBuffer()!

      #if os(macOS)
        let options = MTLResourceOptions.storageModeManaged
      #else
        let options = MTLResourceOptions.storageModePrivate
      #endif
      let buf = device.makeBuffer(length: 4, options: options)!
      let tex = device.makeTexture(descriptor: MTLTextureDescriptor())!
      heapDesc.size = 4
      let heap = device.makeHeap(descriptor: heapDesc)!
      let smplr = device.makeSamplerState(descriptor: MTLSamplerDescriptor())

      /* Call APIs */

      let encoder = cmdBuf.makeComputeCommandEncoder()!
      encoder.useResources([buf], usage: MTLResourceUsage.read)
      encoder.useHeaps([heap])
      encoder.setBuffers([buf], offsets: [0], range: 0..<1)
      encoder.setTextures([tex], range: 0..<1)
      encoder.setSamplerStates([smplr], range: 0..<1)
      encoder.setSamplerStates(
        [smplr], lodMinClamps: [0], lodMaxClamps: [0], range: 0..<1)
        if #available(macOS 10.14, iOS 12.0, tvOS 12.0, *)
        {
            encoder.memoryBarrier(resources: [buf])
            /* encoder.memoryBarrier(scope: MTLBarrierScope.buffers) */
        }
      encoder.endEncoding()
    }
  }

  MetalTests.test("MTLDevice") {
    func apiAvailabilityTest() {

      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!

      /* Call APIs */

      var samplePositions : [MTLSamplePosition]
      if (device.supportsTextureSampleCount(2)) {
        samplePositions = device.getDefaultSamplePositions(sampleCount: 2)
      }
      else if (device.supportsTextureSampleCount(4)) {
        samplePositions = device.getDefaultSamplePositions(sampleCount: 4)
      }
      else {
        expectUnreachable("device unexpectedly does not support sample count 2 or 4")
      }
    }
  }

  MetalTests.test("MTLFunctionConstantValues") {
    func apiAvailabilityTest() {

      /* Call APIs */

      let vals = MTLFunctionConstantValues()
      vals.setConstantValues([0], type: MTLDataType.float, range: 0..<1)
    }
  }

  MetalTests.test("MTLRenderCommandEncoder") {
    func apiAvailabilityTest(heapDesc: MTLHeapDescriptor) {

      /* Setup */
      let device = MTLCreateSystemDefaultDevice()!
      let queue = device.makeCommandQueue()!
      let cmdBuf = queue.makeCommandBuffer()!

      #if os(macOS)
        let options = MTLResourceOptions.storageModeManaged
      #else
        let options = MTLResourceOptions.storageModePrivate
      #endif
      let buf = device.makeBuffer(length: 4, options: options)!
      let texDesc = MTLTextureDescriptor()
      texDesc.usage = MTLTextureUsage.renderTarget
      let tex = device.makeTexture(descriptor: texDesc)!
      heapDesc.size = 4
      let heap = device.makeHeap(descriptor: heapDesc)!
      let smplr = device.makeSamplerState(descriptor: MTLSamplerDescriptor())
      let rpDesc = MTLRenderPassDescriptor()
      rpDesc.colorAttachments[0].texture = tex

      /* Call APIs */

      let encoder = cmdBuf.makeRenderCommandEncoder(descriptor: rpDesc)!
      encoder.useResources([buf], usage: MTLResourceUsage.read)
      encoder.useHeaps([heap])
#if os(macOS) || os(iOS)
      if #available(iOS 12.0, macOS 10.13, *) {
        encoder.setViewports([MTLViewport()])
        encoder.setScissorRects([MTLScissorRect(x:0, y:0, width:1, height:1)])
      }
#endif
      encoder.setVertexBuffers([buf], offsets: [0], range: 0..<1)
      encoder.setVertexTextures([tex], range: 0..<1)
      encoder.setVertexSamplerStates([smplr], range: 0..<1)
      encoder.setVertexSamplerStates(
        [smplr], lodMinClamps: [0], lodMaxClamps: [0], range: 0..<1)
      encoder.setFragmentBuffers([buf], offsets: [0], range: 0..<1)
      encoder.setFragmentTextures([tex], range: 0..<1)
      encoder.setFragmentSamplerStates([smplr], range: 0..<1)
      encoder.setFragmentSamplerStates(
        [smplr], lodMinClamps: [0], lodMaxClamps: [0], range: 0..<1)
     #if os(iOS)
         encoder.setTileBuffers([buf], offsets: [0], range: 0..<1)
         encoder.setTileTextures([tex], range: 0..<1)
         encoder.setTileSamplerStates([smplr], range: 0..<1)
         encoder.setTileSamplerStates(
           [smplr], lodMinClamps: [0], lodMaxClamps: [0], range: 0..<1)
     #endif
      #if os(OSX)
        if #available(macOS 10.14, *)
        {
            encoder.memoryBarrier(resources: [buf], after:MTLRenderStages.fragment, before:MTLRenderStages.vertex)
            /* encoder.memoryBarrier(scope: MTLBarrierScope.renderTargets, after:MTLRenderStages.fragment, before:MTLRenderStages.vertex) */
        }
      #endif
      encoder.endEncoding()
    }
  }

  MetalTests.test("MTLRenderPassDescriptor") {
    func apiAvailabilityTest() {

      /* Setup */

      let rpDesc = MTLRenderPassDescriptor()

      /* Call APIs */

      rpDesc.setSamplePositions(
        [MTLSamplePosition(x:0.25,y:0.75), MTLSamplePosition(x:0.75, y:0.25)])
      _ = rpDesc.getSamplePositions()
    }
  }

  MetalTests.test("MTLTexture") {
    func apiAvailabilityTest() {
      /* Setup */

      let device = MTLCreateSystemDefaultDevice()!
      let texDesc = MTLTextureDescriptor()
      texDesc.usage = MTLTextureUsage.renderTarget
      let tex = device.makeTexture(descriptor: texDesc)!

      /* Call APIs */

      let _ = tex.makeTextureView(
        pixelFormat: texDesc.pixelFormat,
        textureType: texDesc.textureType,
        levels: 0..<1,
        slices: 0..<1)
    }
  }
}

runAllTests()
