Handle blocks of patch I/O.
In this case, each member of the block will be decorated with `DecorationPatch`, rather than the block variable having the decoration.
This commit is contained in:
Родитель
03b4d3c19f
Коммит
6b7988046d
|
@ -0,0 +1,55 @@
|
|||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Block
|
||||
{
|
||||
float4 a;
|
||||
float4 b;
|
||||
};
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float4 a;
|
||||
float4 b;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 vColor [[attribute(0)]];
|
||||
float4 Block_a [[attribute(2)]];
|
||||
float4 Block_b [[attribute(3)]];
|
||||
};
|
||||
|
||||
struct main0_patchIn
|
||||
{
|
||||
float4 vColors [[attribute(1)]];
|
||||
float4 Foo_a [[attribute(4)]];
|
||||
float4 Foo_b [[attribute(5)]];
|
||||
patch_control_point<main0_in> gl_in;
|
||||
};
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
Foo vFoo = {};
|
||||
vFoo.a = patchIn.Foo_a;
|
||||
vFoo.b = patchIn.Foo_b;
|
||||
out.gl_Position = patchIn.gl_in[0].Block_a;
|
||||
out.gl_Position += patchIn.gl_in[0].Block_b;
|
||||
out.gl_Position += patchIn.gl_in[1].Block_a;
|
||||
out.gl_Position += patchIn.gl_in[1].Block_b;
|
||||
out.gl_Position += patchIn.gl_in[0].vColor;
|
||||
out.gl_Position += patchIn.gl_in[1].vColor;
|
||||
out.gl_Position += patchIn.vColors;
|
||||
out.gl_Position += vFoo.a;
|
||||
out.gl_Position += vFoo.b;
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct Block
|
||||
{
|
||||
float4 a;
|
||||
float4 b;
|
||||
};
|
||||
|
||||
struct Foo
|
||||
{
|
||||
float4 a;
|
||||
float4 b;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 vColor [[attribute(0)]];
|
||||
float4 Block_a [[attribute(2)]];
|
||||
float4 Block_b [[attribute(3)]];
|
||||
};
|
||||
|
||||
struct main0_patchIn
|
||||
{
|
||||
float4 vColors [[attribute(1)]];
|
||||
float4 Foo_a [[attribute(4)]];
|
||||
float4 Foo_b [[attribute(5)]];
|
||||
patch_control_point<main0_in> gl_in;
|
||||
};
|
||||
|
||||
void set_from_function(thread float4& gl_Position, thread patch_control_point<main0_in>& gl_in, thread float4& vColors, thread Foo& vFoo)
|
||||
{
|
||||
gl_Position = gl_in[0].Block_a;
|
||||
gl_Position += gl_in[0].Block_b;
|
||||
gl_Position += gl_in[1].Block_a;
|
||||
gl_Position += gl_in[1].Block_b;
|
||||
gl_Position += gl_in[0].vColor;
|
||||
gl_Position += gl_in[1].vColor;
|
||||
gl_Position += vColors;
|
||||
gl_Position += vFoo.a;
|
||||
gl_Position += vFoo.b;
|
||||
}
|
||||
|
||||
[[ patch(quad, 0) ]] vertex main0_out main0(main0_patchIn patchIn [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
Foo vFoo = {};
|
||||
vFoo.a = patchIn.Foo_a;
|
||||
vFoo.b = patchIn.Foo_b;
|
||||
set_from_function(out.gl_Position, patchIn.gl_in, patchIn.vColors, vFoo);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#version 450
|
||||
|
||||
layout(ccw, quads, fractional_even_spacing) in;
|
||||
|
||||
layout(location = 0) in vec4 vColor[];
|
||||
layout(location = 1) patch in vec4 vColors;
|
||||
layout(location = 2) in Block
|
||||
{
|
||||
vec4 a;
|
||||
vec4 b;
|
||||
} blocks[];
|
||||
|
||||
struct Foo
|
||||
{
|
||||
vec4 a;
|
||||
vec4 b;
|
||||
};
|
||||
layout(location = 4) patch in Foo vFoo;
|
||||
|
||||
void set_from_function()
|
||||
{
|
||||
gl_Position = blocks[0].a;
|
||||
gl_Position += blocks[0].b;
|
||||
gl_Position += blocks[1].a;
|
||||
gl_Position += blocks[1].b;
|
||||
gl_Position += vColor[0];
|
||||
gl_Position += vColor[1];
|
||||
gl_Position += vColors;
|
||||
gl_Position += vFoo.a;
|
||||
gl_Position += vFoo.b;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
set_from_function();
|
||||
}
|
|
@ -878,7 +878,7 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
|
|||
|
||||
if (((is_tessellation_shader() && var.storage == StorageClassInput) ||
|
||||
(get_execution_model() == ExecutionModelTessellationControl && var.storage == StorageClassOutput)) &&
|
||||
!has_decoration(arg_id, DecorationPatch) &&
|
||||
!(has_decoration(arg_id, DecorationPatch) || is_patch_block(*p_type)) &&
|
||||
(!is_builtin_variable(var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
|
||||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance ||
|
||||
p_type->basetype == SPIRType::Struct))
|
||||
|
@ -1687,7 +1687,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
|
|||
BuiltIn bi_type = BuiltIn(get_decoration(var_id, DecorationBuiltIn));
|
||||
if (var.storage == storage && interface_variable_exists_in_entry_point(var.self) &&
|
||||
!is_hidden_variable(var, incl_builtins) && type.pointer &&
|
||||
has_decoration(var_id, DecorationPatch) == patch &&
|
||||
(has_decoration(var_id, DecorationPatch) || is_patch_block(type)) == patch &&
|
||||
(!is_builtin_variable(var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
|
||||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance || bi_type == BuiltInLayer ||
|
||||
bi_type == BuiltInViewportIndex || bi_type == BuiltInFragDepth || bi_type == BuiltInSampleMask ||
|
||||
|
@ -2925,7 +2925,7 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l
|
|||
if (var &&
|
||||
(var->storage == StorageClassInput ||
|
||||
(get_execution_model() == ExecutionModelTessellationControl && var->storage == StorageClassOutput)) &&
|
||||
!has_decoration(ops[2], DecorationPatch) &&
|
||||
!(has_decoration(ops[2], DecorationPatch) || is_patch_block(get_variable_data_type(*var))) &&
|
||||
(!is_builtin_variable(*var) || bi_type == BuiltInPosition || bi_type == BuiltInPointSize ||
|
||||
bi_type == BuiltInClipDistance || bi_type == BuiltInCullDistance ||
|
||||
get_variable_data_type(*var).basetype == SPIRType::Struct))
|
||||
|
@ -4652,6 +4652,21 @@ string CompilerMSL::to_swizzle_expression(uint32_t id)
|
|||
}
|
||||
}
|
||||
|
||||
// Checks whether the type is a Block all of whose members have DecorationPatch.
|
||||
bool CompilerMSL::is_patch_block(const SPIRType &type)
|
||||
{
|
||||
if (!has_decoration(type.self, DecorationBlock))
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < type.member_types.size(); i++)
|
||||
{
|
||||
if (!has_member_decoration(type.self, i, DecorationPatch))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checks whether the ID is a row_major matrix that requires conversion before use
|
||||
bool CompilerMSL::is_non_native_row_major_matrix(uint32_t id)
|
||||
{
|
||||
|
|
|
@ -388,6 +388,7 @@ protected:
|
|||
void replace_illegal_names() override;
|
||||
void declare_undefined_values() override;
|
||||
void declare_constant_arrays();
|
||||
bool is_patch_block(const SPIRType &type);
|
||||
bool is_non_native_row_major_matrix(uint32_t id) override;
|
||||
bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override;
|
||||
std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, bool is_packed) override;
|
||||
|
|
Загрузка…
Ссылка в новой задаче