| 25 | } |
| 26 | |
| 27 | bool assemble_code_for_entry_point(const std::string &entry_point_name, std::string &cso, std::string &assembly, std::string &errors) const override |
| 28 | { |
| 29 | const auto entry_point_it = std::find_if(_module.entry_points.begin(), _module.entry_points.end(), |
| 30 | [&entry_point_name](const std::pair<std::string, shader_type> &entry_point) { |
| 31 | return entry_point.first == entry_point_name; |
| 32 | }); |
| 33 | if (entry_point_it == _module.entry_points.end()) |
| 34 | return false; |
| 35 | |
| 36 | com_ptr<IDxcCompiler3> compiler; |
| 37 | if (FAILED(DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler)))) |
| 38 | return false; |
| 39 | |
| 40 | std::string hlsl; |
| 41 | if (!codegen_hlsl::assemble_code_for_entry_point(entry_point_name, hlsl, hlsl, errors)) |
| 42 | return false; |
| 43 | |
| 44 | WCHAR profile[] = L"cs_0_0"; |
| 45 | profile[0] = entry_point_it->second == shader_type::vertex ? L'v' : entry_point_it->second == shader_type::pixel ? L'p' : L'c'; |
| 46 | profile[3] = L'0' + (_shader_model / 10) % 10; |
| 47 | profile[5] = L'0' + (_shader_model % 10); |
| 48 | |
| 49 | const std::wstring entry_point_name_wide(entry_point_name.begin(), entry_point_name.end()); |
| 50 | |
| 51 | WCHAR optimization_level_flag[] = L"-O3"; |
| 52 | optimization_level_flag[2] = _optimization_level >= 0 ? L'0' + (_optimization_level % 10) : L'd'; |
| 53 | |
| 54 | LPCWSTR arguments[] = { |
| 55 | L"-T", profile, |
| 56 | L"-E", entry_point_name_wide.c_str(), |
| 57 | optimization_level_flag, |
| 58 | L"-Zi", |
| 59 | L"-Qembed_debug", |
| 60 | _shader_model >= 62 ? L"-enable-16bit-types" : L"", |
| 61 | L"-Wno-ignored-attributes", |
| 62 | }; |
| 63 | |
| 64 | const DxcBuffer hlsl_buffer = { |
| 65 | hlsl.data(), hlsl.size(), DXC_CP_UTF8 |
| 66 | }; |
| 67 | |
| 68 | com_ptr<IDxcResult> result; |
| 69 | |
| 70 | HRESULT hr = compiler->Compile(&hlsl_buffer, arguments, static_cast<UINT32>(std::size(arguments)), nullptr, IID_PPV_ARGS(&result)); |
| 71 | if (result != nullptr) |
| 72 | { |
| 73 | result->GetStatus(&hr); |
| 74 | |
| 75 | if (com_ptr<IDxcBlobUtf8> d3d_errors; |
| 76 | SUCCEEDED(result->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&d3d_errors), nullptr))) |
| 77 | { |
| 78 | errors.append(static_cast<const char *>(d3d_errors->GetBufferPointer()), d3d_errors->GetBufferSize()); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | if (FAILED(hr)) |
| 83 | return false; |
| 84 |
nothing calls this directly
no test coverage detected