MSL: Add support for SubgroupSize / SubgroupInvocationID in fragment.

This commit is contained in:
Hans-Kristian Arntzen 2019-06-24 12:31:54 +02:00
parent 9c57364f18
commit ab3798fd91
4 changed files with 72 additions and 4 deletions

View File

@ -0,0 +1,18 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
uint2 FragColor [[color(0)]];
};
fragment main0_out main0(uint gl_SubgroupSize [[threads_per_simdgroup]], uint gl_SubgroupInvocationID [[thread_index_in_simdgroup]])
{
main0_out out = {};
out.FragColor.x = gl_SubgroupSize;
out.FragColor.y = gl_SubgroupInvocationID;
return out;
}

View File

@ -0,0 +1,18 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
uint2 FragColor [[color(0)]];
};
fragment main0_out main0(uint gl_SubgroupSize [[threads_per_simdgroup]], uint gl_SubgroupInvocationID [[thread_index_in_simdgroup]])
{
main0_out out = {};
out.FragColor.x = gl_SubgroupSize;
out.FragColor.y = gl_SubgroupInvocationID;
return out;
}

View File

@ -0,0 +1,10 @@
#version 450
#extension GL_KHR_shader_subgroup_basic : require
layout(location = 0) out uvec2 FragColor;
void main()
{
FragColor.x = gl_SubgroupSize;
FragColor.y = gl_SubgroupInvocationID;
}

View File

@ -7820,7 +7820,18 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
return "thread_index_in_threadgroup";
case BuiltInSubgroupSize:
return "thread_execution_width";
if (execution.model == ExecutionModelFragment)
{
if (!msl_options.supports_msl_version(2, 2))
SPIRV_CROSS_THROW("threads_per_simdgroup requires Metal 2.2 in fragment shaders.");
return "threads_per_simdgroup";
}
else
{
// thread_execution_width is an alias for threads_per_simdgroup, and it's only available since 1.0,
// but not in fragment.
return "thread_execution_width";
}
case BuiltInNumSubgroups:
if (!msl_options.supports_msl_version(2))
@ -7833,9 +7844,18 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
return msl_options.is_ios() ? "quadgroup_index_in_threadgroup" : "simdgroup_index_in_threadgroup";
case BuiltInSubgroupLocalInvocationId:
if (!msl_options.supports_msl_version(2))
SPIRV_CROSS_THROW("Subgroup builtins require Metal 2.0.");
return msl_options.is_ios() ? "thread_index_in_quadgroup" : "thread_index_in_simdgroup";
if (execution.model == ExecutionModelFragment)
{
if (!msl_options.supports_msl_version(2, 2))
SPIRV_CROSS_THROW("thread_index_in_simdgroup requires Metal 2.2 in fragment shaders.");
return "thread_index_in_simdgroup";
}
else
{
if (!msl_options.supports_msl_version(2))
SPIRV_CROSS_THROW("Subgroup builtins require Metal 2.0.");
return msl_options.is_ios() ? "thread_index_in_quadgroup" : "thread_index_in_simdgroup";
}
case BuiltInSubgroupEqMask:
case BuiltInSubgroupGeMask:
@ -8519,6 +8539,8 @@ void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &exp
case BuiltInViewportIndex:
case BuiltInFragStencilRefEXT:
case BuiltInPrimitiveId:
case BuiltInSubgroupSize:
case BuiltInSubgroupLocalInvocationId:
expected_type = SPIRType::UInt;
break;