metal compute shader generation

This commit is contained in:
attilaz
2019-01-14 09:24:06 +01:00
parent 3f3a9450ba
commit b9b58296c7
7 changed files with 88 additions and 24 deletions

View File

@@ -1046,7 +1046,14 @@ namespace bgfx
else if (0 == bx::strCmpI(platform, "osx") )
{
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];
bx::snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", metal);
preprocessor.setDefine(temp);
@@ -1327,8 +1334,7 @@ namespace bgfx
else
{
if (0 != glsl
|| 0 != essl
|| 0 != metal)
|| 0 != essl)
{
}
else
@@ -1456,9 +1462,9 @@ namespace bgfx
code += _comment;
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)
{

View File

@@ -14,6 +14,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
#include <ResourceLimits.h>
#include <SPIRV/SPVRemapper.h>
#include <SPIRV/GlslangToSpv.h>
#include <spirv_msl.hpp>
BX_PRAGMA_DIAGNOSTIC_POP()
namespace bgfx
@@ -799,12 +800,59 @@ namespace bgfx { namespace spirv
bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) );
disassemble(writer, &reader, &err);
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);
if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0))
{
if (g_verbose)
{
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();
bx::write(_writer, numAttr);