Compare commits

...

20 Commits

Author SHA1 Message Date
48d16031e9 Android #55 2023-08-30 00:57:37 +00:00
2f03fac9a0 Merge pull request #11413 from t895/intents
android: Support intents to emulation activity
2023-08-29 20:01:52 -04:00
3d5ecc1f08 Merge pull request #11406 from german77/sdl2-28-2
externals: Update SDL to 2.28.2
2023-08-29 09:27:54 -04:00
52c71e7eb6 Merge pull request #11408 from Kelebek1/fix_audio_node_id
[Audio] Fix node id index in DropVoices
2023-08-29 09:27:40 -04:00
1f04a3dd55 Merge pull request #11409 from liamwhite/splatoon-nsd-v2
sfdnsres: ensure lp1 is not resolved
2023-08-29 09:27:32 -04:00
d360abadba Merge pull request #11112 from danilaml/nvdec-deinterlace
Use initial_frame to check interlaced flag
2023-08-29 09:27:22 -04:00
2dbe067d74 android: Support intents to emulation activity 2023-08-29 02:57:20 -04:00
2f18fa5cd1 Merge pull request #11392 from t895/layout-troubles
android: Emulation activity fixes
2023-08-29 02:11:13 -04:00
1615a86375 Merge pull request #11390 from FearlessTobi/hwopus-multi
hwopus: Implement OpenHardwareOpusDecoderForMultiStreamEx and DecodeInterleavedForMultiStream
2023-08-28 19:14:44 -04:00
199de26995 Merge pull request #11399 from liamwhite/cubeb-latency
audio: allow more latency in cubeb initialization
2023-08-28 19:14:33 -04:00
6c68b07a67 sfdnsres: ensure lp1 is not resolved 2023-08-28 11:55:53 -04:00
1d201c71dc Fix node id index in DropVoices 2023-08-28 10:35:30 +01:00
4077ff6851 externals: Update SDL to 2.28.2 2023-08-27 21:08:28 -06:00
164f880f23 Use initial_frame to check interlaced flag
If final frame was transferred from GPU, it won't carry the props.

Fixes #11089
2023-08-28 00:48:53 +04:00
954144e22b audio: allow more latency in cubeb initialization 2023-08-27 12:46:01 -04:00
c2f827b85e hwopus: Implement OpenHardwareOpusDecoderForMultiStreamEx and DecodeInterleavedForMultiStream
Allows MLB The Show 22 to boot.

Fixes https://github.com/yuzu-emu/yuzu/issues/7911.
2023-08-27 18:03:10 +02:00
037f82025c android: Don't set a default emulation orientation
Could cause unnecessary configuration change when setting an orientation other than "Landscape"
2023-08-27 00:19:03 -04:00
338d6f29b1 android: Properly adjust emulation surface aspect ratio
Previously the emulation surface wouldn't respond properly to orientation changes. This would result in the screen appearing stretched when starting in one orientation and switching to another.

The code for calculating the bounds of the view have been changed to match the expected behavior now. Before the view would just match parent in height and width. Now instead of using setLeftTopRightBottom (which is intended to be used for animations) we pass newly calculated bounds for the view into super. Now the view bounds match the emulation output.

This also means that we don't need the overload for the SettingsActivity to launch it using an ActivityResultLauncher. We can just update the view in onResume.
2023-08-27 00:16:53 -04:00
ada4697300 Merge pull request #11389 from FernandoS27/discard-fix
Buffer Cache: fix discard writes.
2023-08-27 04:26:59 +02:00
acc99433c7 Buffer Cache: fix discard writes. 2023-08-27 03:45:43 +02:00
20 changed files with 177 additions and 78 deletions

View File

@ -524,7 +524,7 @@ if (ENABLE_SDL2)
if (YUZU_USE_BUNDLED_SDL2)
# Detect toolchain and platform
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.28.1")
set(SDL2_VER "SDL2-2.28.2")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
endif()

View File

@ -1,3 +1,11 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
End of merge log. You can find the original README.md below the break.
-----
<!--
SPDX-FileCopyrightText: 2018 yuzu Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later

2
externals/SDL vendored

View File

