[Bf-blender-cvs] [b3464fe152c] master: Metal: Implement suppot for clip plane toggling via GPU_clip_distances.
Jason Fielder
noreply at git.blender.org
Tue Dec 20 14:17:16 CET 2022
Commit: b3464fe152ca8a7b50dddf0774e33d24e38fd6b5
Author: Jason Fielder
Date: Tue Dec 20 14:15:52 2022 +0100
Branches: master
https://developer.blender.org/rBb3464fe152ca8a7b50dddf0774e33d24e38fd6b5
Metal: Implement suppot for clip plane toggling via GPU_clip_distances.
The Metal backend already supports output for the 6 clipping planes via gl_ClipDistances equivalent, however, functionality to toggle clipping plane enablement was missing.
Authored by Apple: Michael Parkin-White
Ref T96261
Depends on D16777
Reviewed By: fclem
Maniphest Tasks: T96261
Differential Revision: https://developer.blender.org/D16813
===================================================================
M source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh
M source/blender/gpu/metal/mtl_context.hh
M source/blender/gpu/metal/mtl_pso_descriptor_state.hh
M source/blender/gpu/metal/mtl_shader.mm
M source/blender/gpu/metal/mtl_shader_generator.mm
M source/blender/gpu/metal/mtl_state.hh
M source/blender/gpu/metal/mtl_state.mm
M source/blender/gpu/shaders/metal/mtl_shader_common.msl
===================================================================
diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh
index 2d1671ac98d..dd848d6fef9 100644
--- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh
+++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh
@@ -59,7 +59,9 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_material_surface_vert_common)
.additional_info("eevee_legacy_material_empty_base")
.additional_info("draw_resource_id_varying")
.additional_info("eevee_legacy_common_utiltex_lib")
- .additional_info("eevee_legacy_closure_eval_surface_lib");
+ .additional_info("eevee_legacy_closure_eval_surface_lib")
+ /* Planar reflections assigns to gl_ClipDistance via surface_vert.glsl. */
+ .define("USE_CLIP_PLANES");
GPU_SHADER_CREATE_INFO(eevee_legacy_material_surface_vert)
.additional_info("eevee_legacy_material_surface_vert_common")
diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh
index 3656fbdcd19..a26e31aadde 100644
--- a/source/blender/gpu/metal/mtl_context.hh
+++ b/source/blender/gpu/metal/mtl_context.hh
@@ -460,6 +460,9 @@ struct MTLContextGlobalShaderPipelineState {
/* Render parameters. */
float point_size = 1.0f;
float line_width = 1.0f;
+
+ /* Clipping plane enablement. */
+ bool clip_distance_enabled[6] = {false};
};
/* Command Buffer Manager - Owned by MTLContext.
diff --git a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
index 8b0d69c6251..1890f6e8ccd 100644
--- a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
+++ b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh
@@ -174,6 +174,9 @@ struct MTLRenderPipelineStateDescriptor {
/* Global color write mask as this cannot be specified per attachment. */
MTLColorWriteMask color_write_mask;
+ /* Clip distance enablement. */
+ uchar clipping_plane_enable_mask = 0;
+
/* Point size required by point primitives. */
float point_size = 0.0f;
@@ -184,6 +187,10 @@ struct MTLRenderPipelineStateDescriptor {
return false;
}
+ if (clipping_plane_enable_mask != other.clipping_plane_enable_mask) {
+ return false;
+ }
+
if ((num_color_attachments != other.num_color_attachments) ||
(depth_attachment_format != other.depth_attachment_format) ||
(stencil_attachment_format != other.stencil_attachment_format) ||
@@ -243,6 +250,9 @@ struct MTLRenderPipelineStateDescriptor {
hash |= uint64_t((this->blending_enabled && (this->num_color_attachments > 0)) ? 1 : 0) << 62;
hash ^= uint64_t(this->point_size);
+ /* Clipping plane enablement. */
+ hash ^= uint64_t(clipping_plane_enable_mask) << 20;
+
return hash;
}
diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm
index 747746ea424..496f919d189 100644
--- a/source/blender/gpu/metal/mtl_shader.mm
+++ b/source/blender/gpu/metal/mtl_shader.mm
@@ -654,6 +654,14 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state(
pipeline_descriptor.src_rgb_blend_factor = ctx->pipeline_state.src_rgb_blend_factor;
pipeline_descriptor.point_size = ctx->pipeline_state.point_size;
+ /* Resolve clipping plane enablement. */
+ pipeline_descriptor.clipping_plane_enable_mask = 0;
+ for (const int plane : IndexRange(6)) {
+ pipeline_descriptor.clipping_plane_enable_mask =
+ pipeline_descriptor.clipping_plane_enable_mask |
+ ((ctx->pipeline_state.clip_distance_enabled[plane]) ? (1 << plane) : 0);
+ }
+
/* Primitive Type -- Primitive topology class needs to be specified for layered rendering. */
bool requires_specific_topology_class = uses_mtl_array_index_ ||
prim_type == MTLPrimitiveTopologyClassPoint;
@@ -856,6 +864,29 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state(
withName:@"MTL_transform_feedback_buffer_index"];
}
+ /* Clipping planes. */
+ int MTL_clip_distances_enabled = (pipeline_descriptor.clipping_plane_enable_mask > 0) ? 1 : 0;
+
+ /* Only define specialization constant if planes are required.
+ * We guard clip_planes usage on this flag. */
+ [values setConstantValue:&MTL_clip_distances_enabled
+ type:MTLDataTypeInt
+ withName:@"MTL_clip_distances_enabled"];
+
+ if (MTL_clip_distances_enabled > 0) {
+ /* Assign individual enablement flags. Only define a flag function constant
+ * if it is used. */
+ for (const int plane : IndexRange(6)) {
+ int plane_enabled = ctx->pipeline_state.clip_distance_enabled[plane] ? 1 : 0;
+ if (plane_enabled) {
+ [values
+ setConstantValue:&plane_enabled
+ type:MTLDataTypeInt
+ withName:[NSString stringWithFormat:@"MTL_clip_distance_enabled%d", plane]];
+ }
+ }
+ }
+
/* gl_PointSize constant. */
bool null_pointsize = true;
float MTL_pointsize = pipeline_descriptor.point_size;
diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm
index b8c9a28efbd..b938f3fd228 100644
--- a/source/blender/gpu/metal/mtl_shader_generator.mm
+++ b/source/blender/gpu/metal/mtl_shader_generator.mm
@@ -1876,11 +1876,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh
out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl;
if (this->clip_distances.size() > 1) {
/* Output array of clip distances if specified. */
- out << "\tfloat clipdistance [[clip_distance]] [" << this->clip_distances.size() << "];"
- << std::endl;
+ out << "\tfloat clipdistance [[clip_distance, "
+ "function_constant(MTL_clip_distances_enabled)]] ["
+ << this->clip_distances.size() << "];" << std::endl;
}
else if (this->clip_distances.size() > 0) {
- out << "\tfloat clipdistance [[clip_distance]];" << std::endl;
+ out << "\tfloat clipdistance [[clip_distance, "
+ "function_constant(MTL_clip_distances_enabled)]];"
+ << std::endl;
}
out << "#endif" << std::endl;
}
@@ -2157,18 +2160,24 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population()
<< std::endl;
}
- /* Output clip-distances. */
- out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl;
+ /* Output clip-distances.
+ * Clip distances are only written to if both clipping planes are turned on for the shader,
+ * and the clipping planes are enabled. Enablement is controlled on a per-plane basis
+ * via function constants in the shader pipeline state object (PSO). */
+ out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl
+ << "if(MTL_clip_distances_enabled) {" << std::endl;
if (this->clip_distances.size() > 1) {
for (int cd = 0; cd < this->clip_distances.size(); cd++) {
- out << "\toutput.clipdistance[" << cd << "] = vertex_shader_instance.gl_ClipDistance_" << cd
- << ";" << std::endl;
+ /* Default value when clipping is disabled >= 0.0 to ensure primitive is not clipped. */
+ out << "\toutput.clipdistance[" << cd
+ << "] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd
+ << "))?vertex_shader_instance.gl_ClipDistance_" << cd << ":1.0;" << std::endl;
}
}
else if (this->clip_distances.size() > 0) {
out << "\toutput.clipdistance = vertex_shader_instance.gl_ClipDistance_0;" << std::endl;
}
- out << "#endif" << std::endl;
+ out << "}" << std::endl << "#endif" << std::endl;
/* Populate output vertex variables. */
int output_id = 0;
diff --git a/source/blender/gpu/metal/mtl_state.hh b/source/blender/gpu/metal/mtl_state.hh
index 56114fd313e..bc6c700859d 100644
--- a/source/blender/gpu/metal/mtl_state.hh
+++ b/source/blender/gpu/metal/mtl_state.hh
@@ -80,6 +80,8 @@ class MTLStateManager : public StateManager {
void mtl_depth_range(float near, float far);
void mtl_stencil_mask(uint mask);
void mtl_stencil_set_func(eGPUStencilTest stencil_func, int ref, uint mask);
+ void mtl_clip_plane_enable(uint i);
+ void mtl_clip_plane_disable(uint i);
MEM_CXX_CLASS_ALLOC_FUNCS("MTLStateManager")
};
diff --git a/source/blender/gpu/metal/mtl_state.mm b/source/blender/gpu/metal/mtl_state.mm
index aeb1ec15de3..95b7e5edc7a 100644
--- a/source/blender/gpu/metal/mtl_state.mm
+++ b/source/blender/gpu/metal/mtl_state.mm
@@ -35,6 +35,12 @@ MTLStateManager::MTLStateManager(MTLContext *ctx) : StateManager()
/* Force update using default state. */
current_ = ~state;
current_mutable_ = ~mutable_state;
+
+ /* Clip distances initial mask forces to 0x111, which exceeds
+ * max clip plane count of 6, so limit to ensure all clipping
+ * planes get disabled. */
+ current_.clip_distances = 6;
+
set_state(state);
set_mutable_state(mutable_state);
}
@@ -52,6 +58,7 @@ void MTLStateManager::force_state()
{
/* Little exception for clip distances since they need to keep the old count correct. */
uint32_t clip_distances = current_.clip_distances;
+ BLI_assert(clip_distances <= 6);
current_ = ~this->state;
current_.clip_distances = clip_distances;
current_mutable_ = ~this->mutable_state;
@@ -329,11 +336,32 @@ void MTLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStat
}
}
+void MTLStateManager::mtl_clip_plane_enable(uint i)
+{
+ BLI_assert(context_);
+ MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
+ pipeline_state.clip_distance_enabled[i] = true;
+ pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
+}
+
+void MTLStateManager::mtl_clip_plane_disable(uint i)
+{
+ BLI_assert(context_);
+ MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state;
+ pipeline_state.clip_distance_enabled[i] = false;
+ pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG;
+}
+
void MTLStateManager::set_
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list