Emit KHR barycentrics if source enables the KHR extension.

For roundtrip purposes, need to match KHR or NV extension.
This commit is contained in:
Hans-Kristian Arntzen 2022-05-27 13:27:48 +02:00
parent 0aedc7d128
commit e45d01c41f
7 changed files with 71 additions and 37 deletions

View File

@ -15,14 +15,14 @@ struct main0_out
struct main0_in
{
float3 gl_BaryCoordNoPerspNV [[barycentric_coord, center_no_perspective]];
float3 gl_BaryCoordNoPerspEXT [[barycentric_coord, center_no_perspective]];
};
fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[buffer(0)]], uint gl_PrimitiveID [[primitive_id]])
{
main0_out out = {};
int _23 = 3 * int(gl_PrimitiveID);
out.value = ((_19.uvs[_23] * in.gl_BaryCoordNoPerspNV.x) + (_19.uvs[_23 + 1] * in.gl_BaryCoordNoPerspNV.y)) + (_19.uvs[_23 + 2] * in.gl_BaryCoordNoPerspNV.z);
out.value = ((_19.uvs[_23] * in.gl_BaryCoordNoPerspEXT.x) + (_19.uvs[_23 + 1] * in.gl_BaryCoordNoPerspEXT.y)) + (_19.uvs[_23 + 2] * in.gl_BaryCoordNoPerspEXT.z);
return out;
}

View File

@ -15,14 +15,14 @@ struct main0_out
struct main0_in
{
float3 gl_BaryCoordNV [[barycentric_coord, center_perspective]];
float3 gl_BaryCoordEXT [[barycentric_coord, center_perspective]];
};
fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[buffer(0)]], uint gl_PrimitiveID [[primitive_id]])
{
main0_out out = {};
int _23 = 3 * int(gl_PrimitiveID);
out.value = ((_19.uvs[_23] * in.gl_BaryCoordNV.x) + (_19.uvs[_23 + 1] * in.gl_BaryCoordNV.y)) + (_19.uvs[_23 + 2] * in.gl_BaryCoordNV.z);
out.value = ((_19.uvs[_23] * in.gl_BaryCoordEXT.x) + (_19.uvs[_23 + 1] * in.gl_BaryCoordEXT.y)) + (_19.uvs[_23 + 2] * in.gl_BaryCoordEXT.z);
return out;
}

View File

@ -15,7 +15,7 @@ struct main0_out
struct main0_in
{
float3 gl_BaryCoordNoPerspNV [[barycentric_coord, center_no_perspective]];
float3 gl_BaryCoordNoPerspEXT [[barycentric_coord, center_no_perspective]];
};
fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[buffer(0)]], uint gl_PrimitiveID [[primitive_id]])
@ -25,7 +25,7 @@ fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[
float2 uv0 = _19.uvs[(3 * prim) + 0];
float2 uv1 = _19.uvs[(3 * prim) + 1];
float2 uv2 = _19.uvs[(3 * prim) + 2];
out.value = ((uv0 * in.gl_BaryCoordNoPerspNV.x) + (uv1 * in.gl_BaryCoordNoPerspNV.y)) + (uv2 * in.gl_BaryCoordNoPerspNV.z);
out.value = ((uv0 * in.gl_BaryCoordNoPerspEXT.x) + (uv1 * in.gl_BaryCoordNoPerspEXT.y)) + (uv2 * in.gl_BaryCoordNoPerspEXT.z);
return out;
}

View File

