| 272 | } |
| 273 | |
| 274 | std::array<encoder_settings, 3> get_encoder_settings(wivrn::vk_bundle & bundle, wivrn_session & session) |
| 275 | { |
| 276 | configuration config; |
| 277 | |
| 278 | std::array<wivrn::encoder_settings, 3> res; |
| 279 | const auto & info = session.get_info(); |
| 280 | const auto settings = *session.get_settings(); |
| 281 | |
| 282 | prober prober{bundle, info}; |
| 283 | |
| 284 | for (auto [src, dst]: std::ranges::zip_view(config.encoders, res)) |
| 285 | { |
| 286 | dst.fps = session.default_fps(); |
| 287 | dst.options = src.options; |
| 288 | dst.device = src.device; |
| 289 | |
| 290 | std::tie(dst.encoder_name, dst.codec) = prober.select_encoder(src); |
| 291 | } |
| 292 | |
| 293 | auto width = align(info.stream_eye_width, 64); |
| 294 | auto height = align(info.stream_eye_height, 64); |
| 295 | // Ensure we don't try to encode too large images (only for left/right, ignore alpha) |
| 296 | for (size_t i = 0; i < 2; ++i) |
| 297 | check_video_size(res[i].encoder_name, res[i].codec, width, height); |
| 298 | |
| 299 | for (auto [i, dst]: std::ranges::enumerate_view(res)) |
| 300 | { |
| 301 | dst.width = width; |
| 302 | dst.height = height; |
| 303 | if (i == 2) // alpha channel |
| 304 | dst.height /= 2; |
| 305 | } |
| 306 | |
| 307 | auto bit_depth = config.bit_depth ? config.bit_depth : info.bit_depth; |
| 308 | |
| 309 | if (bit_depth and bit_depth != 8 and bit_depth != 10) |
| 310 | throw std::runtime_error("invalid bit-depth setting. supported values: 8, 10"); |
| 311 | |
| 312 | if (std::ranges::contains(res, video_codec::h264, &encoder_settings::codec) or |
| 313 | std::ranges::contains(res, video_codec::raw, &encoder_settings::codec)) |
| 314 | bit_depth = 8; |
| 315 | else if (not bit_depth) |
| 316 | bit_depth = 10; |
| 317 | |
| 318 | auto check_format = [&](vk::Format format) { |
| 319 | try |
| 320 | { |
| 321 | auto props = bundle.physical_device.getImageFormatProperties( |
| 322 | format, |
| 323 | vk::ImageType::e2D, |
| 324 | vk::ImageTiling::eOptimal, |
| 325 | vk::ImageUsageFlagBits::eStorage | vk::ImageUsageFlagBits::eTransferSrc); |
| 326 | return props.maxArrayLayers >= 3 and |
| 327 | props.maxExtent.depth >= 1 and |
| 328 | props.maxExtent.width >= width and |
| 329 | props.maxExtent.height >= height; |
| 330 | } |
| 331 | catch (vk::FormatNotSupportedError &) |
no test coverage detected