2019-12-16 04:28:01 +01:00
|
|
|
#include "dxso_module.h"
|
|
|
|
|
|
|
|
#include "dxso_code.h"
|
|
|
|
#include "dxso_compiler.h"
|
|
|
|
|
2020-08-26 21:30:51 +02:00
|
|
|
#include <memory>
|
|
|
|
|
2019-12-16 04:28:01 +01:00
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxsoModule::DxsoModule(DxsoReader& reader)
|
|
|
|
: m_header( reader )
|
|
|
|
, m_code ( reader ) { }
|
|
|
|
|
|
|
|
DxsoAnalysisInfo DxsoModule::analyze() {
|
|
|
|
DxsoAnalysisInfo info;
|
|
|
|
|
|
|
|
DxsoAnalyzer analyzer(info);
|
|
|
|
|
|
|
|
this->runAnalyzer(analyzer, m_code.iter());
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
DxsoPermutations DxsoModule::compile(
|
|
|
|
const DxsoModuleInfo& moduleInfo,
|
|
|
|
const std::string& fileName,
|
|
|
|
const DxsoAnalysisInfo& analysis,
|
|
|
|
const D3D9ConstantLayout& layout) {
|
2020-08-26 21:30:51 +02:00
|
|
|
auto compiler = std::make_unique<DxsoCompiler>(
|
2019-12-16 04:28:01 +01:00
|
|
|
fileName, moduleInfo,
|
|
|
|
m_header.info(), analysis,
|
|
|
|
layout);
|
|
|
|
|
2020-08-26 21:30:51 +02:00
|
|
|
this->runCompiler(*compiler, m_code.iter());
|
|
|
|
m_isgn = compiler->isgn();
|
2019-12-16 04:28:01 +01:00
|
|
|
|
2021-11-14 16:00:36 +01:00
|
|
|
m_meta = compiler->meta();
|
|
|
|
m_constants = compiler->constants();
|
|
|
|
m_maxDefinedConst = compiler->maxDefinedConstant();
|
|
|
|
m_usedSamplers = compiler->usedSamplers();
|
|
|
|
m_usedRTs = compiler->usedRTs();
|
2019-12-16 04:28:01 +01:00
|
|
|
|
2020-08-26 21:30:51 +02:00
|
|
|
compiler->finalize();
|
2019-12-16 04:28:01 +01:00
|
|
|
|
2020-08-26 21:30:51 +02:00
|
|
|
return compiler->compile();
|
2019-12-16 04:28:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DxsoModule::runAnalyzer(
|
|
|
|
DxsoAnalyzer& analyzer,
|
|
|
|
DxsoCodeIter iter) const {
|
|
|
|
DxsoCodeIter start = iter;
|
|
|
|
|
|
|
|
DxsoDecodeContext decoder(m_header.info());
|
|
|
|
|
|
|
|
while (decoder.decodeInstruction(iter))
|
|
|
|
analyzer.processInstruction(
|
|
|
|
decoder.getInstructionContext());
|
|
|
|
|
|
|
|
size_t tokenCount = size_t(iter.ptrAt(0) - start.ptrAt(0));
|
|
|
|
|
|
|
|
// We need to account for the header token in the bytecode size...
|
|
|
|
|
|
|
|
// At this point, start is offset by the header due to us this being
|
|
|
|
// a *code* iterator, and not the general reader class.
|
|
|
|
// [start token] ^(start caret)^ [frog rendering code] [end token] ^(end caret)^
|
|
|
|
// where the tokenCount above is inbetween the start and end carets.
|
|
|
|
|
|
|
|
// We need to account for this otherwise it will show up as us not
|
|
|
|
// accounting for the *end* token in GetFunction due to the total size being
|
|
|
|
// offset by -1.
|
|
|
|
// [start token] [frog rendering code] (end of tokenCount) [end token]
|
|
|
|
tokenCount += 1;
|
|
|
|
|
|
|
|
analyzer.finalize(tokenCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DxsoModule::runCompiler(
|
|
|
|
DxsoCompiler& compiler,
|
|
|
|
DxsoCodeIter iter) const {
|
|
|
|
DxsoDecodeContext decoder(m_header.info());
|
|
|
|
|
|
|
|
while (decoder.decodeInstruction(iter))
|
|
|
|
compiler.processInstruction(
|
|
|
|
decoder.getInstructionContext());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|