#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 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 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()); } } }