|
@@ -1512,6 +1512,14 @@ void CompilerMSL::preprocess_op_codes()
|
|
|
(is_sample_rate() && (active_input_builtins.get(BuiltInFragCoord) ||
|
|
(is_sample_rate() && (active_input_builtins.get(BuiltInFragCoord) ||
|
|
|
(need_subpass_input && !msl_options.use_framebuffer_fetch_subpasses))))
|
|
(need_subpass_input && !msl_options.use_framebuffer_fetch_subpasses))))
|
|
|
needs_sample_id = true;
|
|
needs_sample_id = true;
|
|
|
|
|
+
|
|
|
|
|
+ if (is_intersection_query())
|
|
|
|
|
+ {
|
|
|
|
|
+ add_header_line("#if __METAL_VERSION__ >= 230");
|
|
|
|
|
+ add_header_line("#include <metal_raytracing>");
|
|
|
|
|
+ add_header_line("using namespace metal::raytracing;");
|
|
|
|
|
+ add_header_line("#endif");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Move the Private and Workgroup global variables to the entry function.
|
|
// Move the Private and Workgroup global variables to the entry function.
|
|
@@ -8142,7 +8150,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
expr += "(";
|
|
expr += "(";
|
|
|
for (uint32_t col = 0; col < type.columns; col++)
|
|
for (uint32_t col = 0; col < type.columns; col++)
|
|
|
{
|
|
{
|
|
|
- expr += to_enclosed_expression(a);
|
|
|
|
|
|
|
+ expr += to_enclosed_unpacked_expression(a);
|
|
|
expr += " * ";
|
|
expr += " * ";
|
|
|
expr += to_extract_component_expression(b, col);
|
|
expr += to_extract_component_expression(b, col);
|
|
|
if (col + 1 < type.columns)
|
|
if (col + 1 < type.columns)
|
|
@@ -8247,19 +8255,19 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
auto &res_type = get<SPIRType>(type.member_types[1]);
|
|
auto &res_type = get<SPIRType>(type.member_types[1]);
|
|
|
if (opcode == OpIAddCarry)
|
|
if (opcode == OpIAddCarry)
|
|
|
{
|
|
{
|
|
|
- statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", to_enclosed_expression(op0), " + ",
|
|
|
|
|
- to_enclosed_expression(op1), ";");
|
|
|
|
|
|
|
+ statement(to_expression(result_id), ".", to_member_name(type, 0), " = ",
|
|
|
|
|
+ to_enclosed_unpacked_expression(op0), " + ", to_enclosed_unpacked_expression(op1), ";");
|
|
|
statement(to_expression(result_id), ".", to_member_name(type, 1), " = select(", type_to_glsl(res_type),
|
|
statement(to_expression(result_id), ".", to_member_name(type, 1), " = select(", type_to_glsl(res_type),
|
|
|
- "(1), ", type_to_glsl(res_type), "(0), ", to_expression(result_id), ".", to_member_name(type, 0),
|
|
|
|
|
- " >= max(", to_expression(op0), ", ", to_expression(op1), "));");
|
|
|
|
|
|
|
+ "(1), ", type_to_glsl(res_type), "(0), ", to_unpacked_expression(result_id), ".", to_member_name(type, 0),
|
|
|
|
|
+ " >= max(", to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), "));");
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", to_enclosed_expression(op0), " - ",
|
|
|
|
|
- to_enclosed_expression(op1), ";");
|
|
|
|
|
|
|
+ statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", to_enclosed_unpacked_expression(op0), " - ",
|
|
|
|
|
+ to_enclosed_unpacked_expression(op1), ";");
|
|
|
statement(to_expression(result_id), ".", to_member_name(type, 1), " = select(", type_to_glsl(res_type),
|
|
statement(to_expression(result_id), ".", to_member_name(type, 1), " = select(", type_to_glsl(res_type),
|
|
|
- "(1), ", type_to_glsl(res_type), "(0), ", to_enclosed_expression(op0),
|
|
|
|
|
- " >= ", to_enclosed_expression(op1), ");");
|
|
|
|
|
|
|
+ "(1), ", type_to_glsl(res_type), "(0), ", to_enclosed_unpacked_expression(op0),
|
|
|
|
|
+ " >= ", to_enclosed_unpacked_expression(op1), ");");
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -8274,10 +8282,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
auto &type = get<SPIRType>(result_type);
|
|
auto &type = get<SPIRType>(result_type);
|
|
|
emit_uninitialized_temporary_expression(result_type, result_id);
|
|
emit_uninitialized_temporary_expression(result_type, result_id);
|
|
|
|
|
|
|
|
- statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", to_enclosed_expression(op0), " * ",
|
|
|
|
|
- to_enclosed_expression(op1), ";");
|
|
|
|
|
- statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(", to_expression(op0), ", ",
|
|
|
|
|
- to_expression(op1), ");");
|
|
|
|
|
|
|
+ statement(to_expression(result_id), ".", to_member_name(type, 0), " = ",
|
|
|
|
|
+ to_enclosed_unpacked_expression(op0), " * ", to_enclosed_unpacked_expression(op1), ";");
|
|
|
|
|
+ statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(",
|
|
|
|
|
+ to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ");");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -8332,8 +8340,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
uint32_t id = ops[1];
|
|
uint32_t id = ops[1];
|
|
|
uint32_t a = ops[2], b = ops[3];
|
|
uint32_t a = ops[2], b = ops[3];
|
|
|
bool forward = should_forward(a) && should_forward(b);
|
|
bool forward = should_forward(a) && should_forward(b);
|
|
|
- emit_op(result_type, id, join("int(short(", to_expression(a), ")) * int(short(", to_expression(b), "))"),
|
|
|
|
|
- forward);
|
|
|
|
|
|
|
+ emit_op(result_type, id, join("int(short(", to_unpacked_expression(a), ")) * int(short(", to_unpacked_expression(b), "))"), forward);
|
|
|
inherit_expression_dependencies(id, a);
|
|
inherit_expression_dependencies(id, a);
|
|
|
inherit_expression_dependencies(id, b);
|
|
inherit_expression_dependencies(id, b);
|
|
|
break;
|
|
break;
|
|
@@ -8345,8 +8352,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
uint32_t id = ops[1];
|
|
uint32_t id = ops[1];
|
|
|
uint32_t a = ops[2], b = ops[3];
|
|
uint32_t a = ops[2], b = ops[3];
|
|
|
bool forward = should_forward(a) && should_forward(b);
|
|
bool forward = should_forward(a) && should_forward(b);
|
|
|
- emit_op(result_type, id, join("uint(ushort(", to_expression(a), ")) * uint(ushort(", to_expression(b), "))"),
|
|
|
|
|
- forward);
|
|
|
|
|
|
|
+ emit_op(result_type, id, join("uint(ushort(", to_unpacked_expression(a), ")) * uint(ushort(", to_unpacked_expression(b), "))"), forward);
|
|
|
inherit_expression_dependencies(id, a);
|
|
inherit_expression_dependencies(id, a);
|
|
|
inherit_expression_dependencies(id, b);
|
|
inherit_expression_dependencies(id, b);
|
|
|
break;
|
|
break;
|
|
@@ -8373,6 +8379,98 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
SPIRV_CROSS_THROW("Raster order groups require MSL 2.0.");
|
|
SPIRV_CROSS_THROW("Raster order groups require MSL 2.0.");
|
|
|
break; // Nothing to do in the body
|
|
break; // Nothing to do in the body
|
|
|
|
|
|
|
|
|
|
+ case OpConvertUToAccelerationStructureKHR:
|
|
|
|
|
+ SPIRV_CROSS_THROW("ConvertUToAccelerationStructure is not supported in MSL.");
|
|
|
|
|
+ case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
|
|
|
|
|
+ SPIRV_CROSS_THROW("BindingTableRecordOffset is not supported in MSL.");
|
|
|
|
|
+
|
|
|
|
|
+ case OpRayQueryInitializeKHR:
|
|
|
|
|
+ {
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+
|
|
|
|
|
+ statement(to_expression(ops[0]), ".reset(", "ray(", to_expression(ops[4]), ", ", to_expression(ops[6]), ", ",
|
|
|
|
|
+ to_expression(ops[5]), ", ", to_expression(ops[7]), "), ", to_expression(ops[1]),
|
|
|
|
|
+ ", intersection_params());");
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case OpRayQueryProceedKHR:
|
|
|
|
|
+ {
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".next()"), false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+#define MSL_RAY_QUERY_IS_CANDIDATE get<SPIRConstant>(ops[3]).scalar_i32() == 0
|
|
|
|
|
+
|
|
|
|
|
+#define MSL_RAY_QUERY_GET_OP(op, msl_op) \
|
|
|
|
|
+ case OpRayQueryGet##op##KHR: \
|
|
|
|
|
+ flush_variable_declaration(ops[2]); \
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".get_" #msl_op "()"), false); \
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+#define MSL_RAY_QUERY_OP_INNER2(op, msl_prefix, msl_op) \
|
|
|
|
|
+ case OpRayQueryGet##op##KHR: \
|
|
|
|
|
+ flush_variable_declaration(ops[2]); \
|
|
|
|
|
+ if (MSL_RAY_QUERY_IS_CANDIDATE) \
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), #msl_prefix "_candidate_" #msl_op "()"), false); \
|
|
|
|
|
+ else \
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), #msl_prefix "_committed_" #msl_op "()"), false); \
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+#define MSL_RAY_QUERY_GET_OP2(op, msl_op) MSL_RAY_QUERY_OP_INNER2(op, .get, msl_op)
|
|
|
|
|
+#define MSL_RAY_QUERY_IS_OP2(op, msl_op) MSL_RAY_QUERY_OP_INNER2(op, .is, msl_op)
|
|
|
|
|
+
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP(RayTMin, ray_min_distance);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP(WorldRayOrigin, world_space_ray_direction);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP(WorldRayDirection, world_space_ray_origin);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionInstanceId, instance_id);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionInstanceCustomIndex, user_instance_id);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionBarycentrics, triangle_barycentric_coord);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionPrimitiveIndex, primitive_id);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionGeometryIndex, geometry_id);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionObjectRayOrigin, ray_origin);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionObjectRayDirection, ray_direction);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionObjectToWorld, object_to_world_transform);
|
|
|
|
|
+ MSL_RAY_QUERY_GET_OP2(IntersectionWorldToObject, world_to_object_transform);
|
|
|
|
|
+ MSL_RAY_QUERY_IS_OP2(IntersectionFrontFace, triangle_front_facing);
|
|
|
|
|
+
|
|
|
|
|
+ case OpRayQueryGetIntersectionTypeKHR:
|
|
|
|
|
+ flush_variable_declaration(ops[2]);
|
|
|
|
|
+ if (MSL_RAY_QUERY_IS_CANDIDATE)
|
|
|
|
|
+ emit_op(ops[0], ops[1], join("uint(", to_expression(ops[2]), ".get_candidate_intersection_type()) - 1"),
|
|
|
|
|
+ false);
|
|
|
|
|
+ else
|
|
|
|
|
+ emit_op(ops[0], ops[1], join("uint(", to_expression(ops[2]), ".get_committed_intersection_type())"), false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OpRayQueryGetIntersectionTKHR:
|
|
|
|
|
+ flush_variable_declaration(ops[2]);
|
|
|
|
|
+ if (MSL_RAY_QUERY_IS_CANDIDATE)
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".get_candidate_triangle_distance()"), false);
|
|
|
|
|
+ else
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".get_committed_distance()"), false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR:
|
|
|
|
|
+ {
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+ emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".is_candidate_non_opaque_bounding_box()"), false);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case OpRayQueryConfirmIntersectionKHR:
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+ statement(to_expression(ops[0]), ".commit_triangle_intersection();");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OpRayQueryGenerateIntersectionKHR:
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+ statement(to_expression(ops[0]), ".commit_bounding_box_intersection(", to_expression(ops[1]), ");");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case OpRayQueryTerminateKHR:
|
|
|
|
|
+ flush_variable_declaration(ops[0]);
|
|
|
|
|
+ statement(to_expression(ops[0]), ".abort();");
|
|
|
|
|
+ break;
|
|
|
|
|
+#undef MSL_RAY_QUERY_GET_OP
|
|
|
|
|
+#undef MSL_RAY_QUERY_IS_CANDIDATE
|
|
|
|
|
+#undef MSL_RAY_QUERY_IS_OP2
|
|
|
|
|
+#undef MSL_RAY_QUERY_GET_OP2
|
|
|
|
|
+#undef MSL_RAY_QUERY_OP_INNER2
|
|
|
default:
|
|
default:
|
|
|
CompilerGLSL::emit_instruction(instruction);
|
|
CompilerGLSL::emit_instruction(instruction);
|
|
|
break;
|
|
break;
|
|
@@ -11295,6 +11393,12 @@ bool CompilerMSL::is_sample_rate() const
|
|
|
(msl_options.use_framebuffer_fetch_subpasses && need_subpass_input));
|
|
(msl_options.use_framebuffer_fetch_subpasses && need_subpass_input));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+bool CompilerMSL::is_intersection_query() const
|
|
|
|
|
+{
|
|
|
|
|
+ auto &caps = get_declared_capabilities();
|
|
|
|
|
+ return std::find(caps.begin(), caps.end(), CapabilityRayQueryKHR) != caps.end();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
|
void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
|
|
{
|
|
{
|
|
|
// Builtin variables
|
|
// Builtin variables
|
|
@@ -11773,6 +11877,10 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ case SPIRType::AccelerationStructure:
|
|
|
|
|
+ ep_args += ", " + type_to_glsl(type, var_id) + " " + r.name;
|
|
|
|
|
+ ep_args += " [[buffer(" + convert_to_string(r.index) + ")]]";
|
|
|
|
|
+ break;
|
|
|
default:
|
|
default:
|
|
|
if (!ep_args.empty())
|
|
if (!ep_args.empty())
|
|
|
ep_args += ", ";
|
|
ep_args += ", ";
|
|
@@ -13126,9 +13234,6 @@ void CompilerMSL::sync_entry_point_aliases_and_names()
|
|
|
|
|
|
|
|
string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain)
|
|
string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain)
|
|
|
{
|
|
{
|
|
|
- if (index < uint32_t(type.member_type_index_redirection.size()))
|
|
|
|
|
- index = type.member_type_index_redirection[index];
|
|
|
|
|
-
|
|
|
|
|
auto *var = maybe_get<SPIRVariable>(base);
|
|
auto *var = maybe_get<SPIRVariable>(base);
|
|
|
// If this is a buffer array, we have to dereference the buffer pointers.
|
|
// If this is a buffer array, we have to dereference the buffer pointers.
|
|
|
// Otherwise, if this is a pointer expression, dereference it.
|
|
// Otherwise, if this is a pointer expression, dereference it.
|
|
@@ -13243,8 +13348,23 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
|
|
|
|
|
|
|
// Scalars
|
|
// Scalars
|
|
|
case SPIRType::Boolean:
|
|
case SPIRType::Boolean:
|
|
|
- type_name = "bool";
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ auto *var = maybe_get_backing_variable(id);
|
|
|
|
|
+ if (var && var->basevariable)
|
|
|
|
|
+ var = &get<SPIRVariable>(var->basevariable);
|
|
|
|
|
+
|
|
|
|
|
+ // Need to special-case threadgroup booleans. They are supposed to be logical
|
|
|
|
|
+ // storage, but MSL compilers will sometimes crash if you use threadgroup bool.
|
|
|
|
|
+ // Workaround this by using 16-bit types instead and fixup on load-store to this data.
|
|
|
|
|
+ // FIXME: We have no sane way of working around this problem if a struct member is boolean
|
|
|
|
|
+ // and that struct is used as a threadgroup variable, but ... sigh.
|
|
|
|
|
+ if ((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup)
|
|
|
|
|
+ type_name = "short";
|
|
|
|
|
+ else
|
|
|
|
|
+ type_name = "bool";
|
|
|
break;
|
|
break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
case SPIRType::Char:
|
|
case SPIRType::Char:
|
|
|
case SPIRType::SByte:
|
|
case SPIRType::SByte:
|
|
|
type_name = "char";
|
|
type_name = "char";
|
|
@@ -13283,6 +13403,16 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
|
|
case SPIRType::Double:
|
|
case SPIRType::Double:
|
|
|
type_name = "double"; // Currently unsupported
|
|
type_name = "double"; // Currently unsupported
|
|
|
break;
|
|
break;
|
|
|
|
|
+ case SPIRType::AccelerationStructure:
|
|
|
|
|
+ if (msl_options.supports_msl_version(2, 4))
|
|
|
|
|
+ type_name = "acceleration_structure<instancing>";
|
|
|
|
|
+ else if (msl_options.supports_msl_version(2, 3))
|
|
|
|
|
+ type_name = "instance_acceleration_structure";
|
|
|
|
|
+ else
|
|
|
|
|
+ SPIRV_CROSS_THROW("Acceleration Structure Type is supported in MSL 2.3 and above.");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case SPIRType::RayQuery:
|
|
|
|
|
+ return "intersection_query<instancing, triangle_data>";
|
|
|
|
|
|
|
|
default:
|
|
default:
|
|
|
return "unknown_type";
|
|
return "unknown_type";
|
|
@@ -13327,6 +13457,7 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type)
|
|
|
{
|
|
{
|
|
|
case SPIRType::AtomicCounter:
|
|
case SPIRType::AtomicCounter:
|
|
|
case SPIRType::ControlPointArray:
|
|
case SPIRType::ControlPointArray:
|
|
|
|
|
+ case SPIRType::RayQuery:
|
|
|
{
|
|
{
|
|
|
return CompilerGLSL::type_to_array_glsl(type);
|
|
return CompilerGLSL::type_to_array_glsl(type);
|
|
|
}
|
|
}
|
|
@@ -15240,11 +15371,13 @@ void CompilerMSL::MemberSorter::sort()
|
|
|
meta.members[mbr_idx] = mbr_meta_cpy[mbr_idxs[mbr_idx]];
|
|
meta.members[mbr_idx] = mbr_meta_cpy[mbr_idxs[mbr_idx]];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // If we're sorting by Offset, this might affect user code which accesses a buffer block.
|
|
|
|
|
+ // We will need to redirect member indices from defined index to sorted index using reverse lookup.
|
|
|
if (sort_aspect == SortAspect::Offset)
|
|
if (sort_aspect == SortAspect::Offset)
|
|
|
{
|
|
{
|
|
|
- // If we're sorting by Offset, this might affect user code which accesses a buffer block.
|
|
|
|
|
- // We will need to redirect member indices from one index to sorted index.
|
|
|
|
|
- type.member_type_index_redirection = std::move(mbr_idxs);
|
|
|
|
|
|
|
+ type.member_type_index_redirection.resize(mbr_cnt);
|
|
|
|
|
+ for (uint32_t map_idx = 0; map_idx < mbr_cnt; map_idx++)
|
|
|
|
|
+ type.member_type_index_redirection[mbr_idxs[map_idx]] = map_idx;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -15294,12 +15427,16 @@ void CompilerMSL::remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t
|
|
|
constexpr_samplers_by_binding[{ desc_set, binding }] = sampler;
|
|
constexpr_samplers_by_binding[{ desc_set, binding }] = sampler;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void CompilerMSL::cast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type)
|
|
|
|
|
|
|
+void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type)
|
|
|
{
|
|
{
|
|
|
auto *var = maybe_get_backing_variable(source_id);
|
|
auto *var = maybe_get_backing_variable(source_id);
|
|
|
if (var)
|
|
if (var)
|
|
|
source_id = var->self;
|
|
source_id = var->self;
|
|
|
|
|
|
|
|
|
|
+ // Type fixups for workgroup variables if they are booleans.
|
|
|
|
|
+ if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean)
|
|
|
|
|
+ expr = join(type_to_glsl(expr_type), "(", expr, ")");
|
|
|
|
|
+
|
|
|
// Only interested in standalone builtin variables.
|
|
// Only interested in standalone builtin variables.
|
|
|
if (!has_decoration(source_id, DecorationBuiltIn))
|
|
if (!has_decoration(source_id, DecorationBuiltIn))
|
|
|
return;
|
|
return;
|
|
@@ -15386,12 +15523,20 @@ void CompilerMSL::cast_from_builtin_load(uint32_t source_id, std::string &expr,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void CompilerMSL::cast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type)
|
|
|
|
|
|
|
+void CompilerMSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type)
|
|
|
{
|
|
{
|
|
|
auto *var = maybe_get_backing_variable(target_id);
|
|
auto *var = maybe_get_backing_variable(target_id);
|
|
|
if (var)
|
|
if (var)
|
|
|
target_id = var->self;
|
|
target_id = var->self;
|
|
|
|
|
|
|
|
|
|
+ // Type fixups for workgroup variables if they are booleans.
|
|
|
|
|
+ if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean)
|
|
|
|
|
+ {
|
|
|
|
|
+ auto short_type = expr_type;
|
|
|
|
|
+ short_type.basetype = SPIRType::Short;
|
|
|
|
|
+ expr = join(type_to_glsl(short_type), "(", expr, ")");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// Only interested in standalone builtin variables.
|
|
// Only interested in standalone builtin variables.
|
|
|
if (!has_decoration(target_id, DecorationBuiltIn))
|
|
if (!has_decoration(target_id, DecorationBuiltIn))
|
|
|
return;
|
|
return;
|