| 269 | } |
| 270 | |
| 271 | std::optional<GLProgram> GLShaderCache::GetProgram( |
| 272 | const std::string_view vertex_shader, const std::string_view fragment_shader, const PreLinkCallback& callback) |
| 273 | { |
| 274 | if (!m_program_binary_supported || !m_blob_file) |
| 275 | { |
| 276 | #ifdef PCSX2_DEVBUILD |
| 277 | Common::Timer timer; |
| 278 | #endif |
| 279 | |
| 280 | std::optional<GLProgram> res = CompileProgram(vertex_shader, fragment_shader, callback, false); |
| 281 | |
| 282 | #ifdef PCSX2_DEVBUILD |
| 283 | Console.WriteLn("Time to compile shader without caching: %.2fms", timer.GetTimeMilliseconds()); |
| 284 | #endif |
| 285 | return res; |
| 286 | } |
| 287 | |
| 288 | const auto key = GetCacheKey(vertex_shader, fragment_shader); |
| 289 | auto iter = m_index.find(key); |
| 290 | if (iter == m_index.end()) |
| 291 | return CompileAndAddProgram(key, vertex_shader, fragment_shader, callback); |
| 292 | |
| 293 | std::vector<u8> data(iter->second.blob_size); |
| 294 | if (std::fseek(m_blob_file, iter->second.file_offset, SEEK_SET) != 0 || |
| 295 | std::fread(data.data(), 1, iter->second.blob_size, m_blob_file) != iter->second.blob_size) |
| 296 | { |
| 297 | Console.Error("Read blob from file failed"); |
| 298 | return {}; |
| 299 | } |
| 300 | |
| 301 | #ifdef PCSX2_DEVBUILD |
| 302 | Common::Timer timer; |
| 303 | #endif |
| 304 | |
| 305 | GLProgram prog; |
| 306 | if (prog.CreateFromBinary(data.data(), static_cast<u32>(data.size()), iter->second.blob_format)) |
| 307 | { |
| 308 | #ifdef PCSX2_DEVBUILD |
| 309 | Console.WriteLn("Time to create program from binary: %.2fms", timer.GetTimeMilliseconds()); |
| 310 | #endif |
| 311 | |
| 312 | return std::optional<GLProgram>(std::move(prog)); |
| 313 | } |
| 314 | |
| 315 | Console.Warning( |
| 316 | "Failed to create program from binary, this may be due to a driver or GPU Change. Recreating cache."); |
| 317 | if (!Recreate()) |
| 318 | return CompileProgram(vertex_shader, fragment_shader, callback, false); |
| 319 | else |
| 320 | return CompileAndAddProgram(key, vertex_shader, fragment_shader, callback); |
| 321 | } |
| 322 | |
| 323 | bool GLShaderCache::GetProgram(GLProgram* out_program, const std::string_view vertex_shader, |
| 324 | const std::string_view fragment_shader, const PreLinkCallback& callback /* = */) |
no test coverage detected