MSL: Correctly analyze if builtin block is active.
Need to consider all members, bi_type is invalid for Blocks, need to look at member decorations.
This commit is contained in:
parent
cea934c03f
commit
a159334895
@ -0,0 +1,30 @@
|
|||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float gl_ClipDistance[2];
|
||||||
|
float gl_CullDistance[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct main0_in
|
||||||
|
{
|
||||||
|
uint3 m_57;
|
||||||
|
ushort2 m_61;
|
||||||
|
float gl_ClipDistance[2];
|
||||||
|
float gl_CullDistance[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
kernel void main0(uint3 gl_GlobalInvocationID [[thread_position_in_grid]], device main0_out* spvOut [[buffer(28)]], constant uint* spvIndirectParams [[buffer(29)]], device MTLQuadTessellationFactorsHalf* spvTessLevel [[buffer(26)]], device main0_in* spvIn [[buffer(22)]])
|
||||||
|
{
|
||||||
|
device main0_out* gl_out = &spvOut[gl_GlobalInvocationID.x - gl_GlobalInvocationID.x % 4];
|
||||||
|
device main0_in* gl_in = &spvIn[min(gl_GlobalInvocationID.x / 4, spvIndirectParams[1] - 1) * spvIndirectParams[0]];
|
||||||
|
uint gl_InvocationID = gl_GlobalInvocationID.x % 4;
|
||||||
|
uint gl_PrimitiveID = min(gl_GlobalInvocationID.x / 4, spvIndirectParams[1]);
|
||||||
|
gl_out[gl_InvocationID].gl_ClipDistance[0] = gl_in[gl_InvocationID].gl_ClipDistance[0];
|
||||||
|
gl_out[gl_InvocationID].gl_ClipDistance[1] = gl_in[gl_InvocationID].gl_ClipDistance[1];
|
||||||
|
gl_out[gl_InvocationID].gl_CullDistance[0] = gl_in[gl_InvocationID].gl_CullDistance[0];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(vertices = 4) out;
|
||||||
|
|
||||||
|
in gl_PerVertex
|
||||||
|
{
|
||||||
|
float gl_ClipDistance[2];
|
||||||
|
float gl_CullDistance[1];
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
out gl_PerVertex
|
||||||
|
{
|
||||||
|
float gl_ClipDistance[2];
|
||||||
|
float gl_CullDistance[1];
|
||||||
|
} gl_out[];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_out[gl_InvocationID].gl_ClipDistance[0] = gl_in[gl_InvocationID].gl_ClipDistance[0];
|
||||||
|
gl_out[gl_InvocationID].gl_ClipDistance[1] = gl_in[gl_InvocationID].gl_ClipDistance[1];
|
||||||
|
gl_out[gl_InvocationID].gl_CullDistance[0] = gl_in[gl_InvocationID].gl_CullDistance[0];
|
||||||
|
}
|
@ -3272,23 +3272,49 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
|
|||||||
auto &type = this->get<SPIRType>(var.basetype);
|
auto &type = this->get<SPIRType>(var.basetype);
|
||||||
|
|
||||||
bool is_builtin = is_builtin_variable(var);
|
bool is_builtin = is_builtin_variable(var);
|
||||||
auto bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
|
bool is_block = has_decoration(type.self, DecorationBlock);
|
||||||
|
|
||||||
|
auto bi_type = BuiltInMax;
|
||||||
|
bool builtin_is_gl_in_out = false;
|
||||||
|
if (is_builtin && !is_block)
|
||||||
|
{
|
||||||
|
bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
|
||||||
|
builtin_is_gl_in_out = bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
|
||||||
|
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_builtin && is_block)
|
||||||
|
builtin_is_gl_in_out = true;
|
||||||
|
|
||||||
uint32_t location = get_decoration(var_id, DecorationLocation);
|
uint32_t location = get_decoration(var_id, DecorationLocation);
|
||||||
|
|
||||||
|
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 == BuiltInFragDepth ||
|
||||||
|
bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask;
|
||||||
|
|
||||||
// These builtins are part of the stage in/out structs.
|
// These builtins are part of the stage in/out structs.
|
||||||
bool is_interface_block_builtin =
|
bool is_interface_block_builtin =
|
||||||
(bi_type == BuiltInPosition || bi_type == BuiltInPointSize || bi_type == BuiltInClipDistance ||
|
builtin_is_stage_in_out ||
|
||||||
bi_type == BuiltInCullDistance || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
|
(get_execution_model() == ExecutionModelTessellationEvaluation &&
|
||||||
bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV || bi_type == BuiltInFragDepth ||
|
(bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner));
|
||||||
bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask) ||
|
|
||||||
(get_execution_model() == ExecutionModelTessellationEvaluation &&
|
|
||||||
(bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner));
|
|
||||||
|
|
||||||
bool is_active = interface_variable_exists_in_entry_point(var.self);
|
bool is_active = interface_variable_exists_in_entry_point(var.self);
|
||||||
if (is_builtin && is_active)
|
if (is_builtin && is_active)
|
||||||
{
|
{
|
||||||
// Only emit the builtin if it's active in this entry point. Interface variable list might lie.
|
// Only emit the builtin if it's active in this entry point. Interface variable list might lie.
|
||||||
is_active = has_active_builtin(bi_type, storage);
|
if (is_block)
|
||||||
|
{
|
||||||
|
// If any builtin is active, the block is active.
|
||||||
|
uint32_t mbr_cnt = uint32_t(type.member_types.size());
|
||||||
|
for (uint32_t i = 0; !is_active && i < mbr_cnt; i++)
|
||||||
|
is_active = has_active_builtin(BuiltIn(get_member_decoration(type.self, i, DecorationBuiltIn)), storage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_active = has_active_builtin(bi_type, storage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filter_patch_decoration = (has_decoration(var_id, DecorationPatch) || is_patch_block(type)) == patch;
|
bool filter_patch_decoration = (has_decoration(var_id, DecorationPatch) || is_patch_block(type)) == patch;
|
||||||
|
Loading…
Reference in New Issue
Block a user