@ -164,7 +164,7 @@ if (NOT WIN32 AND NOT ANDROID)
--enable-decoder=h264
--enable-decoder=vp8
--enable-decoder=vp9
--enable-filter=yadif
--enable-filter=yadif,scale
--cc="${FFmpeg_CC}"
--cxx="${FFmpeg_CXX}"
${FFmpeg_HWACCEL_FLAGS}
@ -254,7 +254,7 @@ elseif(ANDROID)
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
elseif(WIN32)
# Use yuzu FFmpeg binaries
set(FFmpeg_EXT_NAME "ffmpeg-5.1.3")
set(FFmpeg_EXT_NAME "ffmpeg-6.0")
set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}")
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "")
set(FFmpeg_FOUND YES)

View File

@ -56,7 +56,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
android:name="org.yuzu.yuzu_emu.activities.EmulationActivity"
android:theme="@style/Theme.Yuzu.Main"
android:launchMode="singleTop"
android:screenOrientation="userLandscape"
android:supportsPictureInPicture="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|uiMode"
android:exported="true">
@ -67,6 +66,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
<data android:mimeType="application/octet-stream" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:mimeType="application/octet-stream"
android:scheme="content"/>
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />

View File

@ -11,7 +11,6 @@ import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
@ -246,17 +245,5 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
settings.putExtra(ARG_GAME_ID, gameId)
context.startActivity(settings)
}
fun launch(
context: Context,
launcher: ActivityResultLauncher<Intent>,
menuTag: String?,
gameId: String?
) {
val settings = Intent(context, SettingsActivity::class.java)
settings.putExtra(ARG_MENU_TAG, menuTag)
settings.putExtra(ARG_GAME_ID, gameId)
launcher.launch(settings)
}
}
}

View File

