int32_t write(bx::WriterI* _writer, const VertexDecl& _decl, bx::Error* _err) { BX_ERROR_SCOPE(_err); int32_t total = 0; uint8_t numAttrs = 0; for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { numAttrs += UINT16_MAX == _decl.m_attributes[attr] ? 0 : 1; } total += bx::write(_writer, numAttrs, _err); total += bx::write(_writer, _decl.m_stride, _err); for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { if (UINT16_MAX != _decl.m_attributes[attr]) { uint8_t num; AttribType::Enum type; bool normalized; bool asInt; _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); total += bx::write(_writer, _decl.m_offset[attr], _err); total += bx::write(_writer, s_attribToId[attr].id, _err); total += bx::write(_writer, num, _err); total += bx::write(_writer, s_attribTypeToId[type].id, _err); total += bx::write(_writer, normalized, _err); total += bx::write(_writer, asInt, _err); } } return total; }
int32_t read(bx::ReaderI* _reader, VertexDecl& _decl, bx::Error* _err) { BX_ERROR_SCOPE(_err); int32_t total = 0; uint8_t numAttrs; total += bx::read(_reader, numAttrs, _err); uint16_t stride; total += bx::read(_reader, stride, _err); if (!_err->isOk() ) { return total; } _decl.begin(); for (uint32_t ii = 0; ii < numAttrs; ++ii) { uint16_t offset; total += bx::read(_reader, offset, _err); uint16_t attribId = 0; total += bx::read(_reader, attribId, _err); uint8_t num; total += bx::read(_reader, num, _err); uint16_t attribTypeId; total += bx::read(_reader, attribTypeId, _err); bool normalized; total += bx::read(_reader, normalized, _err); bool asInt; total += bx::read(_reader, asInt, _err); if (!_err->isOk() ) { return total; } Attrib::Enum attr = idToAttrib(attribId); AttribType::Enum type = idToAttribType(attribTypeId); if (Attrib::Count != attr && AttribType::Count != type) { _decl.add(attr, num, type, normalized, asInt); _decl.m_offset[attr] = offset; } } _decl.end(); _decl.m_stride = stride; return total; }
int32_t read(bx::ReaderSeekerI* _reader, SpirV& _spirv, bx::Error* _err) { BX_ERROR_SCOPE(_err); int32_t size = 0; size += bx::read(_reader, _spirv.header, _err); if (!_err->isOk() || size != sizeof(SpirV::Header) || _spirv.header.magic != SPIRV_MAGIC ) { BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_HEADER, "SPIR-V: Invalid header."); return size; } size += read(_reader, _spirv.shader, _err); return size; }
void parse(const SpvShader& _src, SpvParseFn _fn, void* _userData, bx::Error* _err) { BX_ERROR_SCOPE(_err); uint32_t numBytes = uint32_t(_src.byteCode.size() ); bx::MemoryReader reader(_src.byteCode.data(), numBytes); for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;) { SpvInstruction instruction; uint32_t size = read(&reader, instruction, _err); if (!_err->isOk() ) { return; } if (size/4 != instruction.length) { BX_TRACE("read %d, expected %d, %s" , size/4 , instruction.length , getName(instruction.opcode) ); BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, "SPIR-V: Invalid instruction."); return; } bool cont = _fn(token * sizeof(uint32_t), instruction, _userData); if (!cont) { return; } token += instruction.length; } }
int32_t write(WriterI* _writer, const Settings& _settings, Error* _err) { BX_ERROR_SCOPE(_err); return _settings.write(_writer, _err); }
int32_t read(ReaderSeekerI* _reader, Settings& _settings, Error* _err) { BX_ERROR_SCOPE(_err); return _settings.read(_reader, _err); }