cglm
cglm copied to clipboard
Apple SIMD, Swift and Metal API Support and Helpers
cglm always tries to make things easier and faster. Currently I'm trying to switch my render engine from OpenGL to Metal and other graphics libraries by writing a GPU library (https://github.com/recp/gpu), it will be documented after first release...
cglm offers two APIs
- Array API which makes parameters easier to pass it, also easy to load CPU register
- Struct API which provides type safety and other maybe
A few things I would like to see in cglm
- Helpers to pass cglm types or values to Apple's platform or types.
- Make cglm work better with Swift language, struct API will help a lot here, I think.
- Make cglm work better with Metal API
- todo?
cglm already provides applesimd.h header and it contains helpers to convert cglm types to Apple's simd types.
But there may bee another option:
Now let's see Apple's tempale Metal project, see ShaderTypes.h:
typedef struct
{
matrix_float4x4 projectionMatrix;
matrix_float4x4 modelViewMatrix;
} Uniforms;
This is how I passed cglm values to Metal API:
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
mat4 proj;
if (!uniforms)
return;
glm_perspective(glm_rad(65.0f),
size.width / size.height,
0.1f,
100.0f,
proj);
uniforms->projectionMatrix = glm_mat4_applesimd(proj);
}
As you can see it contains extra copy (it may be fast). We can reduce the copy with this way maybe if this is not undefined behavior or similar:
/* common.h */
#if defined(__APPLE__) \
&& defined(SIMD_COMPILER_HAS_REQUIRED_FEATURES) \
&& defined(SIMD_BASE) \
&& defined(SIMD_TYPES) \
&& defined(SIMD_VECTOR_TYPES)
# define CGLM_APPLE_SIMD
#endif
/* types-struct.h */
typedef union CGLM_ALIGN_MAT mat4s {
mat4 raw;
vec4s col[4];
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
float m00, m01, m02, m03;
float m10, m11, m12, m13;
float m20, m21, m22, m23;
float m30, m31, m32, m33;
};
#endif
/* this could be magic ??? */
#ifdef CGLM_APPLE_SIMD
simd_float4x4 apple;
#endif
} mat4s;
/* repeat for other types */
as you can see it adds a variable called apple to union. If this won't break anything e.g. C spec or clang... then everything will be easier, let's see how (compare with above example):
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
if (!uniforms)
return;
uniforms->projectionMatrix = glms_perspective(glm_rad(65.0f),
size.width / size.height,
0.1f,
100.0f).apple;
}
it converts cglm to Apple's simd directly and it reduces extra copy (glm_mat4_applesimd() ) and it reduces to define mat4 variable...
We are not including Apple's headers to cglm, we are testing a few macro to check if the header was included before cglm, so it should not break anything on Windows or on other platforms
Feedbacks? We can choose a better name than .apple but it indicates the purpose
EDIT: cglm may have different alignment, so this may cause troubles but not sure