diff options
Diffstat (limited to 'source/blender/gpu/shaders/metal/mtl_shader_common.msl')
-rw-r--r-- | source/blender/gpu/shaders/metal/mtl_shader_common.msl | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/source/blender/gpu/shaders/metal/mtl_shader_common.msl b/source/blender/gpu/shaders/metal/mtl_shader_common.msl new file mode 100644 index 00000000000..c504cdbacb1 --- /dev/null +++ b/source/blender/gpu/shaders/metal/mtl_shader_common.msl @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* Common Metal header to be included in all compiled Metal shaders. + * Both native MSL shaders and GLSL shaders. */ + +using namespace metal; + +/* Should match GPUVertFetchMode. */ +typedef enum { + GPU_FETCH_FLOAT = 0, + GPU_FETCH_INT, + GPU_FETCH_INT_TO_FLOAT_UNIT, + GPU_FETCH_INT_TO_FLOAT, +} GPUVertFetchMode; + +/* Consant to flag base binding index of uniform buffers. */ +constant int MTL_uniform_buffer_base_index [[function_constant(0)]]; + +/* Default Point Size. + * Unused if function constant not set. */ +constant float MTL_global_pointsize [[function_constant(1)]]; + +/* Attribute conversions flags (Up to 16 attributes supported in Blender). */ +constant int MTL_AttributeConvert0 [[function_constant(2)]]; +constant int MTL_AttributeConvert1 [[function_constant(3)]]; +constant int MTL_AttributeConvert2 [[function_constant(4)]]; +constant int MTL_AttributeConvert3 [[function_constant(5)]]; +constant int MTL_AttributeConvert4 [[function_constant(6)]]; +constant int MTL_AttributeConvert5 [[function_constant(7)]]; +constant int MTL_AttributeConvert6 [[function_constant(8)]]; +constant int MTL_AttributeConvert7 [[function_constant(9)]]; +constant int MTL_AttributeConvert8 [[function_constant(10)]]; +constant int MTL_AttributeConvert9 [[function_constant(11)]]; +constant int MTL_AttributeConvert10 [[function_constant(12)]]; +constant int MTL_AttributeConvert11 [[function_constant(13)]]; +constant int MTL_AttributeConvert12 [[function_constant(14)]]; +constant int MTL_AttributeConvert13 [[function_constant(15)]]; +constant int MTL_AttributeConvert14 [[function_constant(16)]]; +constant int MTL_AttributeConvert15 [[function_constant(17)]]; + +/* Consant to flag binding index of transform feedback buffer. + * Unused if function constant not set. */ +constant int MTL_transform_feedback_buffer_index [[function_constant(18)]]; + +/** Internal attribute conversion functionality. */ +/* Following descriptions in mtl_shader.hh, Metal only supports some implicit + * attribute type conversions. These conversions occur when there is a difference + * between the type specified in the vertex descriptor (In the input vertex buffers), + * and the attribute type in the shader's VertexIn struct (ShaderInterface). + * + * The supported implicit conversions are described here: + * https://developer.apple.com/documentation/metal/mtlvertexattributedescriptor/1516081-format?language=objc + * + * For unsupported conversions, the mtl_shader_generator will create an attribute reading function + * which performs this conversion manually upon read, depending on the requested fetchmode. + * + * These conversions use the function constants above, so any branching is optimized out during + * backend shader compilation (PSO creation). + * + * NOTE: Not all possibilities have been covered here, any additional conversion routines should + * be added as needed, and mtl_shader_generator should also be updated with any newly required + * read functions. + * + * These paths are only needed for cases where implicit conversion will not happen, in which + * case the value will be read as the type in the shader. + */ +#define internal_vertex_attribute_convert_read_float(ATTR, v_in, v_out) \ + if (ATTR == GPU_FETCH_INT_TO_FLOAT) { \ + v_out = float(as_type<int>(v_in)); \ + } \ + else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ + v_out = float(as_type<int>(v_in)) / float(__INT_MAX__); \ + } \ + else { \ + v_out = v_in; \ + } + +#define internal_vertex_attribute_convert_read_float2(ATTR, v_in, v_out) \ + if (ATTR == GPU_FETCH_INT_TO_FLOAT) { \ + v_out = float2(as_type<int2>(v_in)); \ + } \ + else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ + v_out = float2(as_type<int2>(v_in)) / float2(__INT_MAX__); \ + } \ + else { \ + v_out = v_in; \ + } + +#define internal_vertex_attribute_convert_read_float3(ATTR, v_in, v_out) \ + if (ATTR == GPU_FETCH_INT_TO_FLOAT) { \ + v_out = float3(as_type<int3>(v_in)); \ + } \ + else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ + v_out = float3(as_type<int3>(v_in)) / float3(__INT_MAX__); \ + } \ + else { \ + v_out = v_in; \ + } + +#define internal_vertex_attribute_convert_read_float4(ATTR, v_in, v_out) \ + if (ATTR == GPU_FETCH_INT_TO_FLOAT) { \ + v_out = float4(as_type<int4>(v_in)); \ + } \ + else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ + v_out = float4(as_type<int4>(v_in)) / float4(__INT_MAX__); \ + } \ + else { \ + v_out = v_in; \ + } |