|
|
@@ -1898,9 +1898,18 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
|
|
|
case OpAtomicOr:
|
|
|
case OpAtomicXor:
|
|
|
case OpImageWrite:
|
|
|
+ {
|
|
|
if (needs_frag_discard_checks())
|
|
|
added_arg_ids.insert(builtin_helper_invocation_id);
|
|
|
+ uint32_t ptr = 0;
|
|
|
+ if (op == OpAtomicStore || op == OpImageWrite)
|
|
|
+ ptr = ops[0];
|
|
|
+ else
|
|
|
+ ptr = ops[2];
|
|
|
+ if (global_var_ids.find(ptr) != global_var_ids.end())
|
|
|
+ added_arg_ids.insert(ptr);
|
|
|
break;
|
|
|
+ }
|
|
|
|
|
|
// Emulate texture2D atomic operations
|
|
|
case OpImageTexelPointer:
|
|
|
@@ -4902,9 +4911,18 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp
|
|
|
|
|
|
bool transpose = lhs_e && lhs_e->need_transpose;
|
|
|
|
|
|
- // No physical type remapping, and no packed type, so can just emit a store directly.
|
|
|
- if (!lhs_remapped_type && !lhs_packed_type)
|
|
|
+ if (has_decoration(lhs_expression, DecorationBuiltIn) &&
|
|
|
+ BuiltIn(get_decoration(lhs_expression, DecorationBuiltIn)) == BuiltInSampleMask &&
|
|
|
+ type_is_top_level_array(type))
|
|
|
+ {
|
|
|
+ // Storing an array to SampleMask, have to remove the array-ness before storing.
|
|
|
+ statement(to_expression(lhs_expression), " = ", to_enclosed_unpacked_expression(rhs_expression), "[0];");
|
|
|
+ register_write(lhs_expression);
|
|
|
+ }
|
|
|
+ else if (!lhs_remapped_type && !lhs_packed_type)
|
|
|
{
|
|
|
+ // No physical type remapping, and no packed type, so can just emit a store directly.
|
|
|
+
|
|
|
// We might not be dealing with remapped physical types or packed types,
|
|
|
// but we might be doing a clean store to a row-major matrix.
|
|
|
// In this case, we just flip transpose states, and emit the store, a transpose must be in the RHS expression, if any.
|
|
|
@@ -7290,7 +7308,8 @@ void CompilerMSL::emit_custom_functions()
|
|
|
end_scope_decl();
|
|
|
statement("");
|
|
|
|
|
|
- if (msl_options.runtime_array_rich_descriptor)
|
|
|
+ if (msl_options.runtime_array_rich_descriptor &&
|
|
|
+ spv_function_implementations.count(SPVFuncImplVariableSizedDescriptor) != 0)
|
|
|
{
|
|
|
statement("template<typename T>");
|
|
|
statement("struct spvDescriptorArray<device T*>");
|
|
|
@@ -9365,6 +9384,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
case OpRayQueryInitializeKHR:
|
|
|
{
|
|
|
flush_variable_declaration(ops[0]);
|
|
|
+ register_write(ops[0]);
|
|
|
add_spv_func_and_recompile(SPVFuncImplRayQueryIntersectionParams);
|
|
|
|
|
|
statement(to_expression(ops[0]), ".reset(", "ray(", to_expression(ops[4]), ", ", to_expression(ops[6]), ", ",
|
|
|
@@ -9375,6 +9395,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
case OpRayQueryProceedKHR:
|
|
|
{
|
|
|
flush_variable_declaration(ops[0]);
|
|
|
+ register_write(ops[2]);
|
|
|
emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".next()"), false);
|
|
|
break;
|
|
|
}
|
|
|
@@ -9435,14 +9456,17 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|
|
}
|
|
|
case OpRayQueryConfirmIntersectionKHR:
|
|
|
flush_variable_declaration(ops[0]);
|
|
|
+ register_write(ops[0]);
|
|
|
statement(to_expression(ops[0]), ".commit_triangle_intersection();");
|
|
|
break;
|
|
|
case OpRayQueryGenerateIntersectionKHR:
|
|
|
flush_variable_declaration(ops[0]);
|
|
|
+ register_write(ops[0]);
|
|
|
statement(to_expression(ops[0]), ".commit_bounding_box_intersection(", to_expression(ops[1]), ");");
|
|
|
break;
|
|
|
case OpRayQueryTerminateKHR:
|
|
|
flush_variable_declaration(ops[0]);
|
|
|
+ register_write(ops[0]);
|
|
|
statement(to_expression(ops[0]), ".abort();");
|
|
|
break;
|
|
|
#undef MSL_RAY_QUERY_GET_OP
|
|
|
@@ -13247,8 +13271,13 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
|
|
|
{
|
|
|
if (!ep_args.empty())
|
|
|
ep_args += ", ";
|
|
|
- ep_args +=
|
|
|
- get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_restrict(var_id, true) + r.name;
|
|
|
+ ep_args += get_argument_address_space(var) + " ";
|
|
|
+
|
|
|
+ if (recursive_inputs.count(type.self))
|
|
|
+ ep_args += string("void* ") + to_restrict(var_id, true) + r.name + "_vp";
|
|
|
+ else
|
|
|
+ ep_args += type_to_glsl(type) + "& " + to_restrict(var_id, true) + r.name;
|
|
|
+
|
|
|
ep_args += " [[buffer(" + convert_to_string(r.index) + ")";
|
|
|
if (interlocked_resources.count(var_id))
|
|
|
ep_args += ", raster_order_group(0)";
|
|
|
@@ -13431,6 +13460,19 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (msl_options.replace_recursive_inputs && type_contains_recursion(type) &&
|
|
|
+ (var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant ||
|
|
|
+ var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer))
|
|
|
+ {
|
|
|
+ recursive_inputs.insert(type.self);
|
|
|
+ entry_func.fixup_hooks_in.push_back([this, &type, &var, var_id]() {
|
|
|
+ auto addr_space = get_argument_address_space(var);
|
|
|
+ auto var_name = to_name(var_id);
|
|
|
+ statement(addr_space, " auto& ", to_restrict(var_id, true), var_name,
|
|
|
+ " = *(", addr_space, " ", type_to_glsl(type), "*)", var_name, "_vp;");
|
|
|
+ });
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
// Builtin variables
|
|
|
@@ -17145,6 +17187,7 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
|
|
|
case BuiltInInstanceIndex:
|
|
|
case BuiltInBaseInstance:
|
|
|
case BuiltInBaseVertex:
|
|
|
+ case BuiltInSampleMask:
|
|
|
expected_type = SPIRType::UInt;
|
|
|
expected_width = 32;
|
|
|
break;
|
|
|
@@ -17162,9 +17205,17 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (expected_type != expr_type.basetype)
|
|
|
+ if (type_is_top_level_array(expr_type) && builtin == BuiltInSampleMask)
|
|
|
+ {
|
|
|
+ // Needs special handling.
|
|
|
+ auto wrap_expr = join(type_to_glsl(expr_type), "({ ");
|
|
|
+ wrap_expr += join(type_to_glsl(get<SPIRType>(expr_type.parent_type)), "(", expr, ")");
|
|
|
+ wrap_expr += " })";
|
|
|
+ expr = std::move(wrap_expr);
|
|
|
+ }
|
|
|
+ else if (expected_type != expr_type.basetype)
|
|
|
{
|
|
|
- if (!expr_type.array.empty() && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter))
|
|
|
+ if (type_is_top_level_array(expr_type) && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter))
|
|
|
{
|
|
|
// Triggers when loading TessLevel directly as an array.
|
|
|
// Need explicit padding + cast.
|