CompilerMSL declare threadgroup variables accessed in called functions.

This commit is contained in:
Bill Hollings 2018-01-24 15:38:17 -05:00
parent 3fc2561734
commit fe3683eefa
5 changed files with 67 additions and 11 deletions

View File

@ -0,0 +1,11 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
kernel void main0()
{
threadgroup int foo[1337];
foo[0] = 13;
}

View File

@ -0,0 +1,18 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
void myfunc(threadgroup int* foo)
{
foo[0] = 13;
}
kernel void main0()
{
threadgroup int foo[1337];
myfunc(foo);
}

View File

@ -0,0 +1,12 @@
#version 450
shared int foo[1337];
void myfunc()
{
foo[0]=13;
}
void main()
{
myfunc();
}

View File

@ -6932,15 +6932,22 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
// function arguments. This is necessary for shader languages that do not support global // function arguments. This is necessary for shader languages that do not support global
// access to shader input content from within a function (eg. Metal). Each additional // access to shader input content from within a function (eg. Metal). Each additional
// function args uses the name of the global variable. Function nesting will modify the // function args uses the name of the global variable. Function nesting will modify the
// functions and calls all the way up the nesting chain. // functions and function calls all the way up the nesting chain.
void CompilerGLSL::append_global_func_args(const SPIRFunction &func, uint32_t index, vector<string> &arglist) void CompilerGLSL::append_global_func_args(const SPIRFunction &func, uint32_t index, vector<string> &arglist)
{ {
auto &args = func.arguments; auto &args = func.arguments;
uint32_t arg_cnt = uint32_t(args.size()); uint32_t arg_cnt = uint32_t(args.size());
for (uint32_t arg_idx = index; arg_idx < arg_cnt; arg_idx++) for (uint32_t arg_idx = index; arg_idx < arg_cnt; arg_idx++)
{ {
assert(args[arg_idx].alias_global_variable); auto &arg = args[arg_idx];
arglist.push_back(to_func_call_arg(args[arg_idx].id)); assert(arg.alias_global_variable);
arglist.push_back(to_func_call_arg(arg.id));
// If the underlying variable needs to be declared
// (ie. a local variable with deferred declaration), do so now.
uint32_t var_id = get<SPIRVariable>(arg.id).basevariable;
if (var_id)
flush_variable_declaration(var_id);
} }
} }

View File

@ -2637,19 +2637,27 @@ string CompilerMSL::get_argument_address_space(const SPIRVariable &argument)
{ {
const auto &type = get<SPIRType>(argument.basetype); const auto &type = get<SPIRType>(argument.basetype);
if ((type.basetype == SPIRType::Struct) && switch (type.storage)
(type.storage == StorageClassUniform || type.storage == StorageClassUniformConstant ||
type.storage == StorageClassPushConstant || type.storage == StorageClassStorageBuffer))
{ {
if (type.storage == StorageClassStorageBuffer) case StorageClassWorkgroup:
return "device"; return "threadgroup";
else
{ case StorageClassStorageBuffer:
return "device";
case StorageClassUniform:
case StorageClassUniformConstant:
case StorageClassPushConstant:
if (type.basetype == SPIRType::Struct)
return ((meta[type.self].decoration.decoration_flags & (1ull << DecorationBufferBlock)) != 0 && return ((meta[type.self].decoration.decoration_flags & (1ull << DecorationBufferBlock)) != 0 &&
(meta[argument.self].decoration.decoration_flags & (1ull << DecorationNonWritable)) == 0) ? (meta[argument.self].decoration.decoration_flags & (1ull << DecorationNonWritable)) == 0) ?
"device" : "device" :
"constant"; "constant";
}
break;
default:
break;
} }
return "thread"; return "thread";