This patch adds support for compilation and execution of GLSL compute shaders. This, along with a few systematic changes and fixes, enable realtime compositor functionality with the Metal backend on macOS. A number of GLSL source modifications have been made to add the required level of type explicitness, allowing all compilations to succeed. GLSL Compute shader compilation follows a similar path to Vertex/Fragment translation, with added support for shader atomics, shared memory blocks and barriers. Texture flags have also been updated to ensure correct read/write specification for textures used within the compositor pipeline. GPU command submission changes have also been made in the high level path, when Metal is used, to address command buffer time-outs caused by certain expensive compute shaders. Authored by Apple: Michael Parkin-White Ref T96261 Ref T99210 Reviewed By: fclem Maniphest Tasks: T99210, T96261 Differential Revision: https://developer.blender.org/D16990
129 lines
5.3 KiB
Plaintext
129 lines
5.3 KiB
Plaintext
/* 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<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; \
|
|
}
|