Metal compute shader parameter specification and setting

I am new to Metal. I need to port OpenCL compute shader programs to Metal compute shaders. I am having trouble in finding sample codes in Metal and Swift, Objective-C. I can see examples with GPU buffer objects only. As in the following OpenCL shader function, I need to pass uniform constant float and integer values along with GPU buffer pointers. I only use compute shaders.

__kernel void testfunction (
	float  ratio1,
	int    opr1,
	int    opr2,
	__global float *INPUT1,
	__global float *INPUT2,
	__global float *OUTPUT
} {
	int peIndex = get_global_id(0);
// main compute block
}

How can I code these in Metal? And how can I set/pass these parameter values in Swift and Objective-c main programs?

  • My shader program has several functions to put together. I need enqueue multiple times using different functions with different parameters. Same functions can be used with different parameters. This means that I need to create different "struct" and buffer objects for each enqueuing task and transfer value to GPU at initialization time. Note that for each enqueuing, parameter set is different but in subsequent operations parameters don't change. Am I correct? Thanks.

Add a Comment

Replies

You could do something like this:

struct Uniforms {
  float ratio1;
  int opr1, opr2;
};

int peIndex [[ thread_position_in_grid ]]; // New in MSL 3.1

[[ kernel ]] 
void testFunction(constant Uniforms &uniforms, // implicitly [[ buffer(0) ]]
                  constant float *input1, // implicitly [[ buffer(1) ]]
                  constant float *input2, // implicitly [[ buffer(2) ]]
                  device float* outputs // implicitly [[ buffer(3) ]]
) {
  // main compute block
}

You should look at setBytes:length:atIndex: and setBuffer:offset:atIndex: APIs for the host side.

While it's not compute, there's the Using a Render Pipeline to Render Primitives that uses setVertexBytes whose usage is quite similar to the compute equivalent.