dxvk/src/dxbc/dxbc_module.cpp

117 lines
3.1 KiB
C++

#include "dxbc_analysis.h"
#include "dxbc_compiler.h"
#include "dxbc_module.h"
namespace dxvk {
DxbcModule::DxbcModule(DxbcReader& reader)
: m_header(reader) {
for (uint32_t i = 0; i < m_header.numChunks(); i++) {
// The chunk tag is stored at the beginning of each chunk
auto chunkReader = reader.clone(m_header.chunkOffset(i));
auto tag = chunkReader.readTag();
// The chunk size follows right after the four-character
// code. This does not include the eight bytes that are
// consumed by the FourCC and chunk length entry.
auto chunkLength = chunkReader.readu32();
chunkReader = chunkReader.clone(8);
chunkReader = chunkReader.resize(chunkLength);
if ((tag == "SHDR") || (tag == "SHEX"))
m_shexChunk = new DxbcShex(chunkReader);
if ((tag == "ISGN") || (tag == "ISG1"))
m_isgnChunk = new DxbcIsgn(chunkReader, tag);
if ((tag == "OSGN") || (tag == "OSG5") || (tag == "OSG1"))
m_osgnChunk = new DxbcIsgn(chunkReader, tag);
if ((tag == "PCSG") || (tag == "PSG1"))
m_psgnChunk = new DxbcIsgn(chunkReader, tag);
}
}
DxbcModule::~DxbcModule() {
}
Rc<DxvkShader> DxbcModule::compile(
const DxbcModuleInfo& moduleInfo,
const std::string& fileName) const {
if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
DxbcAnalysisInfo analysisInfo;
DxbcAnalyzer analyzer(moduleInfo,
m_shexChunk->programInfo(),
m_isgnChunk, m_osgnChunk,
m_psgnChunk, analysisInfo);
this->runAnalyzer(analyzer, m_shexChunk->slice());
DxbcCompiler compiler(
fileName, moduleInfo,
m_shexChunk->programInfo(),
m_isgnChunk, m_osgnChunk,
m_psgnChunk, analysisInfo);
this->runCompiler(compiler, m_shexChunk->slice());
return compiler.finalize();
}
Rc<DxvkShader> DxbcModule::compilePassthroughShader(
const DxbcModuleInfo& moduleInfo,
const std::string& fileName) const {
if (m_shexChunk == nullptr)
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
DxbcAnalysisInfo analysisInfo;
DxbcCompiler compiler(
fileName, moduleInfo,
DxbcProgramType::GeometryShader,
m_osgnChunk, m_osgnChunk,
m_psgnChunk, analysisInfo);
compiler.processXfbPassthrough();
return compiler.finalize();
}
void DxbcModule::runAnalyzer(
DxbcAnalyzer& analyzer,
DxbcCodeSlice slice) const {
DxbcDecodeContext decoder;
while (!slice.atEnd()) {
decoder.decodeInstruction(slice);
analyzer.processInstruction(
decoder.getInstruction());
}
}
void DxbcModule::runCompiler(
DxbcCompiler& compiler,
DxbcCodeSlice slice) const {
DxbcDecodeContext decoder;
while (!slice.atEnd()) {
decoder.decodeInstruction(slice);
compiler.processInstruction(
decoder.getInstruction());
}
}
}