diff options
23 files changed, 208 insertions, 184 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e9502a97..1bd9d2aa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,7 @@ macro(yuzu_find_packages) # Cmake Pkg Prefix Version Conan Pkg "Boost 1.73 boost/1.73.0" "Catch2 2.13 catch2/2.13.0" - "fmt 7.0 fmt/7.0.3" + "fmt 7.1 fmt/7.1.0" # can't use until https://github.com/bincrafters/community/issues/1173 #"libzip 1.5 libzip/1.5.2@bincrafters/stable" "lz4 1.8 lz4/1.9.2" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71efbb40d..dbda528ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,6 @@ if (MSVC) # /Zc:inline - Let codegen omit inline functions in object files # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null add_compile_options( - /W3 /MP /Zi /Zo @@ -43,6 +42,13 @@ if (MSVC) /Zc:externConstexpr /Zc:inline /Zc:throwingNew + + # Warnings + /W3 + /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect + /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? + /we4555 # Expression has no effect; expected expression with side-effect + /we4834 # Discarding return value of function with 'nodiscard' attribute ) # /GS- - No stack buffer overflow checks @@ -56,6 +62,7 @@ else() -Werror=implicit-fallthrough -Werror=missing-declarations -Werror=reorder + -Werror=unused-result -Wextra -Wmissing-declarations -Wno-attributes diff --git a/src/common/file_util.h b/src/common/file_util.h index 8b587320f..840cde2a6 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -232,7 +232,7 @@ public: void Swap(IOFile& other) noexcept; - [[nodiscard]] bool Open(const std::string& filename, const char openmode[], int flags = 0); + bool Open(const std::string& filename, const char openmode[], int flags = 0); bool Close(); template <typename T> diff --git a/src/common/misc.cpp b/src/common/misc.cpp index 68cb86cd1..1d5393597 100644 --- a/src/common/misc.cpp +++ b/src/common/misc.cpp @@ -16,16 +16,23 @@ // Call directly after the command or use the error num. // This function might change the error code. std::string GetLastErrorMsg() { - static const std::size_t buff_size = 255; + static constexpr std::size_t buff_size = 255; char err_str[buff_size]; #ifdef _WIN32 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr); + return std::string(err_str, buff_size); +#elif defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) + // Thread safe (GNU-specific) + const char* str = strerror_r(errno, err_str, buff_size); + return std::string(str); #else // Thread safe (XSI-compliant) - strerror_r(errno, err_str, buff_size); + const int success = strerror_r(errno, err_str, buff_size); + if (success != 0) { + return {}; + } + return std::string(err_str); #endif - - return std::string(err_str, buff_size); } diff --git a/src/common/stream.h b/src/common/stream.h index 2585c16af..0e40692de 100644 --- a/src/common/stream.h +++ b/src/common/stream.h @@ -21,6 +21,12 @@ public: explicit Stream(); ~Stream(); + Stream(const Stream&) = delete; + Stream& operator=(const Stream&) = delete; + + Stream(Stream&&) = default; + Stream& operator=(Stream&&) = default; + /// Reposition bitstream "cursor" to the specified offset from origin void Seek(s32 offset, SeekOrigin origin); @@ -30,15 +36,15 @@ public: /// Writes byte at current position void WriteByte(u8 byte); - std::size_t GetPosition() const { + [[nodiscard]] std::size_t GetPosition() const { return position; } - std::vector<u8>& GetBuffer() { + [[nodiscard]] std::vector<u8>& GetBuffer() { return buffer; } - const std::vector<u8>& GetBuffer() const { + [[nodiscard]] const std::vector<u8>& GetBuffer() const { return buffer; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index b27ee0502..75d9191ff 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -36,8 +36,8 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, const std::v return IocCtrlEventRegister(input, output); case IoctlCommand::IocCtrlEventUnregisterCommand: return IocCtrlEventUnregister(input, output); - case IoctlCommand::IocCtrlEventSignalCommand: - return IocCtrlEventSignal(input, output); + case IoctlCommand::IocCtrlClearEventWaitCommand: + return IocCtrlClearEventWait(input, output); default: UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; @@ -154,23 +154,17 @@ u32 nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input, std::vecto return NvResult::Success; } -u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output) { +u32 nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) { IocCtrlEventSignalParams params{}; std::memcpy(¶ms, input.data(), sizeof(params)); - // TODO(Blinkhawk): This is normally called when an NvEvents timeout on WaitSynchronization - // It is believed from RE to cancel the GPU Event. However, better research is required - u32 event_id = params.user_event_id & 0x00FF; - LOG_WARNING(Service_NVDRV, "(STUBBED) called, user_event_id: {:X}", event_id); + u32 event_id = params.event_id & 0x00FF; + LOG_WARNING(Service_NVDRV, "cleared event wait on, event_id: {:X}", event_id); if (event_id >= MaxNvEvents) { return NvResult::BadParameter; } if (events_interface.status[event_id] == EventState::Waiting) { - auto& gpu = system.GPU(); - if (gpu.CancelSyncptInterrupt(events_interface.assigned_syncpt[event_id], - events_interface.assigned_value[event_id])) { - events_interface.LiberateEvent(event_id); - events_interface.events[event_id].writable->Signal(); - } + events_interface.LiberateEvent(event_id); + events_interface.events[event_id].writable->Signal(); } return NvResult::Success; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 9898623de..f7b04d9f1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -31,7 +31,7 @@ private: IocSyncptWaitexCommand = 0xC0100019, IocSyncptReadMaxCommand = 0xC008001A, IocGetConfigCommand = 0xC183001B, - IocCtrlEventSignalCommand = 0xC004001C, + IocCtrlClearEventWaitCommand = 0xC004001C, IocCtrlEventWaitCommand = 0xC010001D, IocCtrlEventWaitAsyncCommand = 0xC010001E, IocCtrlEventRegisterCommand = 0xC004001F, @@ -94,7 +94,7 @@ private: static_assert(sizeof(IocGetConfigParams) == 387, "IocGetConfigParams is incorrect size"); struct IocCtrlEventSignalParams { - u32_le user_event_id; + u32_le event_id; }; static_assert(sizeof(IocCtrlEventSignalParams) == 4, "IocCtrlEventSignalParams is incorrect size"); @@ -142,7 +142,7 @@ private: u32 IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); - u32 IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output); + u32 IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); EventInterface& events_interface; }; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 85792495f..30f03f845 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -38,7 +38,7 @@ std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::s namespace NvErrCodes { constexpr u32 Success{}; -constexpr u32 OutOfMemory{static_cast<u32>(-12)}; +[[maybe_unused]] constexpr u32 OutOfMemory{static_cast<u32>(-12)}; constexpr u32 InvalidInput{static_cast<u32>(-22)}; } // namespace NvErrCodes diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 2df410be8..1adf3cd13 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp @@ -4,6 +4,7 @@ #include <cstring> #include <fstream> +#include <vector> #include "common/assert.h" #include "video_core/command_classes/codecs/codec.h" #include "video_core/command_classes/codecs/h264.h" diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h index 2e56daf29..cb67094f6 100644 --- a/src/video_core/command_classes/codecs/codec.h +++ b/src/video_core/command_classes/codecs/codec.h @@ -5,8 +5,6 @@ #pragma once #include <memory> -#include <vector> -#include "common/common_funcs.h" #include "common/common_types.h" #include "video_core/command_classes/nvdec_common.h" diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/command_classes/codecs/h264.cpp index 1a39f7b23..549a40f52 100644 --- a/src/video_core/command_classes/codecs/h264.cpp +++ b/src/video_core/command_classes/codecs/h264.cpp @@ -18,12 +18,27 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#include <array> #include "common/bit_util.h" #include "video_core/command_classes/codecs/h264.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" namespace Tegra::Decoder { +namespace { +// ZigZag LUTs from libavcodec. +constexpr std::array<u8, 64> zig_zag_direct{ + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, + 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, + 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, +}; + +constexpr std::array<u8, 16> zig_zag_scan{ + 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4, + 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4, 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4, +}; +} // Anonymous namespace + H264::H264(GPU& gpu_) : gpu(gpu_) {} H264::~H264() = default; @@ -48,7 +63,8 @@ std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, bo writer.WriteU(0, 8); writer.WriteU(31, 8); writer.WriteUe(0); - const s32 chroma_format_idc = (context.h264_parameter_set.flags >> 12) & 0x3; + const auto chroma_format_idc = + static_cast<u32>((context.h264_parameter_set.flags >> 12) & 3); writer.WriteUe(chroma_format_idc); if (chroma_format_idc == 3) { writer.WriteBit(false); @@ -59,8 +75,8 @@ std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, bo writer.WriteBit(false); // QpprimeYZeroTransformBypassFlag writer.WriteBit(false); // Scaling matrix present flag - const s32 order_cnt_type = static_cast<s32>((context.h264_parameter_set.flags >> 14) & 3); - writer.WriteUe(static_cast<s32>((context.h264_parameter_set.flags >> 8) & 0xf)); + const auto order_cnt_type = static_cast<u32>((context.h264_parameter_set.flags >> 14) & 3); + writer.WriteUe(static_cast<u32>((context.h264_parameter_set.flags >> 8) & 0xf)); writer.WriteUe(order_cnt_type); if (order_cnt_type == 0) { writer.WriteUe(context.h264_parameter_set.log2_max_pic_order_cnt); @@ -100,7 +116,7 @@ std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, bo writer.WriteUe(0); writer.WriteUe(0); - writer.WriteBit(context.h264_parameter_set.entropy_coding_mode_flag); + writer.WriteBit(context.h264_parameter_set.entropy_coding_mode_flag != 0); writer.WriteBit(false); writer.WriteUe(0); writer.WriteUe(context.h264_parameter_set.num_refidx_l0_default_active); @@ -172,8 +188,8 @@ void H264BitWriter::WriteSe(s32 value) { WriteExpGolombCodedInt(value); } -void H264BitWriter::WriteUe(s32 value) { - WriteExpGolombCodedUInt((u32)value); +void H264BitWriter::WriteUe(u32 value) { + WriteExpGolombCodedUInt(value); } void H264BitWriter::End() { diff --git a/src/video_core/command_classes/codecs/h264.h b/src/video_core/command_classes/codecs/h264.h index 21752dd90..f2292fd2f 100644 --- a/src/video_core/command_classes/codecs/h264.h +++ b/src/video_core/command_classes/codecs/h264.h @@ -38,7 +38,7 @@ public: /// WriteSe and WriteUe write in the Exp-Golomb-coded syntax void WriteU(s32 value, s32 value_sz); void WriteSe(s32 value); - void WriteUe(s32 value); + void WriteUe(u32 value); /// Finalize the bitstream void End(); @@ -55,18 +55,6 @@ public: const std::vector<u8>& GetByteArray() const; private: - // ZigZag LUTs from libavcodec. - static constexpr std::array<u8, 64> zig_zag_direct{ - 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, - 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, - 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, - }; - - static constexpr std::array<u8, 16> zig_zag_scan{ - 0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4, - 1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4, 3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4, - }; - void WriteBits(s32 value, s32 bit_count); void WriteExpGolombCodedInt(s32 value); void WriteExpGolombCodedUInt(u32 value); diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp index d205a8f5d..42520f856 100644 --- a/src/video_core/command_classes/codecs/vp9.cpp +++ b/src/video_core/command_classes/codecs/vp9.cpp @@ -9,7 +9,7 @@ #include "video_core/memory_manager.h" namespace Tegra::Decoder { - +namespace { // Default compressed header probabilities once frame context resets constexpr Vp9EntropyProbs default_probs{ .y_mode_prob{ @@ -170,6 +170,89 @@ constexpr Vp9EntropyProbs default_probs{ .high_precision{128, 128}, }; +constexpr std::array<s32, 256> norm_lut{ + 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +constexpr std::array<s32, 254> map_lut{ + 20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 2, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 3, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 4, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 5, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 6, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 7, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 8, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 9, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 10, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 13, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 14, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 15, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 17, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 18, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 19, +}; + +// 6.2.14 Tile size calculation + +[[nodiscard]] s32 CalcMinLog2TileCols(s32 frame_width) { + const s32 sb64_cols = (frame_width + 63) / 64; + s32 min_log2 = 0; + + while ((64 << min_log2) < sb64_cols) { + min_log2++; + } + + return min_log2; +} + +[[nodiscard]] s32 CalcMaxLog2TileCols(s32 frame_width) { + const s32 sb64_cols = (frame_width + 63) / 64; + s32 max_log2 = 1; + + while ((sb64_cols >> max_log2) >= 4) { + max_log2++; + } + + return max_log2 - 1; +} + +// Recenters probability. Based on section 6.3.6 of VP9 Specification +[[nodiscard]] s32 RecenterNonNeg(s32 new_prob, s32 old_prob) { + if (new_prob > old_prob * 2) { + return new_prob; + } + + if (new_prob >= old_prob) { + return (new_prob - old_prob) * 2; + } + + return (old_prob - new_prob) * 2 - 1; +} + +// Adjusts old_prob depending on new_prob. Based on section 6.3.5 of VP9 Specification +[[nodiscard]] s32 RemapProbability(s32 new_prob, s32 old_prob) { + new_prob--; + old_prob--; + + std::size_t index{}; + + if (old_prob * 2 <= 0xff) { + index = static_cast<std::size_t>(std::max(0, RecenterNonNeg(new_prob, old_prob) - 1)); + } else { + index = static_cast<std::size_t>( + std::max(0, RecenterNonNeg(0xff - 1 - new_prob, 0xff - 1 - old_prob) - 1)); + } + + return map_lut[index]; +} +} // Anonymous namespace + VP9::VP9(GPU& gpu) : gpu(gpu) {} VP9::~VP9() = default; @@ -207,32 +290,6 @@ void VP9::WriteProbabilityDelta(VpxRangeEncoder& writer, u8 new_prob, u8 old_pro EncodeTermSubExp(writer, delta); } -s32 VP9::RemapProbability(s32 new_prob, s32 old_prob) { - new_prob--; - old_prob--; - - std::size_t index{}; - - if (old_prob * 2 <= 0xff) { - index = static_cast<std::size_t>(std::max(0, RecenterNonNeg(new_prob, old_prob) - 1)); - } else { - index = static_cast<std::size_t>( - std::max(0, RecenterNonNeg(0xff - 1 - new_prob, 0xff - 1 - old_prob) - 1)); - } - - return map_lut[index]; -} - -s32 VP9::RecenterNonNeg(s32 new_prob, s32 old_prob) { - if (new_prob > old_prob * 2) { - return new_prob; - } else if (new_prob >= old_prob) { - return (new_prob - old_prob) * 2; - } else { - return (old_prob - new_prob) * 2 - 1; - } -} - void VP9::EncodeTermSubExp(VpxRangeEncoder& writer, s32 value) { if (WriteLessThan(writer, value, 16)) { writer.Write(value, 4); @@ -332,28 +389,6 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_ } } -s32 VP9::CalcMinLog2TileCols(s32 frame_width) { - const s32 sb64_cols = (frame_width + 63) / 64; - s32 min_log2 = 0; - - while ((64 << min_log2) < sb64_cols) { - min_log2++; - } - - return min_log2; -} - -s32 VP9::CalcMaxLog2TileCols(s32 frameWidth) { - const s32 sb64_cols = (frameWidth + 63) / 64; - s32 max_log2 = 1; - - while ((sb64_cols >> max_log2) >= 4) { - max_log2++; - } - - return max_log2 - 1; -} - Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) { PictureInfo picture_info{}; gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo)); @@ -379,14 +414,14 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) Vp9FrameContainer frame{}; { gpu.SyncGuestHost(); - frame.info = std::move(GetVp9PictureInfo(state)); + frame.info = GetVp9PictureInfo(state); frame.bit_stream.resize(frame.info.bitstream_size); gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.bit_stream.data(), frame.info.bitstream_size); } // Buffer two frames, saving the last show frame info - if (next_next_frame.bit_stream.size() != 0) { + if (!next_next_frame.bit_stream.empty()) { Vp9FrameContainer temp{ .info = frame.info, .bit_stream = frame.bit_stream, @@ -396,15 +431,15 @@ Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) frame.bit_stream = next_next_frame.bit_stream; next_next_frame = std::move(temp); - if (next_frame.bit_stream.size() != 0) { - Vp9FrameContainer temp{ + if (!next_frame.bit_stream.empty()) { + Vp9FrameContainer temp2{ .info = frame.info, .bit_stream = frame.bit_stream, }; next_frame.info.show_frame = frame.info.last_frame_shown; frame.info = next_frame.info; frame.bit_stream = next_frame.bit_stream; - next_frame = std::move(temp); + next_frame = std::move(temp2); } else { next_frame.info = frame.info; next_frame.bit_stream = frame.bit_stream; @@ -605,12 +640,6 @@ std::vector<u8> VP9::ComposeCompressedHeader() { writer.End(); return writer.GetBuffer(); - - const auto writer_bytearray = writer.GetBuffer(); - - std::vector<u8> compressed_header(writer_bytearray.size()); - std::memcpy(compressed_header.data(), writer_bytearray.data(), writer_bytearray.size()); - return compressed_header; } VpxBitStreamWriter VP9::ComposeUncompressedHeader() { @@ -648,7 +677,6 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { current_frame_info.intra_only = true; } else { - std::array<s32, 3> ref_frame_index; if (!current_frame_info.show_frame) { uncomp_writer.WriteBit(current_frame_info.intra_only); @@ -663,9 +691,9 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { } // Last, Golden, Altref frames - ref_frame_index = std::array<s32, 3>{0, 1, 2}; + std::array<s32, 3> ref_frame_index{0, 1, 2}; - // set when next frame is hidden + // Set when next frame is hidden // altref and golden references are swapped if (swap_next_golden) { ref_frame_index = std::array<s32, 3>{0, 2, 1}; @@ -754,17 +782,19 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() { for (std::size_t index = 0; index < current_frame_info.ref_deltas.size(); index++) { const s8 old_deltas = loop_filter_ref_deltas[index]; const s8 new_deltas = current_frame_info.ref_deltas[index]; + const bool differing_delta = old_deltas != new_deltas; - loop_filter_delta_update |= - (update_loop_filter_ref_deltas[index] = old_deltas != new_deltas); + update_loop_filter_ref_deltas[index] = differing_delta; + loop_filter_delta_update |= differing_delta; } for (std::size_t index = 0; index < current_frame_info.mode_deltas.size(); index++) { const s8 old_deltas = loop_filter_mode_deltas[index]; const s8 new_deltas = current_frame_info.mode_deltas[index]; + const bool differing_delta = old_deltas != new_deltas; - loop_filter_delta_update |= - (update_loop_filter_mode_deltas[index] = old_deltas != new_deltas); + update_loop_filter_mode_deltas[index] = differing_delta; + loop_filter_delta_update |= differing_delta; } uncomp_writer.WriteBit(loop_filter_delta_update); @@ -829,7 +859,7 @@ std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) { { Vp9FrameContainer curr_frame = GetCurrentFrame(state); current_frame_info = curr_frame.info; - bitstream = curr_frame.bit_stream; + bitstream = std::move(curr_frame.bit_stream); } // The uncompressed header routine sets PrevProb parameters needed for the compressed header diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h index 748e11bae..05c9682fa 100644 --- a/src/video_core/command_classes/codecs/vp9.h +++ b/src/video_core/command_classes/codecs/vp9.h @@ -4,9 +4,9 @@ #pragma once -#include <unordered_map> +#include <array> #include <vector> -#include "common/common_funcs.h" + #include "common/common_types.h" #include "common/stream.h" #include "video_core/command_classes/codecs/vp9_types.h" @@ -25,6 +25,12 @@ public: VpxRangeEncoder(); ~VpxRangeEncoder(); + VpxRangeEncoder(const VpxRangeEncoder&) = delete; + VpxRangeEncoder& operator=(const VpxRangeEncoder&) = delete; + + VpxRangeEncoder(VpxRangeEncoder&&) = default; + VpxRangeEncoder& operator=(VpxRangeEncoder&&) = default; + /// Writes the rightmost value_size bits from value into the stream void Write(s32 value, s32 value_size); @@ -37,11 +43,11 @@ public: /// Signal the end of the bitstream void End(); - std::vector<u8>& GetBuffer() { + [[nodiscard]] std::vector<u8>& GetBuffer() { return base_stream.GetBuffer(); } - const std::vector<u8>& GetBuffer() const { + [[nodiscard]] const std::vector<u8>& GetBuffer() const { return base_stream.GetBuffer(); } @@ -52,17 +58,6 @@ private: u32 range{0xff}; s32 count{-24}; s32 half_probability{128}; - static constexpr std::array<s32, 256> norm_lut{ - 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; }; class VpxBitStreamWriter { @@ -70,6 +65,12 @@ public: VpxBitStreamWriter(); ~VpxBitStreamWriter(); + VpxBitStreamWriter(const VpxBitStreamWriter&) = delete; + VpxBitStreamWriter& operator=(const VpxBitStreamWriter&) = delete; + + VpxBitStreamWriter(VpxBitStreamWriter&&) = default; + VpxBitStreamWriter& operator=(VpxBitStreamWriter&&) = default; + /// Write an unsigned integer value void WriteU(u32 value, u32 value_size); @@ -86,10 +87,10 @@ public: void Flush(); /// Returns byte_array - std::vector<u8>& GetByteArray(); + [[nodiscard]] std::vector<u8>& GetByteArray(); /// Returns const byte_array - const std::vector<u8>& GetByteArray() const; + [[nodiscard]] const std::vector<u8>& GetByteArray() const; private: /// Write bit_count bits from value into buffer @@ -110,12 +111,18 @@ public: explicit VP9(GPU& gpu); ~VP9(); + VP9(const VP9&) = delete; + VP9& operator=(const VP9&) = delete; + + VP9(VP9&&) = default; + VP9& operator=(VP9&&) = delete; + /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec /// documentation std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state); /// Returns true if the most recent frame was a hidden frame. - bool WasFrameHidden() const { + [[nodiscard]] bool WasFrameHidden() const { return hidden; } @@ -132,12 +139,6 @@ private: /// Generates compressed header probability deltas in the bitstream writer void WriteProbabilityDelta(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob); - /// Adjusts old_prob depending on new_prob. Based on section 6.3.5 of VP9 Specification - s32 RemapProbability(s32 new_prob, s32 old_prob); - - /// Recenters probability. Based on section 6.3.6 of VP9 Specification - s32 RecenterNonNeg(s32 new_prob, s32 old_prob); - /// Inverse of 6.3.4 Decode term subexp void EncodeTermSubExp(VpxRangeEncoder& writer, s32 value); @@ -157,22 +158,18 @@ private: /// Write motion vector probability updates. 6.3.17 in the spec void WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob); - /// 6.2.14 Tile size calculation - s32 CalcMinLog2TileCols(s32 frame_width); - s32 CalcMaxLog2TileCols(s32 frame_width); - /// Returns VP9 information from NVDEC provided offset and size - Vp9PictureInfo GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state); + [[nodiscard]] Vp9PictureInfo GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state); /// Read and convert NVDEC provided entropy probs to Vp9EntropyProbs struct void InsertEntropy(u64 offset, Vp9EntropyProbs& dst); /// Returns frame to be decoded after buffering - Vp9FrameContainer GetCurrentFrame(const NvdecCommon::NvdecRegisters& state); + [[nodiscard]] Vp9FrameContainer GetCurrentFrame(const NvdecCommon::NvdecRegisters& state); /// Use NVDEC providied information to compose the headers for the current frame - std::vector<u8> ComposeCompressedHeader(); - VpxBitStreamWriter ComposeUncompressedHeader(); + [[nodiscard]] std::vector<u8> ComposeCompressedHeader(); + [[nodiscard]] VpxBitStreamWriter ComposeUncompressedHeader(); GPU& gpu; std::vector<u8> frame; @@ -180,7 +177,7 @@ private: std::array<s8, 4> loop_filter_ref_deltas{}; std::array<s8, 2> loop_filter_mode_deltas{}; - bool hidden; + bool hidden = false; s64 current_frame_number = -2; // since we buffer 2 frames s32 grace_period = 6; // frame offsets need to stabilize std::array<FrameContexts, 4> frame_ctxs{}; @@ -193,23 +190,6 @@ private: s32 diff_update_probability = 252; s32 frame_sync_code = 0x498342; - static constexpr std::array<s32, 254> map_lut = { - 20, 21, 22, 23, 24, 25, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 2, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 3, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 4, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 5, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 6, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 7, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 8, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 9, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 10, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 12, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 13, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 14, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 15, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 16, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 17, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 18, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19, - }; }; } // namespace Decoder diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h index 8688fdac0..a50acf6e8 100644 --- a/src/video_core/command_classes/codecs/vp9_types.h +++ b/src/video_core/command_classes/codecs/vp9_types.h @@ -4,13 +4,11 @@ #pragma once -#include <algorithm> -#include <list> +#include <array> +#include <cstring> #include <vector> -#include "common/cityhash.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "video_core/command_classes/nvdec_common.h" namespace Tegra { class GPU; diff --git a/src/video_core/command_classes/host1x.cpp b/src/video_core/command_classes/host1x.cpp index a5234ee47..c4dd4881a 100644 --- a/src/video_core/command_classes/host1x.cpp +++ b/src/video_core/command_classes/host1x.cpp @@ -15,7 +15,7 @@ void Tegra::Host1x::StateWrite(u32 offset, u32 arguments) { std::memcpy(state_offset, &arguments, sizeof(u32)); } -void Tegra::Host1x::ProcessMethod(Host1x::Method method, const std::vector<u32>& arguments) { +void Tegra::Host1x::ProcessMethod(Method method, const std::vector<u32>& arguments) { StateWrite(static_cast<u32>(method), arguments[0]); switch (method) { case Method::WaitSyncpt: diff --git a/src/video_core/command_classes/host1x.h b/src/video_core/command_classes/host1x.h index 501a5ed2e..013eaa0c1 100644 --- a/src/video_core/command_classes/host1x.h +++ b/src/video_core/command_classes/host1x.h @@ -61,7 +61,7 @@ public: ~Host1x(); /// Writes the method into the state, Invoke Execute() if encountered - void ProcessMethod(Host1x::Method method, const std::vector<u32>& arguments); + void ProcessMethod(Method method, const std::vector<u32>& arguments); private: /// For Host1x, execute is waiting on a syncpoint previously written into the state diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/command_classes/nvdec.cpp index ede9466eb..8ca7a7b06 100644 --- a/src/video_core/command_classes/nvdec.cpp +++ b/src/video_core/command_classes/nvdec.cpp @@ -2,13 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <bitset> #include "common/assert.h" -#include "common/bit_util.h" -#include "core/memory.h" #include "video_core/command_classes/nvdec.h" #include "video_core/gpu.h" -#include "video_core/memory_manager.h" namespace Tegra { @@ -16,7 +12,7 @@ Nvdec::Nvdec(GPU& gpu_) : gpu(gpu_), codec(std::make_unique<Codec>(gpu)) {} Nvdec::~Nvdec() = default; -void Nvdec::ProcessMethod(Nvdec::Method method, const std::vector<u32>& arguments) { +void Nvdec::ProcessMethod(Method method, const std::vector<u32>& arguments) { if (method == Method::SetVideoCodec) { codec->StateWrite(static_cast<u32>(method), arguments[0]); } else { diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h index c1a9d843e..af14f9857 100644 --- a/src/video_core/command_classes/nvdec.h +++ b/src/video_core/command_classes/nvdec.h @@ -4,8 +4,8 @@ #pragma once +#include <memory> #include <vector> -#include "common/common_funcs.h" #include "common/common_types.h" #include "video_core/command_classes/codecs/codec.h" @@ -23,7 +23,7 @@ public: ~Nvdec(); /// Writes the method into the state, Invoke Execute() if encountered - void ProcessMethod(Nvdec::Method method, const std::vector<u32>& arguments); + void ProcessMethod(Method method, const std::vector<u32>& arguments); /// Return most recently decoded frame AVFrame* GetFrame(); @@ -34,6 +34,6 @@ private: void Execute(); GPU& gpu; - std::unique_ptr<Tegra::Codec> codec; + std::unique_ptr<Codec> codec; }; } // namespace Tegra diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 66e15a1a8..5b52da277 100644 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp @@ -26,7 +26,7 @@ void Vic::VicStateWrite(u32 offset, u32 arguments) { std::memcpy(state_offset, &arguments, sizeof(u32)); } -void Vic::ProcessMethod(Vic::Method method, const std::vector<u32>& arguments) { +void Vic::ProcessMethod(Method method, const std::vector<u32>& arguments) { LOG_DEBUG(HW_GPU, "Vic method 0x{:X}", static_cast<u32>(method)); VicStateWrite(static_cast<u32>(method), arguments[0]); const u64 arg = static_cast<u64>(arguments[0]) << 8; diff --git a/src/video_core/command_classes/vic.h b/src/video_core/command_classes/vic.h index dd0a2aed8..8c4e284a1 100644 --- a/src/video_core/command_classes/vic.h +++ b/src/video_core/command_classes/vic.h @@ -63,11 +63,11 @@ public: SetOutputSurfaceChromaVOffset = 0x1ca }; - explicit Vic(GPU& gpu, std::shared_ptr<Tegra::Nvdec> nvdec_processor); + explicit Vic(GPU& gpu, std::shared_ptr<Nvdec> nvdec_processor); ~Vic(); /// Write to the device state. - void ProcessMethod(Vic::Method method, const std::vector<u32>& arguments); + void ProcessMethod(Method method, const std::vector<u32>& arguments); private: void Execute(); diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d374b73cf..a3c05d1b0 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -1893,6 +1893,7 @@ public: ICMP_IMM, FCMP_RR, FCMP_RC, + FCMP_IMMR, MUFU, // Multi-Function Operator RRO_C, // Range Reduction Operator RRO_R, @@ -2205,6 +2206,7 @@ private: INST("0111110-0-------", Id::HSET2_IMM, Type::HalfSet, "HSET2_IMM"), INST("010110111010----", Id::FCMP_RR, Type::Arithmetic, "FCMP_RR"), INST("010010111010----", Id::FCMP_RC, Type::Arithmetic, "FCMP_RC"), + INST("0011011-1010----", Id::FCMP_IMMR, Type::Arithmetic, "FCMP_IMMR"), INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index 4db329fa5..afef5948d 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp @@ -137,7 +137,8 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) { break; } case OpCode::Id::FCMP_RR: - case OpCode::Id::FCMP_RC: { + case OpCode::Id::FCMP_RC: + case OpCode::Id::FCMP_IMMR: { UNIMPLEMENTED_IF(instr.fcmp.ftz == 0); Node op_c = GetRegister(instr.gpr39); Node comp = GetPredicateComparisonFloat(instr.fcmp.cond, std::move(op_c), Immediate(0.0f)); |