diff --git a/tools/shaderc/shaderc_metal.cpp b/tools/shaderc/shaderc_metal.cpp index f180edab0..120600c09 100644 --- a/tools/shaderc/shaderc_metal.cpp +++ b/tools/shaderc/shaderc_metal.cpp @@ -40,7 +40,7 @@ namespace bgfx #include namespace stl = tinystl; -#include "../../src/shader_spirv.h" +#include "../../src/shader.h" namespace bgfx { namespace metal { @@ -153,374 +153,6 @@ namespace bgfx { namespace metal }, }; - bool printAsm(uint32_t _offset, const SpvInstruction& _instruction, void* _userData) - { - BX_UNUSED(_userData); - char temp[512]; - toString(temp, sizeof(temp), _instruction); - BX_TRACE("%5d: %s", _offset, temp); - return true; - } - - struct SpvReflection - { - struct TypeId - { - enum Enum - { - Void, - Bool, - Int32, - Int64, - Uint32, - Uint64, - Float, - Double, - - Vector, - Matrix, - - Count - }; - - TypeId() - : baseType(Enum::Count) - , type(Enum::Count) - , numComponents(0) - { - } - - Enum baseType; - Enum type; - uint32_t numComponents; - - stl::string toString() - { - stl::string result; - - switch (type) - { - case Float: - result.append("float"); - break; - - case Vector: - bx::stringPrintf(result, "vec%d" - , numComponents - ); - break; - - case Matrix: - bx::stringPrintf(result, "mat%d" - , numComponents - ); - - default: - break; - } - - return result; - } - }; - - struct Id - { - struct Variable - { - Variable() - : decoration(SpvDecoration::Count) - , builtin(SpvBuiltin::Count) - , storageClass(SpvStorageClass::Count) - , location(UINT32_MAX) - , offset(UINT32_MAX) - , type(UINT32_MAX) - { - } - - stl::string name; - SpvDecoration::Enum decoration; - SpvBuiltin::Enum builtin; - SpvStorageClass::Enum storageClass; - uint32_t location; - uint32_t offset; - uint32_t type; - }; - - typedef stl::vector MemberArray; - - Variable var; - MemberArray members; - }; - - typedef stl::unordered_map TypeIdMap; - typedef stl::unordered_map IdMap; - - TypeIdMap typeIdMap; - IdMap idMap; - - stl::string getTypeName(uint32_t _typeId) - { - return getTypeId(_typeId).toString(); - } - - Id& getId(uint32_t _id) - { - IdMap::iterator it = idMap.find(_id); - if (it == idMap.end() ) - { - Id id; - stl::pair result = idMap.insert(stl::make_pair(_id, id) ); - it = result.first; - } - - return it->second; - } - - Id::Variable& get(uint32_t _id, uint32_t _idx) - { - Id& id = getId(_id); - id.members.resize(bx::uint32_max(_idx+1, uint32_t(id.members.size() ) ) ); - return id.members[_idx]; - } - - TypeId& getTypeId(uint32_t _id) - { - TypeIdMap::iterator it = typeIdMap.find(_id); - if (it == typeIdMap.end() ) - { - TypeId id; - stl::pair result = typeIdMap.insert(stl::make_pair(_id, id) ); - it = result.first; - } - - return it->second; - } - - void update(uint32_t _id, const stl::string& _name) - { - getId(_id).var.name = _name; - } - - BX_NO_INLINE void update(Id::Variable& _variable, SpvDecoration::Enum _decoration, uint32_t _literal) - { - _variable.decoration = _decoration; - switch (_decoration) - { - case SpvDecoration::Location: - _variable.location = _literal; - break; - - case SpvDecoration::Offset: - _variable.offset = _literal; - break; - - case SpvDecoration::BuiltIn: - _variable.builtin = SpvBuiltin::Enum(_literal); - break; - - default: - break; - } - } - - BX_NO_INLINE void update(Id::Variable& _variable, uint32_t _type, SpvStorageClass::Enum _storageClass) - { - _variable.type = _type; - _variable.storageClass = _storageClass; - } - - void update(uint32_t _id, SpvDecoration::Enum _decoration, uint32_t _literal) - { - update(getId(_id).var, _decoration, _literal); - } - - void update(uint32_t _id, uint32_t _type, SpvStorageClass::Enum _storageClass) - { - update(getId(_id).var, _type, _storageClass); - } - - void update(uint32_t _id, uint32_t _idx, const stl::string& _name) - { - Id::Variable& var = get(_id, _idx); - var.name = _name; - } - - BX_NO_INLINE void update(uint32_t _id, uint32_t _idx, SpvDecoration::Enum _decoration, uint32_t _literal) - { - update(get(_id, _idx), _decoration, _literal); - } - - void update(uint32_t _id, TypeId::Enum _type) - { - TypeId& type = getTypeId(_id); - type.type = _type; - } - - void update(uint32_t _id, TypeId::Enum _type, uint32_t _baseTypeId, uint32_t _numComonents) - { - TypeId& type = getTypeId(_id); - type.type = _type; - - type.baseType = getTypeId(_baseTypeId).type; - type.numComponents = _numComonents; - } - }; - - bool spvParse(uint32_t _offset, const SpvInstruction& _instruction, void* _userData) - { - BX_UNUSED(_offset); - SpvReflection* spv = (SpvReflection*)_userData; - - switch (_instruction.opcode) - { - case SpvOpcode::Name: - spv->update(_instruction.result - , _instruction.operand[0].literalString - ); - break; - - case SpvOpcode::Decorate: - spv->update(_instruction.operand[0].data - , SpvDecoration::Enum(_instruction.operand[1].data) - , _instruction.operand[2].data - ); - break; - - case SpvOpcode::MemberName: - spv->update(_instruction.result - , _instruction.operand[0].data - , _instruction.operand[1].literalString - ); - break; - - case SpvOpcode::MemberDecorate: - spv->update(_instruction.operand[0].data - , _instruction.operand[1].data - , SpvDecoration::Enum(_instruction.operand[2].data) - , _instruction.operand[3].data - ); - break; - - case SpvOpcode::Variable: - spv->update(_instruction.result - , _instruction.type - , SpvStorageClass::Enum(_instruction.operand[0].data) - ); - break; - - case SpvOpcode::TypeVoid: - spv->update(_instruction.result, SpvReflection::TypeId::Void); - break; - - case SpvOpcode::TypeBool: - spv->update(_instruction.result, SpvReflection::TypeId::Bool); - break; - - case SpvOpcode::TypeInt: - spv->update(_instruction.result - , 32 == _instruction.operand[0].data - ? 0 == _instruction.operand[1].data - ? SpvReflection::TypeId::Uint32 - : SpvReflection::TypeId::Int32 - : 0 == _instruction.operand[1].data - ? SpvReflection::TypeId::Uint64 - : SpvReflection::TypeId::Int64 - ); - break; - - case SpvOpcode::TypeFloat: - spv->update(_instruction.result - , 32 == _instruction.operand[0].data - ? SpvReflection::TypeId::Float - : SpvReflection::TypeId::Double - ); - break; - - case SpvOpcode::TypeVector: - spv->update(_instruction.result - , SpvReflection::TypeId::Vector - , _instruction.operand[0].data - , _instruction.operand[1].data - ); - break; - - case SpvOpcode::TypeMatrix: - spv->update(_instruction.result - , SpvReflection::TypeId::Matrix - , _instruction.operand[0].data - , _instruction.operand[1].data - ); - break; - - case SpvOpcode::TypeImage: - case SpvOpcode::TypeSampler: - case SpvOpcode::TypeSampledImage: - break; - - case SpvOpcode::TypeStruct: - for (uint32_t ii = 0, num = _instruction.numOperands; ii < num; ++ii) - { - SpvReflection::Id::Variable& var = spv->get(_instruction.result, ii); - var.type = _instruction.operand[ii].data; - } - break; - - default: - break; - } - - return true; - } - -#define DBG(...) // bx::debugPrintf(__VA_ARGS__) - - void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err) - { - BX_UNUSED(_writer); - - uint32_t magic; - bx::peek(_reader, magic); - - SpvReflection spvx; - - if (magic == SPV_CHUNK_HEADER) - { - SpirV spirv; - read(_reader, spirv, _err); - parse(spirv.shader, spvParse, &spvx, _err); - - for (SpvReflection::IdMap::const_iterator it = spvx.idMap.begin(), itEnd = spvx.idMap.end(); it != itEnd; ++it) - { - const SpvReflection::Id& id = it->second; - uint32_t num = uint32_t(id.members.size() ); - if (0 < num - && 0 != bx::strCmp(id.var.name.c_str(), "gl_PerVertex") ) - { - DBG("%3d: %s %d %s\n" - , it->first - , id.var.name.c_str() - , id.var.location - , getName(id.var.storageClass) - ); - DBG("{\n"); - for (uint32_t ii = 0; ii < num; ++ii) - { - const SpvReflection::Id::Variable& var = id.members[ii]; - DBG("\t\t%s %s %d %s\n" - , spvx.getTypeName(var.type).c_str() - , var.name.c_str() - , var.offset - , getName(var.storageClass) - ); - BX_UNUSED(var); - } - DBG("}\n"); - } - } - - } - } - static EShLanguage getLang(char _p) { switch (_p) @@ -879,10 +511,10 @@ namespace bgfx { namespace metal } else { - bx::Error err; - bx::WriterI* writer = bx::getDebugOut(); - bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) ); - disassemble(writer, &reader, &err); + if (g_verbose) + { + glslang::SpirvToolsDisassemble(std::cout, spirv, SPV_ENV_VULKAN_1_0); + } spirv_cross::CompilerReflection refl(spirv); spirv_cross::ShaderResources resourcesrefl = refl.get_shader_resources(); @@ -910,11 +542,6 @@ namespace bgfx { namespace metal if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0) ) { - if (g_verbose) - { - glslang::SpirvToolsDisassemble(std::cout, spirv, SPV_ENV_VULKAN_1_0); - } - spirv_cross::CompilerMSL msl(std::move(spirv) ); auto executionModel = msl.get_execution_model(); diff --git a/tools/shaderc/shaderc_spirv.cpp b/tools/shaderc/shaderc_spirv.cpp index 03dce482a..64fe89d4a 100644 --- a/tools/shaderc/shaderc_spirv.cpp +++ b/tools/shaderc/shaderc_spirv.cpp @@ -57,7 +57,6 @@ namespace bgfx namespace stl = tinystl; #include "../../src/shader.h" -#include "../../src/shader_spirv.h" #include "../../3rdparty/khronos/vulkan-local/vulkan.h" namespace bgfx { namespace spirv @@ -171,15 +170,6 @@ namespace bgfx { namespace spirv }, }; - bool printAsm(uint32_t _offset, const SpvInstruction& _instruction, void* _userData) - { - BX_UNUSED(_userData); - char temp[512]; - toString(temp, sizeof(temp), _instruction); - BX_TRACE("%5d: %s", _offset, temp); - return true; - } - bgfx::TextureComponentType::Enum SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType spirvBaseType, bool depth) { if (depth) @@ -268,365 +258,6 @@ namespace bgfx { namespace spirv bgfx::TextureFormat::Unknown, // spv::ImageFormatR64i = 41 }; - struct SpvReflection - { - struct TypeId - { - enum Enum - { - Void, - Bool, - Int32, - Int64, - Uint32, - Uint64, - Float, - Double, - - Vector, - Matrix, - - Count - }; - - TypeId() - : baseType(Enum::Count) - , type(Enum::Count) - , numComponents(0) - { - } - - Enum baseType; - Enum type; - uint32_t numComponents; - - stl::string toString() - { - stl::string result; - - switch (type) - { - case Float: - result.append("float"); - break; - - case Vector: - bx::stringPrintf(result, "vec%d" - , numComponents - ); - break; - - case Matrix: - bx::stringPrintf(result, "mat%d" - , numComponents - ); - - default: - break; - } - - return result; - } - }; - - struct Id - { - struct Variable - { - Variable() - : decoration(SpvDecoration::Count) - , builtin(SpvBuiltin::Count) - , storageClass(SpvStorageClass::Count) - , location(UINT32_MAX) - , offset(UINT32_MAX) - , type(UINT32_MAX) - { - } - - stl::string name; - SpvDecoration::Enum decoration; - SpvBuiltin::Enum builtin; - SpvStorageClass::Enum storageClass; - uint32_t location; - uint32_t offset; - uint32_t type; - }; - - typedef stl::vector MemberArray; - - Variable var; - MemberArray members; - }; - - typedef stl::unordered_map TypeIdMap; - typedef stl::unordered_map IdMap; - - TypeIdMap typeIdMap; - IdMap idMap; - - stl::string getTypeName(uint32_t _typeId) - { - return getTypeId(_typeId).toString(); - } - - Id& getId(uint32_t _id) - { - IdMap::iterator it = idMap.find(_id); - if (it == idMap.end() ) - { - Id id; - stl::pair result = idMap.insert(stl::make_pair(_id, id) ); - it = result.first; - } - - return it->second; - } - - Id::Variable& get(uint32_t _id, uint32_t _idx) - { - Id& id = getId(_id); - id.members.resize(bx::uint32_max(_idx+1, uint32_t(id.members.size() ) ) ); - return id.members[_idx]; - } - - TypeId& getTypeId(uint32_t _id) - { - TypeIdMap::iterator it = typeIdMap.find(_id); - if (it == typeIdMap.end() ) - { - TypeId id; - stl::pair result = typeIdMap.insert(stl::make_pair(_id, id) ); - it = result.first; - } - - return it->second; - } - - void update(uint32_t _id, const stl::string& _name) - { - getId(_id).var.name = _name; - } - - BX_NO_INLINE void update(Id::Variable& _variable, SpvDecoration::Enum _decoration, uint32_t _literal) - { - _variable.decoration = _decoration; - switch (_decoration) - { - case SpvDecoration::Location: - _variable.location = _literal; - break; - - case SpvDecoration::Offset: - _variable.offset = _literal; - break; - - case SpvDecoration::BuiltIn: - _variable.builtin = SpvBuiltin::Enum(_literal); - break; - - default: - break; - } - } - - BX_NO_INLINE void update(Id::Variable& _variable, uint32_t _type, SpvStorageClass::Enum _storageClass) - { - _variable.type = _type; - _variable.storageClass = _storageClass; - } - - void update(uint32_t _id, SpvDecoration::Enum _decoration, uint32_t _literal) - { - update(getId(_id).var, _decoration, _literal); - } - - void update(uint32_t _id, uint32_t _type, SpvStorageClass::Enum _storageClass) - { - update(getId(_id).var, _type, _storageClass); - } - - void update(uint32_t _id, uint32_t _idx, const stl::string& _name) - { - Id::Variable& var = get(_id, _idx); - var.name = _name; - } - - BX_NO_INLINE void update(uint32_t _id, uint32_t _idx, SpvDecoration::Enum _decoration, uint32_t _literal) - { - update(get(_id, _idx), _decoration, _literal); - } - - void update(uint32_t _id, TypeId::Enum _type) - { - TypeId& type = getTypeId(_id); - type.type = _type; - } - - void update(uint32_t _id, TypeId::Enum _type, uint32_t _baseTypeId, uint32_t _numComonents) - { - TypeId& type = getTypeId(_id); - type.type = _type; - - type.baseType = getTypeId(_baseTypeId).type; - type.numComponents = _numComonents; - } - }; - - bool spvParse(uint32_t _offset, const SpvInstruction& _instruction, void* _userData) - { - BX_UNUSED(_offset); - SpvReflection* spv = (SpvReflection*)_userData; - - switch (_instruction.opcode) - { - case SpvOpcode::Name: - spv->update(_instruction.result - , _instruction.operand[0].literalString - ); - break; - - case SpvOpcode::Decorate: - spv->update(_instruction.operand[0].data - , SpvDecoration::Enum(_instruction.operand[1].data) - , _instruction.operand[2].data - ); - break; - - case SpvOpcode::MemberName: - spv->update(_instruction.result - , _instruction.operand[0].data - , _instruction.operand[1].literalString - ); - break; - - case SpvOpcode::MemberDecorate: - spv->update(_instruction.operand[0].data - , _instruction.operand[1].data - , SpvDecoration::Enum(_instruction.operand[2].data) - , _instruction.operand[3].data - ); - break; - - case SpvOpcode::Variable: - spv->update(_instruction.result - , _instruction.type - , SpvStorageClass::Enum(_instruction.operand[0].data) - ); - break; - - case SpvOpcode::TypeVoid: - spv->update(_instruction.result, SpvReflection::TypeId::Void); - break; - - case SpvOpcode::TypeBool: - spv->update(_instruction.result, SpvReflection::TypeId::Bool); - break; - - case SpvOpcode::TypeInt: - spv->update(_instruction.result - , 32 == _instruction.operand[0].data - ? 0 == _instruction.operand[1].data - ? SpvReflection::TypeId::Uint32 - : SpvReflection::TypeId::Int32 - : 0 == _instruction.operand[1].data - ? SpvReflection::TypeId::Uint64 - : SpvReflection::TypeId::Int64 - ); - break; - - case SpvOpcode::TypeFloat: - spv->update(_instruction.result - , 32 == _instruction.operand[0].data - ? SpvReflection::TypeId::Float - : SpvReflection::TypeId::Double - ); - break; - - case SpvOpcode::TypeVector: - spv->update(_instruction.result - , SpvReflection::TypeId::Vector - , _instruction.operand[0].data - , _instruction.operand[1].data - ); - break; - - case SpvOpcode::TypeMatrix: - spv->update(_instruction.result - , SpvReflection::TypeId::Matrix - , _instruction.operand[0].data - , _instruction.operand[1].data - ); - break; - - case SpvOpcode::TypeImage: - case SpvOpcode::TypeSampler: - case SpvOpcode::TypeSampledImage: - break; - - case SpvOpcode::TypeStruct: - for (uint32_t ii = 0, num = _instruction.numOperands; ii < num; ++ii) - { - SpvReflection::Id::Variable& var = spv->get(_instruction.result, ii); - var.type = _instruction.operand[ii].data; - } - break; - - default: - break; - } - - return true; - } - -#define DBG(...) // bx::debugPrintf(__VA_ARGS__) - - void disassemble(bx::WriterI* _writer, bx::ReaderSeekerI* _reader, bx::Error* _err) - { - BX_UNUSED(_writer); - - uint32_t magic; - bx::peek(_reader, magic); - - SpvReflection spvx; - - if (magic == SPV_CHUNK_HEADER) - { - SpirV spirv; - read(_reader, spirv, _err); - parse(spirv.shader, spvParse, &spvx, _err); - - for (SpvReflection::IdMap::const_iterator it = spvx.idMap.begin(), itEnd = spvx.idMap.end(); it != itEnd; ++it) - { - const SpvReflection::Id& id = it->second; - uint32_t num = uint32_t(id.members.size() ); - if (0 < num - && 0 != bx::strCmp(id.var.name.c_str(), "gl_PerVertex") ) - { - DBG("%3d: %s %d %s\n" - , it->first - , id.var.name.c_str() - , id.var.location - , getName(id.var.storageClass) - ); - DBG("{\n"); - for (uint32_t ii = 0; ii < num; ++ii) - { - const SpvReflection::Id::Variable& var = id.members[ii]; - DBG("\t\t%s %s %d %s\n" - , spvx.getTypeName(var.type).c_str() - , var.name.c_str() - , var.offset - , getName(var.storageClass) - ); - BX_UNUSED(var); - } - DBG("}\n"); - } - } - - } - } - static EShLanguage getLang(char _p) { switch (_p) @@ -1082,19 +713,14 @@ namespace bgfx { namespace spirv } else { - bx::Error err; - bx::WriterI* writer = bx::getDebugOut(); - bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) ); - disassemble(writer, &reader, &err); + if (g_verbose) + { + glslang::SpirvToolsDisassemble(std::cout, spirv, getSpirvTargetVersion(_version)); + } spirv_cross::CompilerReflection refl(spirv); spirv_cross::ShaderResources resourcesrefl = refl.get_shader_resources(); - if (g_verbose) - { - glslang::SpirvToolsDisassemble(std::cout, spirv, getSpirvTargetVersion(_version) ); - } - // Loop through the separate_images, and extract the uniform names: for (auto &resource : resourcesrefl.separate_images) { @@ -1191,68 +817,11 @@ namespace bgfx { namespace spirv uint16_t size = writeUniformArray( _writer, uniforms, _options.shaderType == 'f'); - if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0) ) - { - spirv_cross::CompilerMSL msl(std::move(spirv) ); - - spirv_cross::ShaderResources resources = msl.get_shader_resources(); - - spirv_cross::SmallVector entryPoints = msl.get_entry_points_and_stages(); - if (!entryPoints.empty() ) - { - msl.rename_entry_point( - entryPoints[0].name - , "xlatMtlMain" - , entryPoints[0].execution_model - ); - } - - 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); - } - - for (auto &resource : resources.separate_images) - { - std::string name = msl.get_name(resource.id); - if (name.size() > 7 - && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") ) - { - msl.set_name(resource.id, name.substr(0, name.length() - 7) ); - } - } - - std::string source = msl.compile(); - - if ('c' == _options.shaderType) - { - 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); - } + 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);