Updated spirv-cross.

This commit is contained in:
Бранимир Караџић
2024-10-18 20:28:47 -07:00
parent 4157813255
commit 132266c1bd
10 changed files with 195 additions and 57 deletions

View File

@@ -1,5 +1,5 @@
/*
** Copyright (c) 2014-2020 The Khronos Group Inc.
** Copyright (c) 2014-2024 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@@ -511,6 +511,7 @@ typedef enum SpvDecoration_ {
SpvDecorationNoUnsignedWrap = 4470,
SpvDecorationWeightTextureQCOM = 4487,
SpvDecorationBlockMatchTextureQCOM = 4488,
SpvDecorationBlockMatchSamplerQCOM = 4499,
SpvDecorationExplicitInterpAMD = 4999,
SpvDecorationOverrideCoverageNV = 5248,
SpvDecorationPassthroughNV = 5250,
@@ -996,6 +997,7 @@ typedef enum SpvCapability_ {
SpvCapabilityTextureSampleWeightedQCOM = 4484,
SpvCapabilityTextureBoxFilterQCOM = 4485,
SpvCapabilityTextureBlockMatchQCOM = 4486,
SpvCapabilityTextureBlockMatch2QCOM = 4498,
SpvCapabilityFloat16ImageAMD = 5008,
SpvCapabilityImageGatherBiasLodAMD = 5009,
SpvCapabilityFragmentMaskAMD = 5010,
@@ -1605,6 +1607,10 @@ typedef enum SpvOp_ {
SpvOpImageBoxFilterQCOM = 4481,
SpvOpImageBlockMatchSSDQCOM = 4482,
SpvOpImageBlockMatchSADQCOM = 4483,
SpvOpImageBlockMatchWindowSSDQCOM = 4500,
SpvOpImageBlockMatchWindowSADQCOM = 4501,
SpvOpImageBlockMatchGatherSSDQCOM = 4502,
SpvOpImageBlockMatchGatherSADQCOM = 4503,
SpvOpGroupIAddNonUniformAMD = 5000,
SpvOpGroupFAddNonUniformAMD = 5001,
SpvOpGroupFMinNonUniformAMD = 5002,
@@ -2284,6 +2290,10 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2014-2020 The Khronos Group Inc.
// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -507,6 +507,7 @@ enum Decoration {
DecorationNoUnsignedWrap = 4470,
DecorationWeightTextureQCOM = 4487,
DecorationBlockMatchTextureQCOM = 4488,
DecorationBlockMatchSamplerQCOM = 4499,
DecorationExplicitInterpAMD = 4999,
DecorationOverrideCoverageNV = 5248,
DecorationPassthroughNV = 5250,
@@ -992,6 +993,7 @@ enum Capability {
CapabilityTextureSampleWeightedQCOM = 4484,
CapabilityTextureBoxFilterQCOM = 4485,
CapabilityTextureBlockMatchQCOM = 4486,
CapabilityTextureBlockMatch2QCOM = 4498,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
@@ -1601,6 +1603,10 @@ enum Op {
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
OpImageBlockMatchWindowSSDQCOM = 4500,
OpImageBlockMatchWindowSADQCOM = 4501,
OpImageBlockMatchGatherSSDQCOM = 4502,
OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -2280,6 +2286,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;

View File

@@ -198,6 +198,8 @@ struct spvc_resources_s : ScratchMemoryAllocation
SmallVector<spvc_reflected_resource> separate_images;
SmallVector<spvc_reflected_resource> separate_samplers;
SmallVector<spvc_reflected_resource> acceleration_structures;
SmallVector<spvc_reflected_resource> gl_plain_uniforms;
SmallVector<spvc_reflected_builtin_resource> builtin_inputs;
SmallVector<spvc_reflected_builtin_resource> builtin_outputs;
@@ -520,6 +522,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
case SPVC_COMPILER_OPTION_HLSL_USE_ENTRY_POINT_NAME:
options->hlsl.use_entry_point_name = value != 0;
break;
case SPVC_COMPILER_OPTION_HLSL_PRESERVE_STRUCTURED_BUFFERS:
options->hlsl.preserve_structured_buffers = value != 0;
break;
#endif
#if SPIRV_CROSS_C_API_MSL
@@ -1855,6 +1861,8 @@ bool spvc_resources_s::copy_resources(const ShaderResources &resources)
return false;
if (!copy_resources(acceleration_structures, resources.acceleration_structures))
return false;
if (!copy_resources(gl_plain_uniforms, resources.gl_plain_uniforms))
return false;
if (!copy_resources(builtin_inputs, resources.builtin_inputs))
return false;
if (!copy_resources(builtin_outputs, resources.builtin_outputs))
@@ -2006,6 +2014,9 @@ spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources,
list = &resources->shader_record_buffers;
break;
case SPVC_RESOURCE_TYPE_GL_PLAIN_UNIFORM:
list = &resources->gl_plain_uniforms;
default:
break;
}
@@ -2177,7 +2188,11 @@ spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler, const spvc_en
spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name, SpvExecutionModel model)
{
compiler->compiler->set_entry_point(name, static_cast<spv::ExecutionModel>(model));
SPVC_BEGIN_SAFE_SCOPE
{
compiler->compiler->set_entry_point(name, static_cast<spv::ExecutionModel>(model));
}
SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT)
return SPVC_SUCCESS;
}

View File

@@ -40,7 +40,7 @@ extern "C" {
/* Bumped if ABI or API breaks backwards compatibility. */
#define SPVC_C_API_VERSION_MAJOR 0
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
#define SPVC_C_API_VERSION_MINOR 62
#define SPVC_C_API_VERSION_MINOR 64
/* Bumped if internal implementation details change. */
#define SPVC_C_API_VERSION_PATCH 0
@@ -226,6 +226,7 @@ typedef enum spvc_resource_type
SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12,
SPVC_RESOURCE_TYPE_RAY_QUERY = 13,
SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14,
SPVC_RESOURCE_TYPE_GL_PLAIN_UNIFORM = 15,
SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff
} spvc_resource_type;
@@ -745,6 +746,7 @@ typedef enum spvc_compiler_option
SPVC_COMPILER_OPTION_MSL_FORCE_FRAGMENT_WITH_SIDE_EFFECTS_EXECUTION = 89 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_HLSL_USE_ENTRY_POINT_NAME = 90 | SPVC_COMPILER_OPTION_HLSL_BIT,
SPVC_COMPILER_OPTION_HLSL_PRESERVE_STRUCTURED_BUFFERS = 91 | SPVC_COMPILER_OPTION_HLSL_BIT,
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
} spvc_compiler_option;

