diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 44e062f50d..010072a5b3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector& input, std::vector& u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector& input, std::vector& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlActiveSlotMask params{}; - std::memcpy(¶ms, input.data(), input.size()); + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } params.slot = 0x07; params.mask = 0x01; std::memcpy(output.data(), ¶ms, output.size()); @@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector& input, std::vector u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector& input, std::vector& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlZcullGetCtxSize params{}; - std::memcpy(¶ms, input.data(), input.size()); + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } params.size = 0x1; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector& input, std::vector& input, std::vector& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlNvgpuGpuZcullGetInfoArgs params{}; - std::memcpy(¶ms, input.data(), input.size()); + + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } + params.width_align_pixels = 0x20; params.height_align_pixels = 0x20; params.pixel_squares_by_aliquots = 0x400; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 126782573a..5a1123ad26 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -132,9 +132,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector& input, std::vector& outp LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, params.num_entries, params.flags); - auto entries = std::vector(); - entries.resize(params.num_entries); - std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], + ASSERT_MSG(input.size() == + sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry), + "Incorrect input size"); + + std::vector entries(params.num_entries); + std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], params.num_entries * sizeof(IoctlGpfifoEntry)); for (auto entry : entries) { Tegra::GPUVAddr va_addr = entry.Address(); diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 44ece01c14..377bd66ab0 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp @@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector& code, bool is_delay_slot) { if (taken) { // Ignore the delay slot if the branch has the annul bit. if (opcode.branch_annul) { - pc = base_address + (opcode.immediate << 2); + pc = base_address + opcode.GetBranchTarget(); return true; } - delayed_pc = base_address + (opcode.immediate << 2); + delayed_pc = base_address + opcode.GetBranchTarget(); // Execute one more instruction due to the delay slot. return Step(code, true); } diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h index a71e359d89..7d836b8160 100644 --- a/src/video_core/macro_interpreter.h +++ b/src/video_core/macro_interpreter.h @@ -91,6 +91,10 @@ private: u32 GetBitfieldMask() const { return (1 << bf_size) - 1; } + + s32 GetBranchTarget() const { + return static_cast(immediate * sizeof(u32)); + } }; union MethodAddress {