2018-03-22 19:01:57 +00:00
|
|
|
#include "dxbc_analysis.h"
|
2017-10-16 16:50:09 +01:00
|
|
|
#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.
|
2017-10-31 23:01:40 +00:00
|
|
|
auto chunkLength = chunkReader.readu32();
|
|
|
|
|
|
|
|
chunkReader = chunkReader.clone(8);
|
|
|
|
chunkReader = chunkReader.resize(chunkLength);
|
2017-10-16 16:50:09 +01:00
|
|
|
|
|
|
|
if ((tag == "SHDR") || (tag == "SHEX"))
|
|
|
|
m_shexChunk = new DxbcShex(chunkReader);
|
|
|
|
|
2019-01-12 14:17:51 +00:00
|
|
|
if ((tag == "ISGN") || (tag == "ISG1"))
|
2018-05-31 21:13:08 +01:00
|
|
|
m_isgnChunk = new DxbcIsgn(chunkReader, tag);
|
2017-10-31 23:01:40 +00:00
|
|
|
|
2019-01-12 14:17:51 +00:00
|
|
|
if ((tag == "OSGN") || (tag == "OSG5") || (tag == "OSG1"))
|
2018-05-31 21:13:08 +01:00
|
|
|
m_osgnChunk = new DxbcIsgn(chunkReader, tag);
|
2019-01-26 13:52:29 +00:00
|
|
|
|
|
|
|
if ((tag == "PCSG") || (tag == "PSG1"))
|
|
|
|
m_psgnChunk = new DxbcIsgn(chunkReader, tag);
|
2017-10-16 16:50:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxbcModule::~DxbcModule() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-15 20:00:08 +01:00
|
|
|
Rc<DxvkShader> DxbcModule::compile(
|
2018-06-23 16:14:35 +01:00
|
|
|
const DxbcModuleInfo& moduleInfo,
|
|
|
|
const std::string& fileName) const {
|
2022-11-21 18:35:21 +00:00
|
|
|
if (m_shexChunk == nullptr)
|
|
|
|
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
2017-10-16 16:50:09 +01:00
|
|
|
|
2018-03-23 00:04:04 +00:00
|
|
|
DxbcAnalysisInfo analysisInfo;
|
|
|
|
|
2018-06-23 16:14:35 +01:00
|
|
|
DxbcAnalyzer analyzer(moduleInfo,
|
2018-10-08 08:34:56 +01:00
|
|
|
m_shexChunk->programInfo(),
|
2018-03-23 18:48:07 +00:00
|
|
|
m_isgnChunk, m_osgnChunk,
|
2019-01-26 13:52:29 +00:00
|
|
|
m_psgnChunk, analysisInfo);
|
2017-12-17 23:28:54 +00:00
|
|
|
|
2018-05-26 16:46:49 +01:00
|
|
|
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
|
|
|
|
2018-04-15 20:00:08 +01:00
|
|
|
DxbcCompiler compiler(
|
2018-06-23 16:14:35 +01:00
|
|
|
fileName, moduleInfo,
|
2018-10-08 08:34:56 +01:00
|
|
|
m_shexChunk->programInfo(),
|
2018-03-23 00:04:04 +00:00
|
|
|
m_isgnChunk, m_osgnChunk,
|
2019-01-26 13:52:29 +00:00
|
|
|
m_psgnChunk, analysisInfo);
|
2017-12-07 15:29:34 +00:00
|
|
|
|
2018-03-22 19:01:57 +00:00
|
|
|
this->runCompiler(compiler, m_shexChunk->slice());
|
|
|
|
|
|
|
|
return compiler.finalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-25 21:45:23 +01:00
|
|
|
Rc<DxvkShader> DxbcModule::compilePassthroughShader(
|
|
|
|
const DxbcModuleInfo& moduleInfo,
|
|
|
|
const std::string& fileName) const {
|
2022-11-21 18:35:21 +00:00
|
|
|
if (m_shexChunk == nullptr)
|
|
|
|
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
|
|
|
|
2018-07-25 21:45:23 +01:00
|
|
|
DxbcAnalysisInfo analysisInfo;
|
|
|
|
|
|
|
|
DxbcCompiler compiler(
|
|
|
|
fileName, moduleInfo,
|
|
|
|
DxbcProgramType::GeometryShader,
|
|
|
|
m_osgnChunk, m_osgnChunk,
|
2019-01-26 13:52:29 +00:00
|
|
|
m_psgnChunk, analysisInfo);
|
2018-07-25 21:45:23 +01:00
|
|
|
|
|
|
|
compiler.processXfbPassthrough();
|
|
|
|
return compiler.finalize();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-22 19:01:57 +00:00
|
|
|
void DxbcModule::runAnalyzer(
|
|
|
|
DxbcAnalyzer& analyzer,
|
|
|
|
DxbcCodeSlice slice) const {
|
2017-12-17 23:28:54 +00:00
|
|
|
DxbcDecodeContext decoder;
|
|
|
|
|
|
|
|
while (!slice.atEnd()) {
|
|
|
|
decoder.decodeInstruction(slice);
|
2017-12-13 14:32:54 +00:00
|
|
|
|
2018-03-22 19:01:57 +00:00
|
|
|
analyzer.processInstruction(
|
2017-12-17 23:28:54 +00:00
|
|
|
decoder.getInstruction());
|
2017-12-13 14:32:54 +00:00
|
|
|
}
|
2018-03-22 19:01:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DxbcModule::runCompiler(
|
|
|
|
DxbcCompiler& compiler,
|
|
|
|
DxbcCodeSlice slice) const {
|
|
|
|
DxbcDecodeContext decoder;
|
2017-12-08 17:14:05 +00:00
|
|
|
|
2018-03-22 19:01:57 +00:00
|
|
|
while (!slice.atEnd()) {
|
|
|
|
decoder.decodeInstruction(slice);
|
|
|
|
|
|
|
|
compiler.processInstruction(
|
|
|
|
decoder.getInstruction());
|
|
|
|
}
|
2017-10-16 16:50:09 +01:00
|
|
|
}
|
|
|
|
|
2018-10-08 08:34:56 +01:00
|
|
|
}
|