@ -15,7 +15,7 @@ struct main0_out
struct main0_in
{
float3 gl_BaryCoordNV [[barycentric_coord, center_perspective]];
float3 gl_BaryCoordEXT [[barycentric_coord, center_perspective]];
};
fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[buffer(0)]], uint gl_PrimitiveID [[primitive_id]])
@ -25,7 +25,7 @@ fragment main0_out main0(main0_in in [[stage_in]], const device Vertices& _19 [[
float2 uv0 = _19.uvs[(3 * prim) + 0];
float2 uv1 = _19.uvs[(3 * prim) + 1];
float2 uv2 = _19.uvs[(3 * prim) + 2];
out.value = ((uv0 * in.gl_BaryCoordNV.x) + (uv1 * in.gl_BaryCoordNV.y)) + (uv2 * in.gl_BaryCoordNV.z);
out.value = ((uv0 * in.gl_BaryCoordEXT.x) + (uv1 * in.gl_BaryCoordEXT.y)) + (uv2 * in.gl_BaryCoordEXT.z);
return out;
}

View File

@ -619,6 +619,11 @@ void CompilerGLSL::find_static_extensions()
SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders.");
require_extension_internal("GL_OVR_multiview2");
}
// KHR one is likely to get promoted at some point, so if we don't see an explicit SPIR-V extension, assume KHR.
for (auto &ext : ir.declared_extensions)
if (ext == "SPV_NV_fragment_shader_barycentric")
barycentric_is_nv = true;
}
void CompilerGLSL::ray_tracing_khr_fixup_locations()
@ -1206,14 +1211,23 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags)
res += "__explicitInterpAMD ";
}
if (flags.get(DecorationPerVertexNV))
if (flags.get(DecorationPerVertexKHR))
{
if (options.es && options.version < 320)
SPIRV_CROSS_THROW("pervertexNV requires ESSL 320.");
SPIRV_CROSS_THROW("pervertexEXT requires ESSL 320.");
else if (!options.es && options.version < 450)
SPIRV_CROSS_THROW("pervertexNV requires GLSL 450.");
require_extension_internal("GL_NV_fragment_shader_barycentric");
res += "pervertexNV ";
SPIRV_CROSS_THROW("pervertexEXT requires GLSL 450.");
if (barycentric_is_nv)
{
require_extension_internal("GL_NV_fragment_shader_barycentric");
res += "pervertexNV ";
}
else
{
require_extension_internal("GL_EXT_fragment_shader_barycentric");
res += "pervertexEXT ";
}
}
return res;
@ -8758,24 +8772,42 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
case BuiltInIncomingRayFlagsKHR:
return ray_tracing_is_khr ? "gl_IncomingRayFlagsEXT" : "gl_IncomingRayFlagsNV";
case BuiltInBaryCoordNV:
case BuiltInBaryCoordKHR:
{
if (options.es && options.version < 320)
SPIRV_CROSS_THROW("gl_BaryCoordNV requires ESSL 320.");
SPIRV_CROSS_THROW("gl_BaryCoordEXT requires ESSL 320.");
else if (!options.es && options.version < 450)
SPIRV_CROSS_THROW("gl_BaryCoordNV requires GLSL 450.");
require_extension_internal("GL_NV_fragment_shader_barycentric");
return "gl_BaryCoordNV";
SPIRV_CROSS_THROW("gl_BaryCoordEXT requires GLSL 450.");
if (barycentric_is_nv)
{
require_extension_internal("GL_NV_fragment_shader_barycentric");
return "gl_BaryCoordNV";
}
else
{
require_extension_internal("GL_EXT_fragment_shader_barycentric");
return "gl_BaryCoordEXT";
}
}
case BuiltInBaryCoordNoPerspNV:
{
if (options.es && options.version < 320)
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires ESSL 320.");
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires ESSL 320.");
else if (!options.es && options.version < 450)
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires GLSL 450.");
require_extension_internal("GL_NV_fragment_shader_barycentric");
return "gl_BaryCoordNoPerspNV";
SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires GLSL 450.");
if (barycentric_is_nv)
{
require_extension_internal("GL_NV_fragment_shader_barycentric");
return "gl_BaryCoordNoPerspNV";
}
else
{
require_extension_internal("GL_EXT_fragment_shader_barycentric");
return "gl_BaryCoordNoPerspEXT";
}
}
case BuiltInFragStencilRefEXT:

View File

@ -877,6 +877,7 @@ protected:
bool requires_transpose_3x3 = false;
bool requires_transpose_4x4 = false;
bool ray_tracing_is_khr = false;
bool barycentric_is_nv = false;
void ray_tracing_khr_fixup_locations();
bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure);

View File

@ -3175,6 +3175,9 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st
return;
}
if (storage == StorageClassInput && has_decoration(var.self, DecorationPerVertexKHR))
SPIRV_CROSS_THROW("PerVertexKHR decoration is not supported in MSL.");
// If variable names alias, they will end up with wrong names in the interface struct, because
// there might be aliases in the member name cache and there would be a mismatch in fixup_in code.
// Make sure to register the variables as unique resource names ahead of time.
@ -3458,7 +3461,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
bool builtin_is_stage_in_out = builtin_is_gl_in_out ||
bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV ||
bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR ||
bi_type == BuiltInFragDepth ||
bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask;
@ -3515,7 +3518,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
}
// Barycentric inputs must be emitted in stage-in, because they can have interpolation arguments.
if (is_active && (bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV))
if (is_active && (bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR))
{
if (has_seen_barycentric)
SPIRV_CROSS_THROW("Cannot declare both BaryCoordNV and BaryCoordNoPerspNV in same shader in MSL.");
@ -11072,8 +11075,8 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
case BuiltInSampleId:
case BuiltInSampleMask:
case BuiltInLayer:
case BuiltInBaryCoordNV:
case BuiltInBaryCoordNoPerspNV:
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
quals = builtin_qualifier(builtin);
break;
@ -11089,7 +11092,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
else
quals = member_location_attribute_qualifier(type, index);
if (builtin == BuiltInBaryCoordNV || builtin == BuiltInBaryCoordNoPerspNV)
if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR)
{
if (has_member_decoration(type.self, index, DecorationFlat) ||
has_member_decoration(type.self, index, DecorationCentroid) ||
@ -11555,8 +11558,8 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type)
// Fragment function in
case BuiltInSamplePosition:
case BuiltInHelperInvocation:
case BuiltInBaryCoordNV:
case BuiltInBaryCoordNoPerspNV:
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
return false;
case BuiltInViewIndex:
return get_execution_model() == ExecutionModelFragment && msl_options.multiview &&
@ -14494,8 +14497,8 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
break;
case BuiltInBaryCoordNV:
case BuiltInBaryCoordNoPerspNV:
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point))
return stage_in_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
break;
@ -14732,16 +14735,14 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
// Shouldn't be reached.
SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL.");
case BuiltInBaryCoordNV:
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
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 BuiltInBaryCoordNoPerspNV:
// TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3.
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))
@ -14831,8 +14832,8 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id)
case BuiltInHelperInvocation:
return "bool";
case BuiltInBaryCoordNV:
case BuiltInBaryCoordNoPerspNV:
case BuiltInBaryCoordKHR:
case BuiltInBaryCoordNoPerspKHR:
// Use the type as declared, can be 1, 2 or 3 components.
return type_to_glsl(get_variable_data_type(get<SPIRVariable>(id)));