-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathVpuCompiler.cpp
102 lines (73 loc) · 2.36 KB
/
VpuCompiler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "llvm/Support/Error.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELF.h"
#include "VpuCompiler.h"
#include "LlvmLinker.h"
#include "LlvmCompiler.h"
#include "VpuImage.h"
#include "LlvmObject.h"
#include <dxcapi.h>
#include <d3dcompiler.h>
#include <assert.h>
using namespace llvm;
using namespace object;
#define TLS_SYMBOL "g_tls"
bool vpu_compiler(ID3DBlob * inDxilByteCode, ID3DBlob ** outVpuImage)
{
IDxcCompiler * pCompiler;
HRESULT hr = DxcCreateInstance(CLSID_DxcCompiler, __uuidof(IDxcCompiler), (void **)& pCompiler);
assert(hr == S_OK);
IDxcBlobEncoding * pDisassembly;
hr = pCompiler->Disassemble((IDxcBlob *)inDxilByteCode, &pDisassembly);
assert(hr == S_OK);
hr = D3DWriteBlobToFile((ID3DBlob *)pDisassembly, L"dis.dxil", TRUE);
assert(hr == S_OK);
pDisassembly->Release();
pCompiler->Release();
llvm_linker("vpu_compiler",
"VpuShaderLib.bc",
"DxilToVpu.ll",
"dis.dxil",
"VpuShader.bc");
llvm_compile("vpu_compiler", "VpuShader.bc", "VpuShader.obj");
bool success = true;
VpuObject obj;
VpuImageHeader header;
success = obj.Open("VpuShader.obj") &&
obj.GetSymbolValue("main", header.m_entryOffset) &&
obj.GetSymbolValue(TLS_SYMBOL, header.m_tlsSize);
if (success) {
header.m_codeSize = obj.GetCodeSize();
header.m_relocationCount = obj.GetRelocations().size();
hr = D3DCreateBlob(header.GetSerializationSize(), outVpuImage);
assert(hr == S_OK);
VpuImageHeader * image = (VpuImageHeader*) (*outVpuImage)->GetBufferPointer();
*image = header;
const std::vector<VpuObjRelocation> & objRelocations = obj.GetRelocations();
VpuRelocation * relocations = (VpuRelocation *)(image + 1);
int relocationCount = 0;
for (auto & objr : objRelocations) {
VpuRelocation & r = relocations[relocationCount++];
r.m_fixupOffset = objr.m_fixupOffset;
r.m_type = objr.m_type;
if (objr.m_symbolName == TLS_SYMBOL)
r.m_referenceOffset = header.GetTlsOffset();
else {
std::string name = objr.m_symbolName;
if (!obj.GetSymbolValue(name.c_str(), r.m_referenceOffset)) {
success = false;
break;
}
}
}
if (success) {
assert(relocationCount == header.m_relocationCount);
uint8_t * code = (uint8_t *)&relocations[header.m_relocationCount];
obj.GetCode(code, header.m_codeSize);
}
}
obj.Close();
return true;
}