1 | #include <cstring>
|
---|
2 | #include <fstream>
|
---|
3 | #include <vector>
|
---|
4 |
|
---|
5 | #include <d3dcompiler.h>
|
---|
6 |
|
---|
7 | #include <shellapi.h>
|
---|
8 | #include <windows.h>
|
---|
9 | #include <windowsx.h>
|
---|
10 |
|
---|
11 | #include "../test_utils.h"
|
---|
12 |
|
---|
13 | using namespace dxvk;
|
---|
14 |
|
---|
15 | int WINAPI WinMain(HINSTANCE hInstance,
|
---|
16 | HINSTANCE hPrevInstance,
|
---|
17 | LPSTR lpCmdLine,
|
---|
18 | int nCmdShow) {
|
---|
19 | int argc = 0;
|
---|
20 | LPWSTR* argv = CommandLineToArgvW(
|
---|
21 | GetCommandLineW(), &argc);
|
---|
22 |
|
---|
23 | if (argc < 5) {
|
---|
24 | std::cerr << "Usage: hlsl-compiler target entrypoint input.hlsl output.dxbc [--strip] [--text]" << std::endl;
|
---|
25 | return 1;
|
---|
26 | }
|
---|
27 |
|
---|
28 | bool strip = false;
|
---|
29 | bool text = false;
|
---|
30 |
|
---|
31 | for (int i = 5; i < argc; i++) {
|
---|
32 | strip |= str::fromws(argv[i]) == "--strip";
|
---|
33 | text |= str::fromws(argv[i]) == "--text";
|
---|
34 | }
|
---|
35 |
|
---|
36 | const LPWSTR target = argv[1];
|
---|
37 | const LPWSTR entryPoint = argv[2];
|
---|
38 | const LPWSTR inputFile = argv[3];
|
---|
39 | const LPWSTR outputFile = argv[4];
|
---|
40 |
|
---|
41 | std::ifstream ifile(str::fromws(inputFile), std::ios::binary);
|
---|
42 | ifile.ignore(std::numeric_limits<std::streamsize>::max());
|
---|
43 | std::streamsize length = ifile.gcount();
|
---|
44 | ifile.clear();
|
---|
45 |
|
---|
46 | ifile.seekg(0, std::ios_base::beg);
|
---|
47 | std::vector<char> hlslCode(length);
|
---|
48 | ifile.read(hlslCode.data(), length);
|
---|
49 |
|
---|
50 | Com<ID3DBlob> binary;
|
---|
51 | Com<ID3DBlob> errors;
|
---|
52 |
|
---|
53 | HRESULT hr = D3DCompile(
|
---|
54 | hlslCode.data(),
|
---|
55 | hlslCode.size(),
|
---|
56 | "Shader", nullptr, nullptr,
|
---|
57 | str::fromws(entryPoint).c_str(),
|
---|
58 | str::fromws(target).c_str(),
|
---|
59 | D3DCOMPILE_OPTIMIZATION_LEVEL3 |
|
---|
60 | D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES,
|
---|
61 | 0, &binary, &errors);
|
---|
62 |
|
---|
63 | if (FAILED(hr)) {
|
---|
64 | if (errors != nullptr)
|
---|
65 | std::cerr << reinterpret_cast<const char*>(errors->GetBufferPointer()) << std::endl;
|
---|
66 | return 1;
|
---|
67 | }
|
---|
68 |
|
---|
69 | if (strip) {
|
---|
70 | Com<ID3DBlob> strippedBlob;
|
---|
71 |
|
---|
72 | hr = D3DStripShader(binary->GetBufferPointer(), binary->GetBufferSize(),
|
---|
73 | D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_DEBUG_INFO,
|
---|
74 | &strippedBlob);
|
---|
75 |
|
---|
76 | if (FAILED(hr)) {
|
---|
77 | std::cerr << "Failed to strip shader" << std::endl;
|
---|
78 | return 1;
|
---|
79 | }
|
---|
80 |
|
---|
81 | binary = strippedBlob;
|
---|
82 | }
|
---|
83 |
|
---|
84 | std::ofstream file;
|
---|
85 |
|
---|
86 | if (str::fromws(outputFile) != "-")
|
---|
87 | file = std::ofstream(str::fromws(outputFile), std::ios::binary | std::ios::trunc);
|
---|
88 |
|
---|
89 | std::ostream& outputStream = file.is_open() ? file : std::cout;
|
---|
90 |
|
---|
91 | if (text) {
|
---|
92 | auto data = reinterpret_cast<const uint32_t*>(binary->GetBufferPointer());
|
---|
93 | auto size = binary->GetBufferSize() / sizeof(uint32_t);
|
---|
94 |
|
---|
95 | outputStream << std::hex;
|
---|
96 |
|
---|
97 | for (uint32_t i = 0; i < size; i++) {
|
---|
98 | if (i && !(i & 0x7))
|
---|
99 | outputStream << std::endl;
|
---|
100 | outputStream << "0x" << std::setfill('0') << std::setw(8) << data[i] << ", ";
|
---|
101 | }
|
---|
102 |
|
---|
103 | outputStream << std::endl;
|
---|
104 | } else {
|
---|
105 | outputStream.write(reinterpret_cast<const char*>(binary->GetBufferPointer()), binary->GetBufferSize());
|
---|
106 | }
|
---|
107 |
|
---|
108 | return 0;
|
---|
109 | }
|
---|