From 84740190e7831f1c51e9363e1fa8c6940870c5bf Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 27 May 2026 05:49:47 +0000 Subject: [PATCH] [android] MediaTek specific opts Signed-off-by: lizzie --- src/video_core/host1x/ffmpeg.cpp | 61 +++++++++---------- .../renderer_vulkan/vk_graphics_pipeline.cpp | 24 +++----- .../vulkan_common/vulkan_device.cpp | 6 ++ 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/video_core/host1x/ffmpeg.cpp b/src/video_core/host1x/ffmpeg.cpp index 80e48692f7..507e94f193 100644 --- a/src/video_core/host1x/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg.cpp @@ -25,10 +25,10 @@ namespace FFmpeg { namespace { -constexpr AVPixelFormat PreferredGpuFormat = AV_PIX_FMT_NV12; -constexpr AVPixelFormat PreferredCpuFormat = AV_PIX_FMT_YUV420P; -constexpr std::array PreferredGpuDecoders = { -#if defined (_WIN32) +constexpr AVPixelFormat PREFERRED_GPU_FORMAT = AV_PIX_FMT_NV12; +constexpr AVPixelFormat PREFERRED_CPU_FORMAT = AV_PIX_FMT_YUV420P; +constexpr std::array PREFERRED_GPU_DECODERS = { +#if defined(_WIN32) AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2, @@ -54,15 +54,14 @@ AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* p if (desc && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { for (int i = 0;; i++) { const AVCodecHWConfig* config = avcodec_get_hw_config(codec_context->codec, i); - if (!config) { + if (config) { + for (const auto type : PREFERRED_GPU_DECODERS) + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) { + codec_context->pix_fmt = config->pix_fmt; + } + } else { break; } - - for (const auto type : PreferredGpuDecoders) { - if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) { - codec_context->pix_fmt = config->pix_fmt; - } - } } } @@ -74,7 +73,7 @@ AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* p LOG_INFO(HW_GPU, "Could not find supported GPU pixel format, falling back to CPU decoder"); av_buffer_unref(&codec_context->hw_device_ctx); - codec_context->pix_fmt = PreferredCpuFormat; + codec_context->pix_fmt = PREFERRED_CPU_FORMAT; return codec_context->pix_fmt; } @@ -142,13 +141,10 @@ bool Decoder::SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceTyp std::vector HardwareContext::GetSupportedDeviceTypes() { std::vector types; AVHWDeviceType current_device_type = AV_HWDEVICE_TYPE_NONE; - while (true) { current_device_type = av_hwdevice_iterate_types(current_device_type); - if (current_device_type == AV_HWDEVICE_TYPE_NONE) { + if (current_device_type == AV_HWDEVICE_TYPE_NONE) return types; - } - types.push_back(current_device_type); } } @@ -158,25 +154,20 @@ HardwareContext::~HardwareContext() { } bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, const Decoder& decoder) { - const auto supported_types = GetSupportedDeviceTypes(); - for (const auto type : PreferredGpuDecoders) { - AVPixelFormat hw_pix_fmt; - + auto const supported_types = GetSupportedDeviceTypes(); + for (auto const type : PREFERRED_GPU_DECODERS) { if (std::ranges::find(supported_types, type) == supported_types.end()) { LOG_DEBUG(HW_GPU, "{} explicitly unsupported", av_hwdevice_get_type_name(type)); continue; } - - if (!this->InitializeWithType(type)) { - continue; - } - - if (decoder.SupportsDecodingOnDevice(&hw_pix_fmt, type)) { - decoder_context.InitializeHardwareDecoder(*this, hw_pix_fmt); - return true; + if (InitializeWithType(type)) { + AVPixelFormat hw_pix_fmt{}; + if (decoder.SupportsDecodingOnDevice(&hw_pix_fmt, type)) { + decoder_context.InitializeHardwareDecoder(*this, hw_pix_fmt); + return true; + } } } - return false; } @@ -184,7 +175,7 @@ bool HardwareContext::InitializeWithType(AVHWDeviceType type) { av_buffer_unref(&m_gpu_decoder); if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0); ret < 0) { - LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type), AVError(ret)); + LOG_INFO(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type), AVError(ret)); return false; } @@ -265,11 +256,17 @@ std::shared_ptr DecoderContext::ReceiveFrame() { m_final_frame = std::make_shared(); if (m_codec_context->hw_device_ctx) { - m_final_frame->SetFormat(PreferredGpuFormat); +#ifdef __ANDROID__ + // c2.mtk.vp9.decoder, c2.mtk.vp89.decoder will be fine if we don't + // re-encode stuff twice :> + m_final_frame = std::move(intermediate_frame); +#else + m_final_frame->SetFormat(PREFERRED_GPU_FORMAT); if (const int ret = av_hwframe_transfer_data(m_final_frame->GetFrame(), intermediate_frame->GetFrame(), 0); ret < 0) { LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); return {}; } +#endif } else { m_final_frame = std::move(intermediate_frame); } @@ -284,6 +281,8 @@ void DecodeApi::Reset() { } bool DecodeApi::Initialize(Tegra::Host1x::NvdecCommon::VideoCodec codec) { + av_log_set_level(AV_LOG_DEBUG); + this->Reset(); m_decoder.emplace(codec); m_decoder_context.emplace(*m_decoder); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 43fbefe425..57541e88bc 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -37,8 +37,6 @@ namespace Vulkan { namespace { -using boost::container::small_vector; -using boost::container::static_vector; using Shader::ImageBufferDescriptor; using Shader::Backend::SPIRV::RENDERAREA_LAYOUT_OFFSET; using Shader::Backend::SPIRV::RESCALING_LAYOUT_DOWN_FACTOR_OFFSET; @@ -314,8 +312,8 @@ void GraphicsPipeline::AddTransition(GraphicsPipeline* transition) { template bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { - small_vector views; - small_vector samplers; + boost::container::small_vector views; + boost::container::small_vector samplers; views.reserve(num_image_elements); samplers.reserve(num_textures); @@ -585,9 +583,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { } else { dynamic.raw1 = key.state.dynamic_state.raw1; } - static_vector vertex_bindings; - static_vector vertex_binding_divisors; - static_vector vertex_attributes; + boost::container::static_vector vertex_bindings; + boost::container::static_vector vertex_binding_divisors; + boost::container::static_vector vertex_attributes; if (!key.state.dynamic_vertex_input) { const size_t num_vertex_arrays = (std::min)( Maxwell::NumVertexArrays, static_cast(device.GetMaxVertexInputBindings())); @@ -812,7 +810,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { if (dynamic.depth_bounds_enable && !device.IsDepthBoundsSupported()) { LOG_WARNING(Render_Vulkan, "Depth bounds is enabled but not supported"); } - static_vector cb_attachments; + boost::container::static_vector cb_attachments; const size_t num_attachments{NumAttachments(key.state)}; for (size_t index = 0; index < num_attachments; ++index) { static constexpr std::array mask_table{ @@ -848,7 +846,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .pAttachments = cb_attachments.data(), .blendConstants = {} }; - static_vector dynamic_states{ + boost::container::static_vector dynamic_states{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, @@ -943,12 +941,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .pNext = nullptr, .requiredSubgroupSize = GuestWarpSize, }; - static_vector shader_stages; + boost::container::static_vector shader_stages; for (size_t stage = 0; stage < Maxwell::MaxShaderStage; ++stage) { - if (!spv_modules[stage]) { - continue; - } - [[maybe_unused]] auto& stage_ci = + if (spv_modules[stage]) { shader_stages.emplace_back(VkPipelineShaderStageCreateInfo{ .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, @@ -958,6 +953,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .pName = "main", .pSpecializationInfo = nullptr, }); + } } VkPipelineCreateFlags flags{}; if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) { diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 6e55306079..2c6b6b43fa 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -286,6 +286,12 @@ ankerl::unordered_dense::map GetFormatProperties(v VK_FORMAT_R8_UNORM, VK_FORMAT_R8_USCALED, VK_FORMAT_S8_UINT, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, }; ankerl::unordered_dense::map format_properties; for (const auto format : formats) {