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:
Chip Davis 2019-02-15 17:21:38 -06:00
Родитель 03b4d3c19f
Коммит 6b7988046d
5 изменённых файлов: 172 добавлений и 3 удалений

Просмотреть файл

@ -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;