/* 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)]]; /** Clip distance enablement. */ /* General toggle to control whether any clipping distanes are written at all. * This is an optimization to avoid having the clipping distance shader output * paramter if it is not needed. */ constant int MTL_clip_distances_enabled [[function_constant(19)]]; /* If clipping planes are enabled at all, then we require an enablement * flag per clipping plane. If enabled, then gl_ClipDistances[N] will * control clipping for a given plane, otherwise the value is ignored. */ constant int MTL_clip_distance_enabled0 [[function_constant(20)]]; constant int MTL_clip_distance_enabled1 [[function_constant(21)]]; constant int MTL_clip_distance_enabled2 [[function_constant(22)]]; constant int MTL_clip_distance_enabled3 [[function_constant(23)]]; constant int MTL_clip_distance_enabled4 [[function_constant(24)]]; constant int MTL_clip_distance_enabled5 [[function_constant(25)]]; /* Compute and SSBOs. */ constant int MTL_storage_buffer_base_index [[function_constant(26)]]; /** 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(v_in)); \ } \ else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ v_out = float(as_type(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(v_in)); \ } \ else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ v_out = float2(as_type(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(v_in)); \ } \ else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ v_out = float3(as_type(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(v_in)); \ } \ else if (ATTR == GPU_FETCH_INT_TO_FLOAT_UNIT) { \ v_out = float4(as_type(v_in)) / float4(__INT_MAX__); \ } \ else { \ v_out = v_in; \ }