View File

@@ -564,7 +564,8 @@ Bitset ParsedIR::get_buffer_block_type_flags(const SPIRType &type) const
Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
{
auto &type = get<SPIRType>(var.basetype);
assert(type.basetype == SPIRType::Struct);
if (type.basetype != SPIRType::Struct)
SPIRV_CROSS_THROW("Cannot get buffer block flags for non-buffer variable.");
// Some flags like non-writable, non-readable are actually found
// as member decorations. If all members have a decoration set, propagate

View File

@@ -2764,6 +2764,8 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
block_qualifier = "patch ";
else if (has_decoration(var.self, DecorationPerPrimitiveEXT))
block_qualifier = "perprimitiveEXT ";
else if (has_decoration(var.self, DecorationPerVertexKHR))
block_qualifier = "pervertexEXT ";
else
block_qualifier = "";
@@ -3691,11 +3693,11 @@ void CompilerGLSL::emit_resources()
auto &type = this->get<SPIRType>(undef.basetype);
// OpUndef can be void for some reason ...
if (type.basetype == SPIRType::Void)
return;
continue;
// This will break. It is bogus and should not be legal.
if (type_is_top_level_block(type))
return;
continue;
string initializer;
if (options.force_zero_initialized_variables && type_can_zero_initialize(type))
@@ -14481,6 +14483,50 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
break;
}
case OpImageBlockMatchWindowSSDQCOM:
case OpImageBlockMatchWindowSADQCOM:
case OpImageBlockMatchGatherSSDQCOM:
case OpImageBlockMatchGatherSADQCOM:
{
require_extension_internal("GL_QCOM_image_processing2");
uint32_t result_type_id = ops[0];
uint32_t id = ops[1];
string expr;
switch (opcode)
{
case OpImageBlockMatchWindowSSDQCOM:
expr = "textureBlockMatchWindowSSDQCOM";
break;
case OpImageBlockMatchWindowSADQCOM:
expr = "textureBlockMatchWindowSADQCOM";
break;
case OpImageBlockMatchGatherSSDQCOM:
expr = "textureBlockMatchGatherSSDQCOM";
break;
case OpImageBlockMatchGatherSADQCOM:
expr = "textureBlockMatchGatherSADQCOM";
break;
default:
SPIRV_CROSS_THROW("Invalid opcode for QCOM_image_processing2.");
}
expr += "(";
bool forward = false;
expr += to_expression(ops[2]);
expr += ", " + to_expression(ops[3]);
expr += ", " + to_non_uniform_aware_expression(ops[4]);
expr += ", " + to_expression(ops[5]);
expr += ", " + to_expression(ops[6]);
expr += ")";
emit_op(result_type_id, id, expr, forward);
inherit_expression_dependencies(id, ops[3]);
inherit_expression_dependencies(id, ops[5]);
break;
}
// Compute
case OpControlBarrier:
case OpMemoryBarrier:
@@ -17608,7 +17654,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
if (!collapsed_switch)
{
if (block_like_switch || is_legacy_es())
if (block_like_switch || is_legacy())
{
// ESSL 1.0 is not guaranteed to support do/while.
if (is_legacy_es())
@@ -17638,7 +17684,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
// Default case.
if (!block_like_switch)
{
if (is_legacy_es())
if (is_legacy())
statement("else");
else
statement("default:");
@@ -17646,7 +17692,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
}
else
{
if (is_legacy_es())
if (is_legacy())
{
statement((i ? "else " : ""), "if (", to_legacy_case_label(block.condition, literals, label_suffix),
")");
@@ -17698,7 +17744,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
if (block.default_block == block.next_block)
{
if (is_legacy_es())
if (is_legacy())
statement("else");
else
statement("default:");
@@ -17712,7 +17758,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
if (!collapsed_switch)
{
if (block_like_switch && !is_legacy_es())
if ((block_like_switch || is_legacy()) && !is_legacy_es())
end_scope_decl("while(false)");
else
end_scope();

View File

@@ -919,6 +919,17 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
semantic = "SV_RenderTargetArrayIndex";
break;
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
if (hlsl_options.shader_model < 61)
SPIRV_CROSS_THROW("SM 6.1 is required for barycentrics.");
type = builtin == BuiltInBaryCoordNoPerspKHR ? "noperspective float3" : "float3";
if (active_input_builtins.get(BuiltInBaryCoordKHR) && active_input_builtins.get(BuiltInBaryCoordNoPerspKHR))
semantic = builtin == BuiltInBaryCoordKHR ? "SV_Barycentrics0" : "SV_Barycentrics1";
else
semantic = "SV_Barycentrics";
break;
default:
SPIRV_CROSS_THROW("Unsupported builtin in HLSL.");
}
@@ -958,7 +969,7 @@ string CompilerHLSL::to_interpolation_qualifiers(const Bitset &flags)
string res;
//if (flags & (1ull << DecorationSmooth))
// res += "linear ";
if (flags.get(DecorationFlat))
if (flags.get(DecorationFlat) || flags.get(DecorationPerVertexKHR))
res += "nointerpolation ";
if (flags.get(DecorationNoPerspective))
res += "noperspective ";
@@ -1014,7 +1025,11 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var
auto mbr_name = join(to_name(type.self), "_", to_member_name(type, member_index));
auto &mbr_type = get<SPIRType>(type.member_types[member_index]);
statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, member_index)),
Bitset member_decorations = get_member_decoration_bitset(type.self, member_index);
if (has_decoration(var.self, DecorationPerVertexKHR))
member_decorations.set(DecorationPerVertexKHR);
statement(to_interpolation_qualifiers(member_decorations),
type_to_glsl(mbr_type),
" ", mbr_name, type_to_array_glsl(mbr_type, var.self),
" : ", semantic, ";");
@@ -1102,7 +1117,7 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord
else
{
auto decl_type = type;
if (execution.model == ExecutionModelMeshEXT)
if (execution.model == ExecutionModelMeshEXT || has_decoration(var.self, DecorationPerVertexKHR))
{
decl_type.array.erase(decl_type.array.begin());
decl_type.array_size_literal.erase(decl_type.array_size_literal.begin());
@@ -1341,6 +1356,13 @@ void CompilerHLSL::emit_builtin_variables()
type = "uint";
break;
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
if (hlsl_options.shader_model < 61)
SPIRV_CROSS_THROW("Need SM 6.1 for barycentrics.");
type = "float3";
break;
default:
SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin)));
}
@@ -3298,11 +3320,23 @@ void CompilerHLSL::emit_hlsl_entry_point()
{
auto type_name = to_name(type.self);
auto var_name = to_name(var.self);
bool is_per_vertex = has_decoration(var.self, DecorationPerVertexKHR);
uint32_t array_size = is_per_vertex ? to_array_size_literal(type) : 0;
for (uint32_t mbr_idx = 0; mbr_idx < uint32_t(type.member_types.size()); mbr_idx++)
{
auto mbr_name = to_member_name(type, mbr_idx);
auto flat_name = join(type_name, "_", mbr_name);
statement(var_name, ".", mbr_name, " = stage_input.", flat_name, ";");
if (is_per_vertex)
{
for (uint32_t i = 0; i < array_size; i++)
statement(var_name, "[", i, "].", mbr_name, " = GetAttributeAtVertex(stage_input.", flat_name, ", ", i, ");");
}
else
{
statement(var_name, ".", mbr_name, " = stage_input.", flat_name, ";");
}
}
}
else
@@ -3315,6 +3349,12 @@ void CompilerHLSL::emit_hlsl_entry_point()
for (uint32_t col = 0; col < mtype.columns; col++)
statement(name, "[", col, "] = stage_input.", name, "_", col, ";");
}
else if (has_decoration(var.self, DecorationPerVertexKHR))
{
uint32_t array_size = to_array_size_literal(type);
for (uint32_t i = 0; i < array_size; i++)
statement(name, "[", i, "]", " = GetAttributeAtVertex(stage_input.", name, ", ", i, ");");
}
else
{
statement(name, " = stage_input.", name, ";");
@@ -6725,6 +6765,7 @@ string CompilerHLSL::compile()
backend.support_case_fallthrough = false;
backend.force_merged_mesh_block = get_execution_model() == ExecutionModelMeshEXT;
backend.force_gl_in_out_block = backend.force_merged_mesh_block;
backend.supports_empty_struct = hlsl_options.shader_model <= 30;
// SM 4.1 does not support precise for some reason.
backend.support_precise_qualifier = hlsl_options.shader_model >= 50 || hlsl_options.shader_model == 40;

View File

@@ -7599,6 +7599,16 @@ void CompilerMSL::emit_custom_functions()
statement("");
break;
case SPVFuncImplMulExtended:
// Compiler may hit an internal error with mulhi, but doesn't when encapsulated for some reason.
statement("template<typename T, typename U, typename V>");
statement("[[clang::optnone]] T spvMulExtended(V l, V r)");
begin_scope();
statement("return T{U(l * r), U(mulhi(l, r))};");
end_scope();
statement("");
break;
default:
break;
}
@@ -9550,13 +9560,13 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
uint32_t op0 = ops[2];
uint32_t op1 = ops[3];
auto &type = get<SPIRType>(result_type);
auto &op_type = get<SPIRType>(type.member_types[0]);
auto input_type = opcode == OpSMulExtended ? int_type : uint_type;
string cast_op0, cast_op1;
binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, false);
emit_uninitialized_temporary_expression(result_type, result_id);
statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", cast_op0, " * ", cast_op1, ";");
statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(", cast_op0, ", ", cast_op1, ");");
auto expr = join("spvMulExtended<", type_to_glsl(type), ", ", type_to_glsl(op_type), ">(", cast_op0, ", ", cast_op1, ")");
emit_op(result_type, result_id, expr, true);
break;
}
@@ -10303,6 +10313,13 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id,
{
auto obj_expression = to_expression(obj);
auto split_index = obj_expression.find_first_of('@');
bool needs_reinterpret = opcode == OpAtomicUMax || opcode == OpAtomicUMin || opcode == OpAtomicSMax || opcode == OpAtomicSMin;
needs_reinterpret &= type.basetype != expected_type;
SPIRVariable *backing_var = nullptr;
// Try to avoid waiting until not force recompile later mode to enable force recompile later
if (needs_reinterpret && (backing_var = maybe_get_backing_variable(obj)))
add_spv_func_and_recompile(SPVFuncImplTextureCast);
// Will only be false if we're in "force recompile later" mode.
if (split_index != string::npos)
@@ -10313,27 +10330,21 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id,
// Handle problem cases with sign where we need signed min/max on a uint image for example.
// It seems to work to cast the texture type itself, even if it is probably wildly outside of spec,
// but SPIR-V requires this to work.
if ((opcode == OpAtomicUMax || opcode == OpAtomicUMin ||
opcode == OpAtomicSMax || opcode == OpAtomicSMin) &&
type.basetype != expected_type)
if (needs_reinterpret && backing_var)
{
auto *backing_var = maybe_get_backing_variable(obj);
if (backing_var)
{
add_spv_func_and_recompile(SPVFuncImplTextureCast);
assert(spv_function_implementations.count(SPVFuncImplTextureCast) && "Should have been added above");
const auto *backing_type = &get<SPIRType>(backing_var->basetype);
while (backing_type->op != OpTypeImage)
backing_type = &get<SPIRType>(backing_type->parent_type);
const auto *backing_type = &get<SPIRType>(backing_var->basetype);
while (backing_type->op != OpTypeImage)
backing_type = &get<SPIRType>(backing_type->parent_type);
auto img_type = *backing_type;
auto tmp_type = type;
tmp_type.basetype = expected_type;
img_type.image.type = ir.increase_bound_by(1);
set<SPIRType>(img_type.image.type, tmp_type);
auto img_type = *backing_type;
auto tmp_type = type;
tmp_type.basetype = expected_type;
img_type.image.type = ir.increase_bound_by(1);
set<SPIRType>(img_type.image.type, tmp_type);
image_expr = join("spvTextureCast<", type_to_glsl(img_type, obj), ">(", image_expr, ")");
}
image_expr = join("spvTextureCast<", type_to_glsl(img_type, obj), ">(", image_expr, ")");
}
exp += join(image_expr, ".", op, "(");
@@ -12758,17 +12769,10 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
else
quals = member_location_attribute_qualifier(type, index);
if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR)
if (builtin == BuiltInBaryCoordKHR && has_member_decoration(type.self, index, DecorationNoPerspective))
{
if (has_member_decoration(type.self, index, DecorationFlat) ||
has_member_decoration(type.self, index, DecorationCentroid) ||
has_member_decoration(type.self, index, DecorationSample) ||
has_member_decoration(type.self, index, DecorationNoPerspective))
{
// NoPerspective is baked into the builtin type.
SPIRV_CROSS_THROW(
"Flat, Centroid, Sample, NoPerspective decorations are not supported for BaryCoord inputs.");
}
// NoPerspective is baked into the builtin type.
SPIRV_CROSS_THROW("NoPerspective decorations are not supported for BaryCoord inputs.");
}
// Don't bother decorating integers with the 'flat' attribute; it's
@@ -12786,7 +12790,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
{
if (!quals.empty())
quals += ", ";
if (has_member_decoration(type.self, index, DecorationNoPerspective))
if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR)
quals += "centroid_no_perspective";
else
quals += "centroid_perspective";
@@ -12795,17 +12799,23 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
{
if (!quals.empty())
quals += ", ";
if (has_member_decoration(type.self, index, DecorationNoPerspective))
if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR)
quals += "sample_no_perspective";
else
quals += "sample_perspective";
}
else if (has_member_decoration(type.self, index, DecorationNoPerspective))
else if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR)
{
if (!quals.empty())
quals += ", ";
quals += "center_no_perspective";
}
else if (builtin == BuiltInBaryCoordKHR)
{
if (!quals.empty())
quals += ", ";
quals += "center_perspective";
}
}
if (!quals.empty())
@@ -13873,6 +13883,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
}
else
{
add_spv_func_and_recompile(SPVFuncImplVariableDescriptor);
ep_args += "const device spvDescriptor<" + get_argument_address_space(var) + " " +
type_to_glsl(type) + "*>* ";
}
@@ -15253,6 +15264,7 @@ const std::unordered_set<std::string> &CompilerMSL::get_illegal_func_names()
"fmin3",
"fmax3",
"divide",
"fmod",
"median3",
"VARIABLE_TRACEPOINT",
"STATIC_DATA_TRACEPOINT",
@@ -16806,18 +16818,12 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL.");
case BuiltInBaryCoordKHR:
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
else if (!msl_options.supports_msl_version(2, 2))
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS.");
return "barycentric_coord, center_perspective";
case BuiltInBaryCoordNoPerspKHR:
if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3))
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS.");
else if (!msl_options.supports_msl_version(2, 2))
SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS.");
return "barycentric_coord, center_no_perspective";
return "barycentric_coord";
default:
return "unsupported-built-in";
@@ -17705,6 +17711,10 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
case OpSUDotAccSat:
return SPVFuncImplReduceAdd;
case OpSMulExtended:
case OpUMulExtended:
return SPVFuncImplMulExtended;
default:
break;
}

View File

@@ -838,7 +838,8 @@ protected:
SPVFuncImplPaddedStd140,
SPVFuncImplReduceAdd,
SPVFuncImplImageFence,
SPVFuncImplTextureCast
SPVFuncImplTextureCast,
SPVFuncImplMulExtended,
};
// If the underlying resource has been used for comparison then duplicate loads of that resource must be too

View File

@@ -637,6 +637,8 @@ void CompilerReflection::emit_resources(const char *tag, const SmallVector<Resou
json_stream->emit_json_key_value("WeightTextureQCOM", get_decoration(res.id, DecorationWeightTextureQCOM));
if (mask.get(DecorationBlockMatchTextureQCOM))
json_stream->emit_json_key_value("BlockMatchTextureQCOM", get_decoration(res.id, DecorationBlockMatchTextureQCOM));
if (mask.get(DecorationBlockMatchSamplerQCOM))
json_stream->emit_json_key_value("BlockMatchSamplerQCOM", get_decoration(res.id, DecorationBlockMatchSamplerQCOM));
// For images, the type itself adds a layout qualifer.
// Only emit the format for storage images.