예제 #1
0
spv_result_t AggregateStats(const spv_context_t& context, const uint32_t* words,
                            const size_t num_words, spv_diagnostic* pDiagnostic,
                            SpirvStats* stats) {
  spv_const_binary_t binary = {words, num_words};

  spv_endianness_t endian;
  spv_position_t position = {};
  if (spvBinaryEndianness(&binary, &endian)) {
    return libspirv::DiagnosticStream(position, context.consumer,
                                      SPV_ERROR_INVALID_BINARY)
           << "Invalid SPIR-V magic number.";
  }

  spv_header_t header;
  if (spvBinaryHeaderGet(&binary, endian, &header)) {
    return libspirv::DiagnosticStream(position, context.consumer,
                                      SPV_ERROR_INVALID_BINARY)
           << "Invalid SPIR-V header.";
  }

  StatsAggregator stats_aggregator(stats, &context);

  return spvBinaryParse(&context, &stats_aggregator, words, num_words,
                        ProcessHeader, ProcessInstruction, pDiagnostic);
}
예제 #2
0
spv_result_t spvBinaryToText(const spv_const_context context,
                             const uint32_t* code, const size_t wordCount,
                             const uint32_t options, spv_text* pText,
                             spv_diagnostic* pDiagnostic) {
  // Invalid arguments return error codes, but don't necessarily generate
  // diagnostics.  These are programmer errors, not user errors.
  if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
  const libspirv::AssemblyGrammar grammar(context);
  if (!grammar.isValid()) return SPV_ERROR_INVALID_TABLE;

  // Generate friendly names for Ids if requested.
  std::unique_ptr<libspirv::FriendlyNameMapper> friendly_mapper;
  libspirv::NameMapper name_mapper = libspirv::GetTrivialNameMapper();
  if (options & SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) {
    friendly_mapper.reset(
        new libspirv::FriendlyNameMapper(context, code, wordCount));
    name_mapper = friendly_mapper->GetNameMapper();
  }

  // Now disassemble!
  Disassembler disassembler(grammar, options, name_mapper);
  if (auto error = spvBinaryParse(context, &disassembler, code, wordCount,
                                  DisassembleHeader, DisassembleInstruction,
                                  pDiagnostic)) {
    return error;
  }

  return disassembler.SaveTextResult(pText);
}
예제 #3
0
FriendlyNameMapper::FriendlyNameMapper(const spv_const_context context,
                                       const uint32_t* code,
                                       const size_t wordCount)
    : grammar_(libspirv::AssemblyGrammar(context)) {
  spv_diagnostic diag = nullptr;
  // We don't care if the parse fails.
  spvBinaryParse(context, this, code, wordCount, nullptr,
                 ParseInstructionForwarder, &diag);
  spvDiagnosticDestroy(diag);
}
intermediate_type parse_intermediate(std::istream &stream) {
	std::shared_ptr<spv_context_t> context(
		spvContextCreate(SPV_ENV_VULKAN_1_0), spvContextDestroy);
	assert(context);

	const std::string content(std::istreambuf_iterator<char>(stream.rdbuf()),
			std::istreambuf_iterator<char>());
	intermediate_type intermediate;
	spv_diagnostic diagnostic;
	spvBinaryParse(context.get(), &intermediate, (uint32_t *) content.c_str(),
			content.size() / sizeof(uint32_t), &parsed_header, &parsed_instruction, &diagnostic);
	return intermediate;
}
예제 #5
0
std::unique_ptr<ir::IRContext> BuildModule(spv_target_env env,
                                           MessageConsumer consumer,
                                           const uint32_t* binary,
                                           const size_t size) {
  auto context = spvContextCreate(env);
  libspirv::SetContextMessageConsumer(context, consumer);

  auto irContext = MakeUnique<ir::IRContext>(env, consumer);
  ir::IrLoader loader(consumer, irContext->module());

  spv_result_t status = spvBinaryParse(context, &loader, binary, size,
                                       SetSpvHeader, SetSpvInst, nullptr);
  loader.EndModule();

  spvContextDestroy(context);

  return status == SPV_SUCCESS ? std::move(irContext) : nullptr;
}
예제 #6
0
spv_result_t spvBinaryToText(const spv_const_context context,
                             const uint32_t* code, const size_t wordCount,
                             const uint32_t options, spv_text* pText,
                             spv_diagnostic* pDiagnostic) {
  // Invalid arguments return error codes, but don't necessarily generate
  // diagnostics.  These are programmer errors, not user errors.
  if (!pDiagnostic) return SPV_ERROR_INVALID_DIAGNOSTIC;
  const libspirv::AssemblyGrammar grammar(context);
  if (!grammar.isValid()) return SPV_ERROR_INVALID_TABLE;

  Disassembler disassembler(grammar, options);
  if (auto error = spvBinaryParse(context, &disassembler, code, wordCount,
                                  DisassembleHeader, DisassembleInstruction,
                                  pDiagnostic)) {
    return error;
  }

  return disassembler.SaveTextResult(pText);
}