MSL: Support stencil export.

This commit is contained in:
Hans-Kristian Arntzen 2019-06-12 10:06:59 +02:00
parent a9da59b0b8
commit 14d0a1eb0c
4 changed files with 86 additions and 3 deletions

View File

@ -0,0 +1,22 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 MRT0 [[color(0)]];
float4 MRT1 [[color(1)]];
uint gl_FragStencilRefARB [[stencil]];
};
fragment main0_out main0()
{
main0_out out = {};
out.MRT0 = float4(1.0);
out.MRT1 = float4(1.0, 0.0, 1.0, 1.0);
out.gl_FragStencilRefARB = uint(100);
out.gl_FragStencilRefARB = uint(int(out.gl_FragStencilRefARB) + 10);
return out;
}

View File

@ -0,0 +1,29 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 MRT0 [[color(0)]];
float4 MRT1 [[color(1)]];
uint gl_FragStencilRefARB [[stencil]];
};
void update_stencil(thread uint& gl_FragStencilRefARB)
{
gl_FragStencilRefARB = uint(int(gl_FragStencilRefARB) + 10);
}
fragment main0_out main0()
{
main0_out out = {};
out.MRT0 = float4(1.0);
out.MRT1 = float4(1.0, 0.0, 1.0, 1.0);
out.gl_FragStencilRefARB = uint(100);
update_stencil(out.gl_FragStencilRefARB);
return out;
}

View File

@ -0,0 +1,17 @@
#version 450
#extension GL_ARB_shader_stencil_export : require
layout(location = 0) out vec4 MRT0;
layout(location = 1) out vec4 MRT1;
void update_stencil()
{
gl_FragStencilRefARB += 10;
}
void main()
{
MRT0 = vec4(1.0);
MRT1 = vec4(1.0, 0.0, 1.0, 1.0);
gl_FragStencilRefARB = 100;
update_stencil();
}

View File

@ -1956,7 +1956,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
bool is_interface_block_builtin = bool is_interface_block_builtin =
(bi_type == BuiltInPosition || bi_type == BuiltInPointSize || bi_type == BuiltInClipDistance || (bi_type == BuiltInPosition || bi_type == BuiltInPointSize || bi_type == BuiltInClipDistance ||
bi_type == BuiltInCullDistance || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex || bi_type == BuiltInCullDistance || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
bi_type == BuiltInFragDepth || bi_type == BuiltInSampleMask) || bi_type == BuiltInFragDepth || bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask) ||
(get_execution_model() == ExecutionModelTessellationEvaluation && (get_execution_model() == ExecutionModelTessellationEvaluation &&
(bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner)); (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner));
@ -2090,7 +2090,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
set_name(ib_type_id, to_name(ir.default_entry_point) + "_" + ib_var_ref); set_name(ib_type_id, to_name(ir.default_entry_point) + "_" + ib_var_ref);
set_name(ib_var_id, ib_var_ref); set_name(ib_var_id, ib_var_ref);
for (auto p_var : vars) for (auto *p_var : vars)
{ {
bool strip_array = bool strip_array =
(get_execution_model() == ExecutionModelTessellationControl || (get_execution_model() == ExecutionModelTessellationControl ||
@ -2188,7 +2188,8 @@ uint32_t CompilerMSL::ensure_correct_builtin_type(uint32_t type_id, BuiltIn buil
auto &type = get<SPIRType>(type_id); auto &type = get<SPIRType>(type_id);
if ((builtin == BuiltInSampleMask && is_array(type)) || if ((builtin == BuiltInSampleMask && is_array(type)) ||
((builtin == BuiltInLayer || builtin == BuiltInViewportIndex) && type.basetype != SPIRType::UInt)) ((builtin == BuiltInLayer || builtin == BuiltInViewportIndex || builtin == BuiltInFragStencilRefEXT) &&
type.basetype != SPIRType::UInt))
{ {
uint32_t next_id = ir.increase_bound_by(type.pointer ? 2 : 1); uint32_t next_id = ir.increase_bound_by(type.pointer ? 2 : 1);
uint32_t base_type_id = next_id++; uint32_t base_type_id = next_id++;
@ -5632,6 +5633,11 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
{ {
switch (builtin) switch (builtin)
{ {
case BuiltInFragStencilRefEXT:
if (!msl_options.supports_msl_version(2, 1))
SPIRV_CROSS_THROW("Stencil export only supported in MSL 2.1 and up.");
return string(" [[") + builtin_qualifier(builtin) + "]]";
case BuiltInSampleMask: case BuiltInSampleMask:
case BuiltInFragDepth: case BuiltInFragDepth:
return string(" [[") + builtin_qualifier(builtin) + "]]"; return string(" [[") + builtin_qualifier(builtin) + "]]";
@ -7526,6 +7532,7 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
case BuiltInCullDistance: case BuiltInCullDistance:
case BuiltInLayer: case BuiltInLayer:
case BuiltInFragDepth: case BuiltInFragDepth:
case BuiltInFragStencilRefEXT:
case BuiltInSampleMask: case BuiltInSampleMask:
if (get_execution_model() == ExecutionModelTessellationControl) if (get_execution_model() == ExecutionModelTessellationControl)
break; break;
@ -7657,6 +7664,9 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
else else
return "depth(any)"; return "depth(any)";
case BuiltInFragStencilRefEXT:
return "stencil";
// Compute function in // Compute function in
case BuiltInGlobalInvocationId: case BuiltInGlobalInvocationId:
return "thread_position_in_grid"; return "thread_position_in_grid";
@ -7780,6 +7790,9 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin)
case BuiltInFragDepth: case BuiltInFragDepth:
return "float"; return "float";
case BuiltInFragStencilRefEXT:
return "uint";
// Compute function in // Compute function in
case BuiltInGlobalInvocationId: case BuiltInGlobalInvocationId:
case BuiltInLocalInvocationId: case BuiltInLocalInvocationId:
@ -8339,6 +8352,7 @@ void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &exp
case BuiltInNumWorkgroups: case BuiltInNumWorkgroups:
case BuiltInLayer: case BuiltInLayer:
case BuiltInViewportIndex: case BuiltInViewportIndex:
case BuiltInFragStencilRefEXT:
expected_type = SPIRType::UInt; expected_type = SPIRType::UInt;
break; break;
@ -8379,6 +8393,7 @@ void CompilerMSL::bitcast_to_builtin_store(uint32_t target_id, std::string &expr
{ {
case BuiltInLayer: case BuiltInLayer:
case BuiltInViewportIndex: case BuiltInViewportIndex:
case BuiltInFragStencilRefEXT:
expected_type = SPIRType::UInt; expected_type = SPIRType::UInt;
break; break;