diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp index c725baa98..d80e74225 100644 --- a/src/video_core/cdma_pusher.cpp +++ b/src/video_core/cdma_pusher.cpp @@ -38,45 +38,42 @@ CDmaPusher::CDmaPusher(GPU& gpu_) CDmaPusher::~CDmaPusher() = default; void CDmaPusher::ProcessEntries(ChCommandHeaderList&& entries) { - std::vector values(entries.size()); - std::memcpy(values.data(), entries.data(), entries.size() * sizeof(u32)); - - for (const u32 value : values) { + for (const auto& value : entries) { if (mask != 0) { const auto lbs = static_cast(std::countr_zero(mask)); mask &= ~(1U << lbs); - ExecuteCommand(static_cast(offset + lbs), value); + ExecuteCommand(offset + lbs, value.raw); continue; } else if (count != 0) { --count; - ExecuteCommand(static_cast(offset), value); + ExecuteCommand(offset, value.raw); if (incrementing) { ++offset; } continue; } - const auto mode = static_cast((value >> 28) & 0xf); + const auto mode = value.submission_mode.Value(); switch (mode) { case ChSubmissionMode::SetClass: { - mask = value & 0x3f; - offset = (value >> 16) & 0xfff; - current_class = static_cast((value >> 6) & 0x3ff); + mask = value.value & 0x3f; + offset = value.method_offset; + current_class = static_cast((value.value >> 6) & 0x3ff); break; } case ChSubmissionMode::Incrementing: case ChSubmissionMode::NonIncrementing: - count = value & 0xffff; - offset = (value >> 16) & 0xfff; + count = value.value; + offset = value.method_offset; incrementing = mode == ChSubmissionMode::Incrementing; break; case ChSubmissionMode::Mask: - mask = value & 0xffff; - offset = (value >> 16) & 0xfff; + mask = value.value; + offset = value.method_offset; break; case ChSubmissionMode::Immediate: { - const u32 data = value & 0xfff; - offset = (value >> 16) & 0xfff; - ExecuteCommand(static_cast(offset), data); + const u32 data = value.value & 0xfff; + offset = value.method_offset; + ExecuteCommand(offset, data); break; } default: @@ -89,8 +86,8 @@ void CDmaPusher::ProcessEntries(ChCommandHeaderList&& entries) { void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { switch (current_class) { case ChClassId::NvDec: - ThiStateWrite(nvdec_thi_state, state_offset, {data}); - switch (static_cast(state_offset)) { + ThiStateWrite(nvdec_thi_state, offset, data); + switch (static_cast(offset)) { case ThiMethod::IncSyncpt: { LOG_DEBUG(Service_NVDRV, "NVDEC Class IncSyncpt Method"); const auto syncpoint_id = static_cast(data & 0xFF); @@ -106,8 +103,8 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { case ThiMethod::SetMethod1: LOG_DEBUG(Service_NVDRV, "NVDEC method 0x{:X}", static_cast(nvdec_thi_state.method_0)); - nvdec_processor->ProcessMethod(static_cast(nvdec_thi_state.method_0), - {data}); + nvdec_processor->ProcessMethod( + static_cast(nvdec_thi_state.method_0), data); break; default: break; @@ -131,7 +128,8 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { case ThiMethod::SetMethod1: LOG_DEBUG(Service_NVDRV, "VIC method 0x{:X}, Args=({})", static_cast(vic_thi_state.method_0), data); - vic_processor->ProcessMethod(static_cast(vic_thi_state.method_0), {data}); + vic_processor->ProcessMethod(static_cast(vic_thi_state.method_0), + data); break; default: break; @@ -140,7 +138,7 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { case ChClassId::Host1x: // This device is mainly for syncpoint synchronization LOG_DEBUG(Service_NVDRV, "Host1X Class Method"); - host1x_processor->ProcessMethod(static_cast(state_offset), {data}); + host1x_processor->ProcessMethod(static_cast(offset), data); break; default: UNIMPLEMENTED_MSG("Current class not implemented {:X}", static_cast(current_class)); @@ -148,10 +146,9 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) { } } -void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 state_offset, - const std::vector& arguments) { - u8* const state_offset_ptr = reinterpret_cast(&state) + sizeof(u32) * state_offset; - std::memcpy(state_offset_ptr, arguments.data(), sizeof(u32) * arguments.size()); +void CDmaPusher::ThiStateWrite(ThiRegisters& state, u32 offset, u32 argument) { + u8* const state_offset = reinterpret_cast(&state) + sizeof(u32) * offset; + std::memcpy(state_offset, &argument, sizeof(u32)); } } // namespace Tegra diff --git a/src/video_core/cdma_pusher.h b/src/video_core/cdma_pusher.h index de7a3a35b..e16eb2254 100644 --- a/src/video_core/cdma_pusher.h +++ b/src/video_core/cdma_pusher.h @@ -48,16 +48,10 @@ enum class ChClassId : u32 { NvDec = 0xf0 }; -enum class ChMethod : u32 { - Empty = 0, - SetMethod = 0x10, - SetData = 0x11, -}; - union ChCommandHeader { u32 raw; BitField<0, 16, u32> value; - BitField<16, 12, ChMethod> method_offset; + BitField<16, 12, u32> method_offset; BitField<28, 4, ChSubmissionMode> submission_mode; }; static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size"); @@ -107,7 +101,7 @@ private: void ExecuteCommand(u32 state_offset, u32 data); /// Write arguments value to the ThiRegisters member at the specified offset - void ThiStateWrite(ThiRegisters& state, u32 state_offset, const std::vector& arguments); + void ThiStateWrite(ThiRegisters& state, u32 offset, u32 argument); GPU& gpu; std::shared_ptr nvdec_processor; @@ -118,8 +112,8 @@ private: ThiRegisters vic_thi_state{}; ThiRegisters nvdec_thi_state{}; - s32 count{}; - s32 offset{}; + u32 count{}; + u32 offset{}; u32 mask{}; bool incrementing{}; }; diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp index 79e1f4e13..e4f919afd 100644 --- a/src/video_core/command_classes/nvdec.cpp +++ b/src/video_core/command_classes/nvdec.cpp @@ -12,16 +12,16 @@ Nvdec::Nvdec(GPU& gpu_) : gpu(gpu_), codec(std::make_unique(gpu)) {} Nvdec::~Nvdec() = default; -void Nvdec::ProcessMethod(Method method, const std::vector& arguments) { +void Nvdec::ProcessMethod(Method method, u32 argument) { if (method == Method::SetVideoCodec) { - codec->StateWrite(static_cast(method), arguments[0]); + codec->StateWrite(static_cast(method), argument); } else { - codec->StateWrite(static_cast(method), static_cast(arguments[0]) << 8); + codec->StateWrite(static_cast(method), static_cast(argument) << 8); } switch (method) { case Method::SetVideoCodec: - codec->SetTargetCodec(static_cast(arguments[0])); + codec->SetTargetCodec(static_cast(argument)); break; case Method::Execute: Execute(); diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h index e4877c533..e66be80b8 100644 --- a/src/video_core/command_classes/nvdec.h +++ b/src/video_core/command_classes/nvdec.h @@ -23,7 +23,7 @@ public: ~Nvdec(); /// Writes the method into the state, Invoke Execute() if encountered - void ProcessMethod(Method method, const std::vector& arguments); + void ProcessMethod(Method method, u32 argument); /// Return most recently decoded frame [[nodiscard]] AVFramePtr GetFrame(); diff --git a/src/video_core/command_classes/vic.h b/src/video_core/command_classes/vic.h index 6eaf72f21..f5a2ed100 100644 --- a/src/video_core/command_classes/vic.h +++ b/src/video_core/command_classes/vic.h @@ -15,43 +15,6 @@ namespace Tegra { class GPU; class Nvdec; -struct PlaneOffsets { - u32 luma_offset{}; - u32 chroma_u_offset{}; - u32 chroma_v_offset{}; -}; - -struct VicRegisters { - INSERT_PADDING_WORDS(64); - u32 nop{}; - INSERT_PADDING_WORDS(15); - u32 pm_trigger{}; - INSERT_PADDING_WORDS(47); - u32 set_application_id{}; - u32 set_watchdog_timer{}; - INSERT_PADDING_WORDS(17); - u32 context_save_area{}; - u32 context_switch{}; - INSERT_PADDING_WORDS(43); - u32 execute{}; - INSERT_PADDING_WORDS(63); - std::array, 8> surfacex_slots{}; - u32 picture_index{}; - u32 control_params{}; - u32 config_struct_offset{}; - u32 filter_struct_offset{}; - u32 palette_offset{}; - u32 hist_offset{}; - u32 context_id{}; - u32 fce_ucode_size{}; - PlaneOffsets output_surface{}; - u32 fce_ucode_offset{}; - INSERT_PADDING_WORDS(4); - std::array slot_context_id{}; - INSERT_PADDING_WORDS(16); -}; -static_assert(sizeof(VicRegisters) == 0x7A0, "VicRegisters is an invalid size"); - class Vic { public: enum class Method : u32 { @@ -67,14 +30,11 @@ public: ~Vic(); /// Write to the device state. - void ProcessMethod(Method method, const std::vector& arguments); + void ProcessMethod(Method method, u32 argument); private: void Execute(); - void VicStateWrite(u32 offset, u32 arguments); - VicRegisters vic_state{}; - enum class VideoPixelFormat : u64_le { RGBA8 = 0x1f, BGRA8 = 0x20, @@ -88,8 +48,6 @@ private: BitField<9, 2, u64_le> chroma_loc_vert; BitField<11, 4, u64_le> block_linear_kind; BitField<15, 4, u64_le> block_linear_height_log2; - BitField<19, 3, u64_le> reserved0; - BitField<22, 10, u64_le> reserved1; BitField<32, 14, u64_le> surface_width_minus1; BitField<46, 14, u64_le> surface_height_minus1; };