@ -7,11 +7,11 @@ import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
@ -19,8 +19,6 @@ import android.util.Rational
import android.view.*
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.Insets
@ -50,6 +48,7 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.overlay.InputOverlay
import org.yuzu.yuzu_emu.utils.*
@ -62,12 +61,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
private var _binding: FragmentEmulationBinding? = null
private val binding get() = _binding!!
val args by navArgs<EmulationFragmentArgs>()
private val args by navArgs<EmulationFragmentArgs>()
private lateinit var game: Game
private var isInFoldableLayout = false
private lateinit var onReturnFromSettings: ActivityResultLauncher<Intent>
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is EmulationActivity) {
@ -81,11 +80,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
.collect { updateFoldableLayout(context, it) }
}
}
onReturnFromSettings = context.activityResultRegistry.register(
"SettingsResult",
ActivityResultContracts.StartActivityForResult()
) { updateScreenLayout() }
} else {
throw IllegalStateException("EmulationFragment must have EmulationActivity parent")
}
@ -97,10 +91,25 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intentUri: Uri? = requireActivity().intent.data
var intentGame: Game? = null
if (intentUri != null) {
intentGame = if (Game.extensions.contains(FileUtil.getExtension(intentUri))) {
GameHelper.getGame(requireActivity().intent.data!!, false)
} else {
null
}
}
game = if (args.game != null) {
args.game!!
} else {
intentGame ?: error("[EmulationFragment] No bootable game present!")
}
// So this fragment doesn't restart on configuration changes; i.e. rotation.
retainInstance = true
preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
emulationState = EmulationState(args.game.path)
emulationState = EmulationState(game.path)
}
/**
@ -124,7 +133,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
updateShowFpsOverlay()
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
args.game.title
game.title
binding.inGameMenu.setNavigationItemSelectedListener {
when (it.itemId) {
R.id.menu_pause_emulation -> {
@ -149,12 +158,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
R.id.menu_settings -> {
SettingsActivity.launch(
requireContext(),
onReturnFromSettings,
SettingsFile.FILE_NAME_CONFIG,
""
)
SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
true
}

View File

@ -63,13 +63,13 @@ object GameHelper {
)
} else {
if (Game.extensions.contains(FileUtil.getExtension(it.uri))) {
games.add(getGame(it.uri))
games.add(getGame(it.uri, true))
}
}
}
}
private fun getGame(uri: Uri): Game {
fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
val filePath = uri.toString()
var name = NativeLibrary.getTitle(filePath)
@ -94,11 +94,13 @@ object GameHelper {
NativeLibrary.isHomebrew(filePath)
)
val addedTime = preferences.getLong(newGame.keyAddedToLibraryTime, 0L)
if (addedTime == 0L) {
preferences.edit()
.putLong(newGame.keyAddedToLibraryTime, System.currentTimeMillis())
.apply()
if (addedToLibrary) {
val addedTime = preferences.getLong(newGame.keyAddedToLibraryTime, 0L)
if (addedTime == 0L) {
preferences.edit()
.putLong(newGame.keyAddedToLibraryTime, System.currentTimeMillis())
.apply()
}
}
return newGame

View File

@ -7,7 +7,6 @@ import android.content.Context
import android.util.AttributeSet
import android.util.Rational
import android.view.SurfaceView
import kotlin.math.roundToInt
class FixedRatioSurfaceView @JvmOverloads constructor(
context: Context,
@ -22,27 +21,44 @@ class FixedRatioSurfaceView @JvmOverloads constructor(
*/
fun setAspectRatio(ratio: Rational?) {
aspectRatio = ratio?.toFloat() ?: 0f
requestLayout()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
val displayWidth: Float = MeasureSpec.getSize(widthMeasureSpec).toFloat()
val displayHeight: Float = MeasureSpec.getSize(heightMeasureSpec).toFloat()
if (aspectRatio != 0f) {
val newWidth: Int
val newHeight: Int
if (height * aspectRatio < width) {
newWidth = (height * aspectRatio).roundToInt()
newHeight = height
val displayAspect = displayWidth / displayHeight
if (displayAspect < aspectRatio) {
// Max out width
val halfHeight = displayHeight / 2
val surfaceHeight = displayWidth / aspectRatio
val newTop: Float = halfHeight - (surfaceHeight / 2)
val newBottom: Float = halfHeight + (surfaceHeight / 2)
super.onMeasure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(
newBottom.toInt() - newTop.toInt(),
MeasureSpec.EXACTLY
)
)
return
} else {
newWidth = width
newHeight = (width / aspectRatio).roundToInt()
// Max out height
val halfWidth = displayWidth / 2
val surfaceWidth = displayHeight * aspectRatio
val newLeft: Float = halfWidth - (surfaceWidth / 2)
val newRight: Float = halfWidth + (surfaceWidth / 2)
super.onMeasure(
MeasureSpec.makeMeasureSpec(
newRight.toInt() - newLeft.toInt(),
MeasureSpec.EXACTLY
),
heightMeasureSpec
)
return
}
val left = (width - newWidth) / 2
val top = (height - newHeight) / 2
setLeftTopRightBottom(left, top, left + newWidth, top + newHeight)
} else {
setLeftTopRightBottom(0, 0, width, height)
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}

View File

@ -12,7 +12,9 @@
tools:layout="@layout/fragment_emulation" >
<argument
android:name="game"
app:argType="org.yuzu.yuzu_emu.model.Game" />
app:argType="org.yuzu.yuzu_emu.model.Game"
app:nullable="true"
android:defaultValue="@null" />
</fragment>
</navigation>

View File

@ -62,7 +62,9 @@
android:label="EmulationActivity">
<argument
android:name="game"
app:argType="org.yuzu.yuzu_emu.model.Game" />
app:argType="org.yuzu.yuzu_emu.model.Game"
app:nullable="true"
android:defaultValue="@null" />
</activity>
<action

View File

@ -778,7 +778,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time
while (i < command_buffer.count) {
const auto node_id{cmd->node_id};
const auto node_id_type{cmd->node_id >> 28};
const auto node_id_base{cmd->node_id & 0xFFF};
const auto node_id_base{(cmd->node_id >> 16) & 0xFFF};
// If the new estimated process time falls below the limit, we're done dropping.
if (estimated_process_time <= time_limit) {

View File

@ -364,7 +364,7 @@ bool IsCubebSuitable() {
}
#endif
// Test min latency
// Get min latency
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;
@ -380,11 +380,6 @@ bool IsCubebSuitable() {
}
latency = std::max(latency, TargetSampleCount * 2);
if (latency > TargetSampleCount * 3) {
LOG_ERROR(Audio_Sink, "Cubeb latency is too high, it is not suitable.");
return false;
}
// Test opening a device with standard parameters
cubeb_devid output_device{0};
cubeb_devid input_device{0};

View File

@ -83,8 +83,8 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
break;
}
}
LOG_ERROR(Service_Audio, "Auto-selecting the {} backend",
Settings::CanonicalizeEnum(iter->id));
LOG_INFO(Service_Audio, "Auto-selecting the {} backend",
Settings::CanonicalizeEnum(iter->id));
} else {
if (iter != std::end(sink_details) && !iter->is_suitable()) {
LOG_ERROR(Service_Audio, "Selected backend {} is not suitable, falling back to null",

View File

@ -174,7 +174,7 @@ public:
{6, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleavedWithPerfAndResetOld"},
{7, nullptr, "DecodeInterleavedForMultiStreamWithPerfAndResetOld"},
{8, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"},
{9, nullptr, "DecodeInterleavedForMultiStream"},
{9, &IHardwareOpusDecoderManager::DecodeInterleavedForMultiStream, "DecodeInterleavedForMultiStream"},
};
// clang-format on
@ -206,6 +206,16 @@ private:
decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior);
}
void DecodeInterleavedForMultiStream(HLERequestContext& ctx) {
LOG_DEBUG(Audio, "called");
IPC::RequestParser rp{ctx};
const auto extra_behavior = rp.Pop<bool>() ? OpusDecoderState::ExtraBehavior::ResetContext
: OpusDecoderState::ExtraBehavior::None;
decoder_state.DecodeInterleaved(ctx, OpusDecoderState::PerfTime::Enabled, extra_behavior);
}
OpusDecoderState decoder_state;
};
@ -354,6 +364,40 @@ void HwOpus::OpenHardwareOpusDecoderEx(HLERequestContext& ctx) {
system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
}
void HwOpus::OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx) {
OpusMultiStreamParametersEx params;
std::memcpy(&params, ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
const auto& sample_rate = params.sample_rate;
const auto& channel_count = params.channel_count;
LOG_INFO(
Audio,
"called with sample_rate={}, channel_count={}, number_streams={}, number_stereo_streams={}",
sample_rate, channel_count, params.number_streams, params.number_stereo_streams);
ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
sample_rate == 12000 || sample_rate == 8000,
"Invalid sample rate");
int error = 0;
OpusDecoderPtr decoder{opus_multistream_decoder_create(
sample_rate, static_cast<int>(channel_count), params.number_streams,
params.number_stereo_streams, params.channel_mappings.data(), &error)};
if (error != OPUS_OK || decoder == nullptr) {
LOG_ERROR(Audio, "Failed to create Opus decoder (error={}).", error);
IPC::ResponseBuilder rb{ctx, 2};
// TODO(ogniK): Use correct error code
rb.Push(ResultUnknown);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IHardwareOpusDecoderManager>(
system, OpusDecoderState{std::move(decoder), sample_rate, channel_count});
}
HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
static const FunctionInfo functions[] = {
{0, &HwOpus::OpenHardwareOpusDecoder, "OpenHardwareOpusDecoder"},
@ -362,7 +406,8 @@ HwOpus::HwOpus(Core::System& system_) : ServiceFramework{system_, "hwopus"} {
{3, nullptr, "GetWorkBufferSizeForMultiStream"},
{4, &HwOpus::OpenHardwareOpusDecoderEx, "OpenHardwareOpusDecoderEx"},
{5, &HwOpus::GetWorkBufferSizeEx, "GetWorkBufferSizeEx"},
{6, nullptr, "OpenHardwareOpusDecoderForMultiStreamEx"},
{6, &HwOpus::OpenHardwareOpusDecoderForMultiStreamEx,
"OpenHardwareOpusDecoderForMultiStreamEx"},
{7, &HwOpus::GetWorkBufferSizeForMultiStreamEx, "GetWorkBufferSizeForMultiStreamEx"},
{8, nullptr, "GetWorkBufferSizeExEx"},
{9, nullptr, "GetWorkBufferSizeForMultiStreamExEx"},

View File

@ -18,8 +18,10 @@ struct OpusMultiStreamParametersEx {
u32 number_stereo_streams;
u32 use_large_frame_size;
u32 padding;
std::array<u32, 64> channel_mappings;
std::array<u8, 0x100> channel_mappings;
};
static_assert(sizeof(OpusMultiStreamParametersEx) == 0x118,
"OpusMultiStreamParametersEx has incorrect size");
class HwOpus final : public ServiceFramework<HwOpus> {
public:
@ -29,6 +31,7 @@ public:
private:
void OpenHardwareOpusDecoder(HLERequestContext& ctx);
void OpenHardwareOpusDecoderEx(HLERequestContext& ctx);
void OpenHardwareOpusDecoderForMultiStreamEx(HLERequestContext& ctx);
void GetWorkBufferSize(HLERequestContext& ctx);
void GetWorkBufferSizeEx(HLERequestContext& ctx);
void GetWorkBufferSizeForMultiStreamEx(HLERequestContext& ctx);

View File

@ -19,6 +19,12 @@ enum class ServerEnvironmentType : u8 {
Dp,
};
// This is nn::nsd::EnvironmentIdentifier
struct EnvironmentIdentifier {
std::array<u8, 8> identifier;
};
static_assert(sizeof(EnvironmentIdentifier) == 0x8);
NSD::NSD(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
@ -101,8 +107,9 @@ void NSD::ResolveEx(HLERequestContext& ctx) {
}
void NSD::GetEnvironmentIdentifier(HLERequestContext& ctx) {
const std::string environment_identifier = "lp1";
ctx.WriteBuffer(environment_identifier);
constexpr EnvironmentIdentifier lp1 = {
.identifier = {'l', 'p', '1', '\0', '\0', '\0', '\0', '\0'}};
ctx.WriteBuffer(lp1);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);

View File

@ -150,6 +150,12 @@ static std::pair<u32, GetAddrInfoError> GetHostByNameRequestImpl(HLERequestConte
const std::string host = Common::StringFromBuffer(host_buffer);
// For now, ignore options, which are in input buffer 1 for GetHostByNameRequestWithOptions.
// Prevent resolution of Nintendo servers
if (host.find("srv.nintendo.net") != std::string::npos) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
return {0, GetAddrInfoError::AGAIN};
}
auto res = Network::GetAddressInfo(host, /*service*/ std::nullopt);
if (!res.has_value()) {
return {0, Translate(res.error())};
@ -261,6 +267,12 @@ static std::pair<u32, GetAddrInfoError> GetAddrInfoRequestImpl(HLERequestContext
const auto host_buffer = ctx.ReadBuffer(0);
const std::string host = Common::StringFromBuffer(host_buffer);
// Prevent resolution of Nintendo servers
if (host.find("srv.nintendo.net") != std::string::npos) {
LOG_WARNING(Network, "Resolution of hostname {} requested, returning EAI_AGAIN", host);
return {0, GetAddrInfoError::AGAIN};
}
std::optional<std::string> service = std::nullopt;
if (ctx.CanReadBuffer(1)) {
const std::span<const u8> service_buffer = ctx.ReadBuffer(1);

View File

@ -289,8 +289,11 @@ std::pair<typename P::Buffer*, u32> BufferCache<P>::ObtainBuffer(GPUVAddr gpu_ad
MarkWrittenBuffer(buffer_id, *cpu_addr, size);
break;
case ObtainBufferOperation::DiscardWrite: {
IntervalType interval{*cpu_addr, size};
VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
IntervalType interval{cpu_addr_start, cpu_addr_end};
ClearDownload(interval);
common_ranges.subtract(interval);
break;
}
default:
@ -1159,6 +1162,11 @@ void BufferCache<P>::UpdateDrawIndirect() {
.size = static_cast<u32>(size),
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
};
VAddr cpu_addr_start = Common::AlignDown(*cpu_addr, 64);
VAddr cpu_addr_end = Common::AlignUp(*cpu_addr + size, 64);
IntervalType interval{cpu_addr_start, cpu_addr_end};
ClearDownload(interval);
common_ranges.subtract(interval);
};
if (current_draw_indirect->include_count) {
update(current_draw_indirect->count_start_address, sizeof(u32),

View File

@ -319,6 +319,7 @@ void Codec::Decode() {
LOG_WARNING(Service_NVDRV, "Zero width or height in frame");
return;
}
bool is_interlaced = initial_frame->interlaced_frame != 0;
if (av_codec_ctx->hw_device_ctx) {
final_frame = AVFramePtr{av_frame_alloc(), AVFrameDeleter};
ASSERT_MSG(final_frame, "av_frame_alloc final_frame failed");
@ -334,7 +335,7 @@ void Codec::Decode() {
UNIMPLEMENTED_MSG("Unexpected video format: {}", final_frame->format);
return;
}
if (!final_frame->interlaced_frame) {
if (!is_interlaced) {
av_frames.push(std::move(final_frame));
} else {
if (!filters_initialized) {