From 19c793af35ea8e694c16995d115d7c9247fee81a Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 22 Mar 2022 12:44:26 +0100 Subject: Metal: Make GLSL shader source MSL compliant also Metal shading language follows the C++ 14 standard and in some cases requires a greater level of explicitness than GLSL. There are also some small language differences: - Explicit type-casts (C++ requirements) - Explicit constant values (C++ requirements, e.g. floating point values using 0.0 instead of 0). - Metal/OpenGL compatibility paths - GLSL Function prototypes - Explicit accessors for vector types when sampling textures. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D14378 --- .../eevee/shaders/closure_eval_glossy_lib.glsl | 3 +++ .../engines/eevee/shaders/closure_type_lib.glsl | 2 ++ .../engines/eevee/shaders/effect_bloom_frag.glsl | 2 +- .../eevee/shaders/effect_dof_resolve_frag.glsl | 2 +- .../eevee/shaders/effect_dof_scatter_vert.glsl | 2 +- .../eevee/shaders/effect_dof_setup_frag.glsl | 8 +++---- .../engines/eevee/shaders/effect_minmaxz_frag.glsl | 9 ++++++-- .../shaders/effect_reflection_trace_frag.glsl | 4 ++-- .../eevee/shaders/effect_velocity_tile_frag.glsl | 2 +- .../draw/engines/eevee/shaders/lightprobe_lib.glsl | 2 +- .../shaders/lightprobe_planar_downsample_frag.glsl | 4 ++-- .../engines/eevee/shaders/volumetric_frag.glsl | 2 +- .../eevee/shaders/volumetric_integration_frag.glsl | 2 +- .../eevee/shaders/volumetric_scatter_frag.glsl | 2 +- .../engines/overlay/shaders/background_frag.glsl | 4 ++-- .../overlay/shaders/outline_detect_frag.glsl | 2 +- .../overlay/shaders/volume_gridlines_vert.glsl | 2 +- .../shaders/workbench_effect_cavity_frag.glsl | 4 ++-- .../shaders/workbench_merge_infront_frag.glsl | 2 +- .../workbench_transparent_resolve_frag.glsl | 4 ++-- .../workbench/shaders/workbench_volume_frag.glsl | 2 +- .../draw/intern/shaders/common_hair_lib.glsl | 4 ++-- .../draw/intern/shaders/common_math_geom_lib.glsl | 2 +- .../draw/intern/shaders/common_math_lib.glsl | 6 ++--- .../draw/intern/shaders/common_view_lib.glsl | 4 ++-- source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/intern/gpu_shader.cc | 10 ++++++++ source/blender/gpu/opengl/gl_shader.cc | 7 +++++- .../gpu_shader_2D_image_multi_rect_vert.glsl | 6 ++--- .../gpu/shaders/gpu_shader_2D_image_rect_vert.glsl | 27 ++++++++++++++++++++++ .../shaders/gpu_shader_2D_widget_base_vert.glsl | 2 +- .../gpu_shader_image_overlays_merge_frag.glsl | 6 ++--- .../shaders/gpu_shader_keyframe_shape_vert.glsl | 2 +- .../blender/gpu/shaders/gpu_shader_text_frag.glsl | 4 ++-- .../blender/gpu/shaders/gpu_shader_text_vert.glsl | 2 +- .../gpu_shader_material_light_falloff.glsl | 4 ++-- .../gpu/shaders/opengl/glsl_shader_defines.glsl | 17 ++++++++++++++ 37 files changed, 120 insertions(+), 50 deletions(-) create mode 100644 source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl index 584aacc9e19..ddc6a0b9661 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl @@ -26,10 +26,13 @@ struct ClosureEvalGlossy { #ifdef STEP_RESOLVE /* SSR */ /* Prototype. */ +# ifndef GPU_METAL +/* MSL does not require prototypes. */ void raytrace_resolve(ClosureInputGlossy cl_in, inout ClosureEvalGlossy cl_eval, inout ClosureEvalCommon cl_common, inout ClosureOutputGlossy cl_out); +# endif #endif ClosureEvalGlossy closure_Glossy_eval_init(inout ClosureInputGlossy cl_in, diff --git a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl index f66f45635f4..fefc8743691 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl @@ -32,8 +32,10 @@ struct Closure { #endif }; +#ifndef GPU_METAL /* Prototype */ Closure nodetree_exec(void); +#endif /* clang-format off */ /* Avoid multi-line defines. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl index 9d9d7beb3cb..bdcc0a2ba93 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl @@ -150,7 +150,7 @@ vec4 step_blit(void) float br = max_v3(m); /* Under-threshold part: quadratic curve */ - float rq = clamp(br - curveThreshold.x, 0, curveThreshold.y); + float rq = clamp(br - curveThreshold.x, 0.0, curveThreshold.y); rq = curveThreshold.z * rq * rq; /* Combine and apply the brightness response curve. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl index 57027c71156..688ae4915e1 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_resolve_frag.glsl @@ -142,7 +142,7 @@ void dof_resolve_load_layer(sampler2D color_tex, out float out_weight) { vec2 pixel_co = gl_FragCoord.xy / 2.0; - vec2 uv = pixel_co / textureSize(color_tex, 0).xy; + vec2 uv = pixel_co / vec2(textureSize(color_tex, 0).xy); out_color = textureLod(color_tex, uv, 0.0); out_weight = textureLod(weight_tex, uv, 0.0).r; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl index b05223e755d..51a351babd3 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl @@ -95,7 +95,7 @@ void main() weights = dof_layer_weight(cocs) * dof_sample_weight(cocs); /* Filter NaNs. */ - weights = mix(weights, vec4(0.0), equal(cocs, vec4(0.0))); + weights = select(weights, vec4(0.0), equal(cocs, vec4(0.0))); color1 = colors[0] * weights[0]; color2 = colors[1] * weights[1]; diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl index 235145b221b..178ef46862b 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl @@ -54,12 +54,12 @@ void main() bvec4 focus = lessThanEqual(cocs, vec4(0.5)); if (any(defocus) && any(focus)) { /* For the same reason as in the flatten pass. This is a case we cannot optimize for. */ - cocs = mix(cocs, vec4(DOF_TILE_MIXED), focus); - cocs = mix(cocs, vec4(DOF_TILE_MIXED), defocus); + cocs = select(cocs, vec4(DOF_TILE_MIXED), focus); + cocs = select(cocs, vec4(DOF_TILE_MIXED), defocus); } else { - cocs = mix(cocs, vec4(DOF_TILE_FOCUS), focus); - cocs = mix(cocs, vec4(DOF_TILE_DEFOCUS), defocus); + cocs = select(cocs, vec4(DOF_TILE_FOCUS), focus); + cocs = select(cocs, vec4(DOF_TILE_DEFOCUS), defocus); } outCoc.y = max_v4(cocs); } diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index ce455123987..aaf673eecd2 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -38,7 +38,7 @@ uniform vec2 texelSize; /* On some AMD card / driver combination, it is needed otherwise, * the shader does not write anything. */ -#if defined(GPU_INTEL) || defined(GPU_ATI) +#if (defined(GPU_INTEL) || defined(GPU_ATI)) && defined(GPU_OPENGL) out vec4 fragColor; #endif @@ -68,9 +68,14 @@ void main() float val = minmax4(samp.x, samp.y, samp.z, samp.w); #endif -#if defined(GPU_INTEL) || defined(GPU_ATI) +#if (defined(GPU_INTEL) || defined(GPU_ATI)) && defined(GPU_OPENGL) /* Use color format instead of 24bit depth texture */ fragColor = vec4(val); #endif + +#if !(defined(GPU_INTEL) && defined(GPU_OPENGL)) + /* If using Intel workaround, do not write out depth as there will be no depth target and this is + * invalid. */ gl_FragDepth = val; +#endif } diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl index f4ff28eaee4..c9010749060 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl @@ -60,11 +60,11 @@ void main() vec3 P = transform_point(ViewMatrixInverse, vP); vec3 vV = viewCameraVec(vP); vec3 V = cameraVec(P); - vec3 vN = normal_decode(texture(normalBuffer, uvs, 0).rg, vV); + vec3 vN = normal_decode(textureLod(normalBuffer, uvs, 0.0).rg, vV); vec3 N = transform_direction(ViewMatrixInverse, vN); /* Retrieve pixel data */ - vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; + vec4 speccol_roughness = textureLod(specroughBuffer, uvs, 0.0).rgba; /* Early out */ if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl index 300477570d0..fc8091161d7 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl @@ -74,7 +74,7 @@ bool neighbor_affect_this_tile(ivec2 offset, vec2 velocity) * offset. If the offset coordinate is zero then * velocity is irrelevant. */ - vec2 point = sign(offset * velocity); + vec2 point = sign(vec2(offset) * velocity); float dist = (point.x + point.y); /** diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 84626eac4cf..e1035af37be 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -289,7 +289,7 @@ vec3 probe_evaluate_grid(GridData gd, vec3 P, vec3 N, vec3 localpos) weight += prbIrradianceSmooth; /* Trilinear weights */ - vec3 trilinear = mix(1.0 - trilinear_weight, trilinear_weight, offset); + vec3 trilinear = mix(1.0 - trilinear_weight, trilinear_weight, vec3(offset)); weight *= trilinear.x * trilinear.y * trilinear.z; /* Avoid zero weight */ diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl index cf44a04b707..5674e464f4c 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl @@ -16,11 +16,11 @@ void main() { #if 0 /* Reconstructing Target uvs like this avoid missing pixels if NPO2 */ - vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0)); + vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0).xy); FragColor = textureLod(source, vec3(uvs, layer), 0.0); #else - vec2 texel_size = 1.0 / vec2(textureSize(source, 0)); + vec2 texel_size = 1.0 / vec2(textureSize(source, 0).xy); vec2 uvs = gl_FragCoord.xy * 2.0 * texel_size; vec4 ofs = texel_size.xyxy * vec4(0.75, 0.75, -0.75, -0.75); diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl index 25661a0d731..9f1afc4767c 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl @@ -31,7 +31,7 @@ layout(location = 3) out vec4 volumePhase; void main() { - ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice); + ivec3 volume_cell = ivec3(ivec2(gl_FragCoord.xy), slice); vec3 ndc_cell = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz); viewPosition = get_view_space_from_depth(ndc_cell.xy, ndc_cell.z); diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl index 12b7d8acbea..11f57c0a82e 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl @@ -52,7 +52,7 @@ void main() ivec2 texco = ivec2(gl_FragCoord.xy); #endif for (int i = 0; i <= slice; i++) { - ivec3 volume_cell = ivec3(gl_FragCoord.xy, i); + ivec3 volume_cell = ivec3(ivec2(gl_FragCoord.xy), i); vec3 Lscat = texelFetch(volumeScattering, volume_cell, 0).rgb; vec3 s_extinction = texelFetch(volumeExtinction, volume_cell, 0).rgb; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl index dc755aeab8b..df3f92966e6 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl @@ -22,7 +22,7 @@ layout(location = 1) out vec4 outTransmittance; void main() { - ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice); + ivec3 volume_cell = ivec3(ivec2(gl_FragCoord.xy), slice); /* Emission */ outScattering = texelFetch(volumeEmission, volume_cell, 0); diff --git a/source/blender/draw/engines/overlay/shaders/background_frag.glsl b/source/blender/draw/engines/overlay/shaders/background_frag.glsl index 52052d414f8..19313c0415b 100644 --- a/source/blender/draw/engines/overlay/shaders/background_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/background_frag.glsl @@ -38,8 +38,8 @@ void main() * This removes the alpha channel and put the background behind reference images * while masking the reference images by the render alpha. */ - float alpha = texture(colorBuffer, uvcoordsvar.st).a; - float depth = texture(depthBuffer, uvcoordsvar.st).r; + float alpha = texture(colorBuffer, uvcoordsvar.xy).a; + float depth = texture(depthBuffer, uvcoordsvar.xy).r; vec3 bg_col; vec3 col_high; diff --git a/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl b/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl index 0e4757f8ea8..19d54a57479 100644 --- a/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/outline_detect_frag.glsl @@ -169,7 +169,7 @@ void diag_dir(bvec4 edges1, bvec4 edges2, out vec2 line_start, out vec2 line_end void main() { - uint ref = textureLod(outlineId, uvcoordsvar.st, 0.0).r; + uint ref = textureLod(outlineId, uvcoordsvar.xy, 0.0).r; uint ref_col = ref; vec2 uvs = gl_FragCoord.xy * sizeViewportInv.xy; diff --git a/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl b/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl index f714646fe40..507beb8a418 100644 --- a/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/volume_gridlines_vert.glsl @@ -53,7 +53,7 @@ vec4 flag_to_color(uint flag) if (bool(flag & uint(16))) { color.rgb += vec3(0.9, 0.3, 0.0); /* orange */ } - if (color.rgb == vec3(0.0)) { + if (is_zero(color.rgb)) { color.rgb += vec3(0.5, 0.0, 0.0); /* medium red */ } return color; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_cavity_frag.glsl index 59222b588a0..7704e7ed0b7 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_cavity_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_cavity_frag.glsl @@ -9,11 +9,11 @@ void main() float cavity = 0.0, edges = 0.0, curvature = 0.0; #ifdef USE_CAVITY - cavity_compute(uvcoordsvar.st, depthBuffer, normalBuffer, cavity, edges); + cavity_compute(uvcoordsvar.xy, depthBuffer, normalBuffer, cavity, edges); #endif #ifdef USE_CURVATURE - curvature_compute(uvcoordsvar.st, objectIdBuffer, normalBuffer, curvature); + curvature_compute(uvcoordsvar.xy, objectIdBuffer, normalBuffer, curvature); #endif float final_cavity_factor = clamp((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl index ae564435258..30daca6b7e3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_merge_infront_frag.glsl @@ -1,7 +1,7 @@ void main() { - float depth = texture(depthBuffer, uvcoordsvar.st).r; + float depth = texture(depthBuffer, uvcoordsvar.xy).r; /* Fix issues with Intel drivers (see T80023). */ fragColor = vec4(0.0); /* Discard background pixels. */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_resolve_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_resolve_frag.glsl index a2c45d2f8e3..35bea830bac 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_resolve_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_resolve_frag.glsl @@ -9,8 +9,8 @@ void main() /* Revealage is actually stored in transparentAccum alpha channel. * This is a workaround to older hardware not having separate blend equation per render target. */ - vec4 trans_accum = texture(transparentAccum, uvcoordsvar.st); - float trans_weight = texture(transparentRevealage, uvcoordsvar.st).r; + vec4 trans_accum = texture(transparentAccum, uvcoordsvar.xy); + float trans_weight = texture(transparentRevealage, uvcoordsvar.xy).r; float trans_reveal = trans_accum.a; /* Listing 4 */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index 076f6e80104..4ff281ccd29 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -94,7 +94,7 @@ vec4 flag_to_color(uint flag) if (bool(flag & uint(16))) { color.rgb += vec3(0.9, 0.3, 0.0); /* orange */ } - if (color.rgb == vec3(0.0)) { + if (is_zero(color.rgb)) { color.rgb += vec3(0.5, 0.0, 0.0); /* medium red */ } return color; diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index ed8b8aeb849..7f94b7ea1c1 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -158,7 +158,7 @@ float hair_shaperadius(float shape, float root, float tip, float time) return (radius * (root - tip)) + tip; } -# ifdef OS_MAC +# if defined(OS_MAC) && defined(GPU_OPENGL) in float dummy; # endif @@ -178,7 +178,7 @@ void hair_get_pos_tan_binor_time(bool is_persp, wpos = data.point_position; time = data.point_time; -# ifdef OS_MAC +# if defined(OS_MAC) && defined(GPU_OPENGL) /* Generate a dummy read to avoid the driver bug with shaders having no * vertex reads on macOS (T60171) */ wpos.y += dummy * 0.0; diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl index 7b701d1d81b..6d4452c18c8 100644 --- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl @@ -86,7 +86,7 @@ float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) float line_unit_box_intersect_dist_safe(vec3 lineorigin, vec3 linedirection) { vec3 safe_linedirection = max(vec3(1e-8), abs(linedirection)) * - mix(vec3(1.0), -vec3(1.0), lessThan(linedirection, vec3(0.0))); + select(vec3(1.0), -vec3(1.0), lessThan(linedirection, vec3(0.0))); return line_unit_box_intersect_dist(lineorigin, safe_linedirection); } diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl index 1701056cbb7..4d0ffaeb40f 100644 --- a/source/blender/draw/intern/shaders/common_math_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_lib.glsl @@ -84,9 +84,9 @@ float avg(vec3 v) { return dot(vec3(1.0 / 3.0), v); } float avg(vec4 v) { return dot(vec4(1.0 / 4.0), v); } float safe_rcp(float a) { return (a != 0.0) ? (1.0 / a) : 0.0; } -vec2 safe_rcp(vec2 a) { return mix(vec2(0.0), (1.0 / a), notEqual(a, vec2(0.0))); } -vec3 safe_rcp(vec3 a) { return mix(vec3(0.0), (1.0 / a), notEqual(a, vec3(0.0))); } -vec4 safe_rcp(vec4 a) { return mix(vec4(0.0), (1.0 / a), notEqual(a, vec4(0.0))); } +vec2 safe_rcp(vec2 a) { return select(vec2(0.0), (1.0 / a), notEqual(a, vec2(0.0))); } +vec3 safe_rcp(vec3 a) { return select(vec3(0.0), (1.0 / a), notEqual(a, vec3(0.0))); } +vec4 safe_rcp(vec4 a) { return select(vec4(0.0), (1.0 / a), notEqual(a, vec4(0.0))); } float safe_sqrt(float a) { return sqrt(max(a, 0.0)); } diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index 2ac157ad208..6c58752c8bb 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -174,7 +174,7 @@ flat in int resourceIDFrag; /* Breaking this across multiple lines causes issues for some older GLSL compilers. */ /* clang-format off */ -#if !defined(GPU_INTEL) && !defined(GPU_DEPRECATED_AMD_DRIVER) && !defined(OS_MAC) && !defined(INSTANCED_ATTR) && !defined(DRW_LEGACY_MODEL_MATRIX) +#if !defined(GPU_INTEL) && !defined(GPU_DEPRECATED_AMD_DRIVER) && (!defined(OS_MAC) || defined(GPU_METAL)) && !defined(INSTANCED_ATTR) && !defined(DRW_LEGACY_MODEL_MATRIX) /* clang-format on */ /* Temporary until we fully make the switch. */ @@ -251,7 +251,7 @@ uniform mat4 ModelMatrixInverse; /* Due to some shader compiler bug, we somewhat need to access gl_VertexID * to make vertex shaders work. even if it's actually dead code. */ -#ifdef GPU_INTEL +#if defined(GPU_INTEL) && defined(GPU_OPENGL) # define GPU_INTEL_VERTEX_SHADER_WORKAROUND gl_Position.x = float(gl_VertexID); #else # define GPU_INTEL_VERTEX_SHADER_WORKAROUND diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 6c795aba560..c28b51de8ac 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -210,6 +210,7 @@ endif() set(GLSL_SRC GPU_shader_shared.h + shaders/opengl/glsl_shader_defines.glsl shaders/gpu_shader_depth_only_frag.glsl shaders/gpu_shader_uniform_color_frag.glsl diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index ac8e98a4a21..b434cfbbb0e 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -88,6 +88,16 @@ static void standard_defines(Vector &sources) else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) { sources.append("#define OS_UNIX\n"); } + /* API Definition */ + eGPUBackendType backend = GPU_backend_get_type(); + switch (backend) { + case GPU_BACKEND_OPENGL: + sources.append("#define GPU_OPENGL\n"); + break; + default: + BLI_assert(false && "Invalid GPU Backend Type"); + break; + } if (GPU_crappy_amd_driver()) { sources.append("#define GPU_DEPRECATED_AMD_DRIVER\n"); diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index c0182306047..c76e21f9f71 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -24,6 +24,8 @@ using namespace blender; using namespace blender::gpu; using namespace blender::gpu::shader; +extern char datatoc_glsl_shader_defines_glsl[]; + /* -------------------------------------------------------------------- */ /** \name Creation / Destruction * \{ */ @@ -760,7 +762,7 @@ bool GLShader::do_geometry_shader_injection(const shader::ShaderCreateInfo *info static char *glsl_patch_default_get() { /** Used for shader patching. Init once. */ - static char patch[1024] = "\0"; + static char patch[2048] = "\0"; if (patch[0] != '\0') { return patch; } @@ -827,6 +829,9 @@ static char *glsl_patch_default_get() STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", GLContext::derivative_signs[0]); STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", GLContext::derivative_signs[1]); + /* GLSL Backend Lib. */ + STR_CONCAT(patch, slen, datatoc_glsl_shader_defines_glsl); + BLI_assert(slen < sizeof(patch)); return patch; } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl index 9851e08fe2e..353bf1481da 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_image_multi_rect_vert.glsl @@ -23,15 +23,15 @@ void main() /* Use pos to select the right swizzle (instead of gl_VertexID) * in order to workaround an OSX driver bug. */ - if (pos == vec2(0.0, 0.0)) { + if (all(equal(pos, vec2(0.0, 0.0)))) { rect.xy = rect.xz; tex.xy = tex.xz; } - else if (pos == vec2(0.0, 1.0)) { + else if (all(equal(pos, vec2(0.0, 1.0)))) { rect.xy = rect.xw; tex.xy = tex.xw; } - else if (pos == vec2(1.0, 1.0)) { + else if (all(equal(pos, vec2(1.0, 1.0)))) { rect.xy = rect.yw; tex.xy = tex.yw; } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl index d9a5aeeef46..903c602c5d6 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_image_rect_vert.glsl @@ -15,6 +15,32 @@ void main() { vec2 uv; vec2 co; + +#ifdef GPU_METAL +/* Metal API does not support Triangle fan primitive topology. + * When this shader is called using Triangle-Strip, vertex ID's + * are in a different order. */ +# define GPU_PRIM_TRI_STRIP +#endif + +#ifdef GPU_PRIM_TRI_STRIP + if (gl_VertexID == 0) { + co = rect_geom.xw; + uv = rect_icon.xw; + } + else if (gl_VertexID == 1) { + co = rect_geom.xy; + uv = rect_icon.xy; + } + else if (gl_VertexID == 2) { + co = rect_geom.zw; + uv = rect_icon.zw; + } + else { + co = rect_geom.zy; + uv = rect_icon.zy; + } +#else if (gl_VertexID == 0) { co = rect_geom.xy; uv = rect_icon.xy; @@ -31,6 +57,7 @@ void main() co = rect_geom.zy; uv = rect_icon.zy; } +#endif gl_Position = ModelViewProjectionMatrix * vec4(co, 0.0f, 1.0f); texCoord_interp = uv; diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl index 80b93baf20a..3a39cd8b847 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -53,7 +53,7 @@ flat out float lineWidth; noperspective out float butCo; flat out float discardFac; -# ifdef OS_MAC +# if defined(OS_MAC) && defined(GPU_OPENGL) in float dummy; # endif #endif diff --git a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl index 2314dbbc5d5..aa182eb52be 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl @@ -32,9 +32,9 @@ void linearrgb_to_srgb(vec4 col_from, out vec4 col_to) void main() { - fragColor = texture(image_texture, texCoord_interp.st); - vec4 overlay_col = texture(overlays_texture, texCoord_interp.st); - + fragColor = texture(image_texture, texCoord_interp.xy); + vec4 overlay_col = texture(overlays_texture, texCoord_interp.xy); + if (overlay) { fragColor = clamp(fragColor, 0.0, 1.0); fragColor *= 1.0 - overlay_col.a; diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl index 4ef3ff1a8d0..617c02ac079 100644 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_vert.glsl @@ -43,7 +43,7 @@ bool test(int bit) vec2 line_thresholds(float width) { - return vec2(max(0, width - line_falloff), width); + return vec2(max(0.0, width - line_falloff), width); } void main() diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl index c339d3cbabb..f958a81b1eb 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl @@ -52,7 +52,7 @@ bool is_inside_box(ivec2 v) float texture_1D_custom_bilinear_filter(vec2 uv) { - vec2 texel_2d = uv * glyph_dim + 0.5; + vec2 texel_2d = uv * vec2(glyph_dim) + vec2(0.5); ivec2 texel_2d_near = ivec2(texel_2d) - 1; int frag_offset = glyph_offset + texel_2d_near.y * glyph_dim.x + texel_2d_near.x; @@ -100,7 +100,7 @@ void main() fragColor.a = texture_1D_custom_bilinear_filter(texCoord_interp); } else { - vec2 texel = 1.0 / glyph_dim; + vec2 texel = 1.0 / vec2(glyph_dim); fragColor.a = 0.0; if (interp_size == 1) { diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl index 5b01fea5266..4221e426a3e 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl @@ -29,7 +29,7 @@ void main() texCoord_interp = mix(-interp_offset, 1.0 + interp_offset, quad); vec2 final_pos = mix( - pos.xy + ivec2(-interp_size, interp_size), pos.zw + ivec2(interp_size, -interp_size), quad); + vec2(ivec2(pos.xy) + ivec2(-interp_size, interp_size)), vec2(ivec2(pos.zw) + ivec2(interp_size, -interp_size)), quad); gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 0.0, 1.0); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_light_falloff.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_light_falloff.glsl index f3eae653f95..e1c7a00646f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_light_falloff.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_light_falloff.glsl @@ -1,7 +1,7 @@ void node_light_falloff( - float strength, float tsmooth, out float quadratic, out float linear, out float constant) + float strength, float tsmooth, out float quadratic, out float linear, out float falloff_constant) { quadratic = strength; linear = strength; - constant = strength; + falloff_constant = strength; } diff --git a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl new file mode 100644 index 00000000000..a5fce2e71c3 --- /dev/null +++ b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl @@ -0,0 +1,17 @@ +/* Backend Functions. */ +#define select(A, B, mask) mix(A, B, mask) + +bool is_zero(vec2 A) +{ + return all(equal(A, vec2(0.0))); +} + +bool is_zero(vec3 A) +{ + return all(equal(A, vec3(0.0))); +} + +bool is_zero(vec4 A) +{ + return all(equal(A, vec4(0.0))); +} -- cgit v1.2.3