metal compute shader generation
This commit is contained in:
parent
3f3a9450ba
commit
b9b58296c7
@ -116,7 +116,7 @@ CS_BIN = $(addprefix $(BUILD_INTERMEDIATE_DIR)/, $(addsuffix .bin, $(basename $(
|
|||||||
BIN = $(VS_BIN) $(FS_BIN)
|
BIN = $(VS_BIN) $(FS_BIN)
|
||||||
ASM = $(VS_ASM) $(FS_ASM)
|
ASM = $(VS_ASM) $(FS_ASM)
|
||||||
|
|
||||||
ifeq ($(TARGET), $(filter $(TARGET),1 3 4 6))
|
ifeq ($(TARGET), $(filter $(TARGET),1 3 4 5 6))
|
||||||
BIN += $(CS_BIN)
|
BIN += $(CS_BIN)
|
||||||
ASM += $(CS_ASM)
|
ASM += $(CS_ASM)
|
||||||
endif
|
endif
|
||||||
|
@ -604,6 +604,8 @@ project "shaderc"
|
|||||||
|
|
||||||
path.join(GLSL_OPTIMIZER, "include"),
|
path.join(GLSL_OPTIMIZER, "include"),
|
||||||
path.join(GLSL_OPTIMIZER, "src/glsl"),
|
path.join(GLSL_OPTIMIZER, "src/glsl"),
|
||||||
|
|
||||||
|
SPIRV_CROSS,
|
||||||
}
|
}
|
||||||
|
|
||||||
links {
|
links {
|
||||||
|
@ -124,9 +124,15 @@
|
|||||||
#define IMAGE3D_WR( _name, _format, _reg) IMAGE3D_RW(_name, _format, _reg)
|
#define IMAGE3D_WR( _name, _format, _reg) IMAGE3D_RW(_name, _format, _reg)
|
||||||
#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg)
|
#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg)
|
||||||
|
|
||||||
|
#if BGFX_SHADER_LANGUAGE_METAL
|
||||||
|
#define BUFFER_RO(_name, _struct, _reg) StructuredBuffer<_struct> _name : REGISTER(t, _reg)
|
||||||
|
#define BUFFER_RW(_name, _struct, _reg) RWStructuredBuffer <_struct> _name : REGISTER(u, _reg)
|
||||||
|
#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg)
|
||||||
|
#else
|
||||||
#define BUFFER_RO(_name, _struct, _reg) Buffer<_struct> _name : REGISTER(t, _reg)
|
#define BUFFER_RO(_name, _struct, _reg) Buffer<_struct> _name : REGISTER(t, _reg)
|
||||||
#define BUFFER_RW(_name, _struct, _reg) RWBuffer<_struct> _name : REGISTER(u, _reg)
|
#define BUFFER_RW(_name, _struct, _reg) RWBuffer<_struct> _name : REGISTER(u, _reg)
|
||||||
#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg)
|
#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)]
|
#define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)]
|
||||||
|
|
||||||
|
@ -831,6 +831,7 @@ namespace bgfx { namespace mtl
|
|||||||
|
|
||||||
Function m_function;
|
Function m_function;
|
||||||
uint32_t m_hash;
|
uint32_t m_hash;
|
||||||
|
uint16_t m_numThreads[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SamplerInfo
|
struct SamplerInfo
|
||||||
@ -912,7 +913,7 @@ namespace bgfx { namespace mtl
|
|||||||
SamplerInfo m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
SamplerInfo m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||||
uint32_t m_samplerCount;
|
uint32_t m_samplerCount;
|
||||||
|
|
||||||
uint32_t m_numThreads[3];
|
uint16_t m_numThreads[3];
|
||||||
|
|
||||||
PredefinedUniform m_predefined[PredefinedUniform::Count*2];
|
PredefinedUniform m_predefined[PredefinedUniform::Count*2];
|
||||||
uint8_t m_numPredefined;
|
uint8_t m_numPredefined;
|
||||||
|
@ -1763,18 +1763,6 @@ namespace bgfx { namespace mtl
|
|||||||
MTLDataType dataType = uniform.dataType;
|
MTLDataType dataType = uniform.dataType;
|
||||||
uint32_t num = 1;
|
uint32_t num = 1;
|
||||||
|
|
||||||
if (dataType == MTLDataTypeInt && bx::strLen(name) > 14
|
|
||||||
&& 0 == bx::strCmp(name, "NUM_THREADS_", 12) )
|
|
||||||
{
|
|
||||||
const int32_t dim = name[12] - 'X';
|
|
||||||
|
|
||||||
if (dim >= 0
|
|
||||||
&& dim <= 2)
|
|
||||||
{
|
|
||||||
bx::fromString(&ps->m_numThreads[dim], bx::StringView(name, 14, INT_MAX));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataType == MTLDataTypeArray)
|
if (dataType == MTLDataTypeArray)
|
||||||
{
|
{
|
||||||
dataType = uniform.arrayType.elementType;
|
dataType = uniform.arrayType.elementType;
|
||||||
@ -2147,6 +2135,11 @@ namespace bgfx { namespace mtl
|
|||||||
ComputePipelineReflection reflection = NULL;
|
ComputePipelineReflection reflection = NULL;
|
||||||
pso->m_cps = m_device.newComputePipelineStateWithFunction(program.m_vsh->m_function, MTLPipelineOptionBufferTypeInfo, &reflection);
|
pso->m_cps = m_device.newComputePipelineStateWithFunction(program.m_vsh->m_function, MTLPipelineOptionBufferTypeInfo, &reflection);
|
||||||
processArguments(pso, reflection.arguments, NULL);
|
processArguments(pso, reflection.arguments, NULL);
|
||||||
|
|
||||||
|
for (uint32_t ii = 0; ii < 3; ++ii)
|
||||||
|
{
|
||||||
|
pso->m_numThreads[ii] = program.m_vsh->m_numThreads[ii];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return program.m_computePS;
|
return program.m_computePS;
|
||||||
@ -2378,6 +2371,14 @@ namespace bgfx { namespace mtl
|
|||||||
bx::read(&reader, regCount);
|
bx::read(&reader, regCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isShaderType(magic, 'C'))
|
||||||
|
{
|
||||||
|
for (uint32_t ii = 0; ii < 3; ++ii)
|
||||||
|
{
|
||||||
|
bx::read(&reader, m_numThreads[ii]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t shaderSize;
|
uint32_t shaderSize;
|
||||||
bx::read(&reader, shaderSize);
|
bx::read(&reader, shaderSize);
|
||||||
|
|
||||||
|
@ -1046,7 +1046,14 @@ namespace bgfx
|
|||||||
else if (0 == bx::strCmpI(platform, "osx") )
|
else if (0 == bx::strCmpI(platform, "osx") )
|
||||||
{
|
{
|
||||||
preprocessor.setDefine("BX_PLATFORM_OSX=1");
|
preprocessor.setDefine("BX_PLATFORM_OSX=1");
|
||||||
preprocessor.setDefine(glslDefine);
|
if (_options.shaderType == 'c')
|
||||||
|
{
|
||||||
|
preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preprocessor.setDefine(glslDefine);
|
||||||
|
}
|
||||||
char temp[256];
|
char temp[256];
|
||||||
bx::snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", metal);
|
bx::snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", metal);
|
||||||
preprocessor.setDefine(temp);
|
preprocessor.setDefine(temp);
|
||||||
@ -1327,8 +1334,7 @@ namespace bgfx
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (0 != glsl
|
if (0 != glsl
|
||||||
|| 0 != essl
|
|| 0 != essl)
|
||||||
|| 0 != metal)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1456,9 +1462,9 @@ namespace bgfx
|
|||||||
code += _comment;
|
code += _comment;
|
||||||
code += preprocessor.m_preprocessed;
|
code += preprocessor.m_preprocessed;
|
||||||
|
|
||||||
if (0 != spirv)
|
if (0 != spirv || 0 != metal)
|
||||||
{
|
{
|
||||||
compiled = compileSPIRVShader(_options, 0, code, _writer);
|
compiled = compileSPIRVShader(_options, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : 0, code, _writer);
|
||||||
}
|
}
|
||||||
else if (0 != pssl)
|
else if (0 != pssl)
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
|
|||||||
#include <ResourceLimits.h>
|
#include <ResourceLimits.h>
|
||||||
#include <SPIRV/SPVRemapper.h>
|
#include <SPIRV/SPVRemapper.h>
|
||||||
#include <SPIRV/GlslangToSpv.h>
|
#include <SPIRV/GlslangToSpv.h>
|
||||||
|
#include <spirv_msl.hpp>
|
||||||
BX_PRAGMA_DIAGNOSTIC_POP()
|
BX_PRAGMA_DIAGNOSTIC_POP()
|
||||||
|
|
||||||
namespace bgfx
|
namespace bgfx
|
||||||
@ -799,12 +800,59 @@ namespace bgfx { namespace spirv
|
|||||||
bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) );
|
bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) );
|
||||||
disassemble(writer, &reader, &err);
|
disassemble(writer, &reader, &err);
|
||||||
|
|
||||||
uint32_t shaderSize = (uint32_t)spirv.size()*sizeof(uint32_t);
|
if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0))
|
||||||
bx::write(_writer, shaderSize);
|
{
|
||||||
bx::write(_writer, spirv.data(), shaderSize);
|
if (g_verbose)
|
||||||
uint8_t nul = 0;
|
{
|
||||||
bx::write(_writer, nul);
|
glslang::SpirvToolsDisassemble(std::cout, spirv);
|
||||||
|
}
|
||||||
|
|
||||||
|
spirv_cross::CompilerMSL msl(std::move(spirv));
|
||||||
|
|
||||||
|
spirv_cross::ShaderResources resources = msl.get_shader_resources();
|
||||||
|
|
||||||
|
int numThreads[3];
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
numThreads[i] = msl.get_execution_mode_argument(spv::ExecutionMode::ExecutionModeLocalSize, i);
|
||||||
|
|
||||||
|
msl.rename_entry_point("main", "xlatMtlMain", spv::ExecutionModel::ExecutionModelGLCompute);
|
||||||
|
|
||||||
|
for (auto &resource : resources.uniform_buffers)
|
||||||
|
{
|
||||||
|
msl.set_name(resource.id, "_mtl_u");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &resource : resources.storage_buffers)
|
||||||
|
{
|
||||||
|
unsigned binding = msl.get_decoration(resource.id, spv::DecorationBinding);
|
||||||
|
msl.set_decoration(resource.id, spv::DecorationBinding, binding + 1);
|
||||||
|
|
||||||
|
// workaround spirv -> msl codegen problem: same name was used as struct type and function parameter name
|
||||||
|
msl.set_name(resource.id, "_" + msl.get_name(resource.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string source = msl.compile();
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
uint16_t dim = (uint16_t)msl.get_execution_mode_argument(spv::ExecutionMode::ExecutionModeLocalSize, i);
|
||||||
|
bx::write(_writer, dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t shaderSize = (uint32_t)source.size();
|
||||||
|
bx::write(_writer, shaderSize);
|
||||||
|
bx::write(_writer, source.c_str(), shaderSize);
|
||||||
|
uint8_t nul = 0;
|
||||||
|
bx::write(_writer, nul);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t shaderSize = (uint32_t)spirv.size() * sizeof(uint32_t);
|
||||||
|
bx::write(_writer, shaderSize);
|
||||||
|
bx::write(_writer, spirv.data(), shaderSize);
|
||||||
|
uint8_t nul = 0;
|
||||||
|
bx::write(_writer, nul);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
const uint8_t numAttr = (uint8_t)program->getNumLiveAttributes();
|
const uint8_t numAttr = (uint8_t)program->getNumLiveAttributes();
|
||||||
bx::write(_writer, numAttr);
|
bx::write(_writer, numAttr);
|
||||||
|
Loading…
Reference in New Issue
Block a user