| 21 | } |
| 22 | |
| 23 | bool assemble_code_for_entry_point(const std::string &entry_point_name, std::string &cso, std::string &assembly, std::string &errors) const override |
| 24 | { |
| 25 | const auto entry_point_it = std::find_if(_module.entry_points.begin(), _module.entry_points.end(), |
| 26 | [&entry_point_name](const std::pair<std::string, shader_type> &entry_point) { |
| 27 | return entry_point.first == entry_point_name; |
| 28 | }); |
| 29 | if (entry_point_it == _module.entry_points.end()) |
| 30 | return false; |
| 31 | |
| 32 | std::string hlsl; |
| 33 | if (!codegen_hlsl::assemble_code_for_entry_point(entry_point_name, hlsl, hlsl, errors)) |
| 34 | return false; |
| 35 | |
| 36 | CHAR profile[] = "cs_0_0"; |
| 37 | profile[0] = entry_point_it->second == shader_type::vertex ? 'v' : entry_point_it->second == shader_type::pixel ? 'p' : 'c'; |
| 38 | profile[3] = '0' + (_shader_model / 10) % 10; |
| 39 | profile[5] = '0' + (_shader_model % 10); |
| 40 | |
| 41 | UINT compile_flags = 0; |
| 42 | if (_optimization_level < 0) |
| 43 | compile_flags |= D3DCOMPILE_SKIP_OPTIMIZATION; |
| 44 | else if (_optimization_level >= 3) |
| 45 | compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; |
| 46 | else if (_optimization_level == 2) |
| 47 | compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL2; |
| 48 | else if (_optimization_level == 1) |
| 49 | compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL1; |
| 50 | else if (_optimization_level == 0) |
| 51 | compile_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0; |
| 52 | |
| 53 | if (_shader_model >= 40) |
| 54 | compile_flags |= D3DCOMPILE_ENABLE_STRICTNESS; |
| 55 | #ifndef NDEBUG |
| 56 | compile_flags |= D3DCOMPILE_DEBUG; |
| 57 | #endif |
| 58 | |
| 59 | com_ptr<ID3DBlob> d3d_errors; |
| 60 | com_ptr<ID3DBlob> d3d_compiled; |
| 61 | com_ptr<ID3DBlob> d3d_disassembled; |
| 62 | |
| 63 | const HRESULT hr = D3DCompile(hlsl.data(), hlsl.size(), nullptr, nullptr, nullptr, entry_point_name.c_str(), profile, compile_flags, 0, &d3d_compiled, &d3d_errors); |
| 64 | |
| 65 | if (d3d_errors != nullptr) // Append warnings to the output error string as well |
| 66 | { |
| 67 | std::string d3d_errors_string( |
| 68 | static_cast<const char *>(d3d_errors->GetBufferPointer()), |
| 69 | d3d_errors->GetBufferSize() - 1); // Subtracting one to not append the null-terminator as well |
| 70 | d3d_errors.reset(); |
| 71 | |
| 72 | // De-duplicate error lines (D3DCompiler sometimes repeats the same error multiple times) |
| 73 | for (size_t line_offset = 0, next_line_offset; (next_line_offset = d3d_errors_string.find('\n', line_offset)) != std::string::npos; line_offset = next_line_offset + 1) |
| 74 | { |
| 75 | const std::string_view cur_line(d3d_errors_string.data() + line_offset, next_line_offset - line_offset); |
| 76 | |
| 77 | if (const size_t end_offset = d3d_errors_string.find('\n', next_line_offset + 1); |
| 78 | end_offset != std::string::npos) |
| 79 | { |
| 80 | const std::string_view next_line(d3d_errors_string.data() + next_line_offset + 1, end_offset - next_line_offset - 1); |
nothing calls this directly
no test coverage detected