5 Replies
      Latest reply on Aug 23, 2019 2:04 AM by chris@interealtime
      Arnfried Griesert Level 1 Level 1 (10 points)

        Does someone know how they GPU channels work exactly in Metal?

        I implemented a blit command encoder in two different ways and metal system traces showed me that one blit command was sheduled to the GPUs blit channel while the other is running on the gfx channel.


        - First Blit Copy: Shared MTLBuffer -> Private MTLBuffer

        - Second Blit Copy: CVMetalTexture -> Private MTLTexture


        Both blit commands were commited to the queue in seperate command buffers and on seperate threads.


        A blit commander for generateMipmaps() on the private MTLTexture from above is also running on the gfx channel and not on the blit channel. Copying parts from one private texture to another region of a destination private texture also runs on the gfx channel.

        So only the blit copy from one buffer to another buffer seems to run in the blit channel or is this wrong?

        • Re: GPU channels, how do they work?
          KMT Level 9 Level 9 (15,785 points)
            • Re: GPU channels, how do they work?
              Arnfried Griesert Level 1 Level 1 (10 points)

              Both examples are using the same source coming from an AVAssetReader. The first one use the system memory directly and copies it (blit copy) into a MTLBuffer and this runs in the GPU blit channel as I can see in Metal System Trace.

              The second example uses the same resource but as a CVMetalTexture and copies this into a private MTLTexture. This should work because I copy from a shared resource (a) into a private texture (b) and blit from there regions into another private texture (c). On this texture I apply another blit operation for creating mipmaps. All these three blit commands are using GPU resources but all of them are not using the blit channel but the gfx instead.

              It seems the sheduling of commands to the different GPU channels is something that happens under the hood in the encoders and can be different from gpu to gpu. But maybe there is also a way to blit copy a texture from a shared storage to a private storage texture that will using the GPUs blit channel (also the mipmap command). Then I could speed up my image processing on the GPU even more.

                • Re: GPU channels, how do they work?
                  chris@interealtime Level 1 Level 1 (10 points)

                  It might simply be that using the GPU channel is faster as the 2nd example is texture data? Especially with mipmapping, that's not a simple data copy, it'll be reading the texture in quads and averaging.


                  It looks like it's forced through the blit channel when your data is a buffer rather than a texture, so if you want to profile it you could just use buffers instead of textures (or create textures with buffer backing).

              • Re: GPU channels, how do they work?
                Arnfried Griesert Level 1 Level 1 (10 points)

                After pulling out my last hair I found the problem:


                If you don't set a label on the blit encoder then instruments shows this command in the DMA channel.

                If you set a label like in the code below (line 4) then the command uses the GPUs BLIT channel.


                if let commandBuffer = engine.commandQueue.makeCommandBuffer() {
                    commandBuffer.label = "Copy Image to GPU [\(processorID)]"
                    if let encoder = commandBuffer.makeBlitCommandEncoder() {
                         encoder.label = "Copy Image to GPU [\(processorID)]"
                         encoder.copy(from: inputBufferSystemMemory, sourceOffset: 0, to: inputBuffer, destinationOffset: 0, size: inp


                Maybe someone knows if this is correct otherwise I would file a radar because for me it looks like a bug. Unfortunately I cannot add the screenshots to show the gpu channels from instruments.