diff --git a/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 3d04d0bf..8529e4c0 100644 --- a/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -203,7 +203,45 @@ void nvhost_as_gpu::FreeMappingLocked(u64 offset) NvResult nvhost_as_gpu::FreeSpace(IoctlFreeSpace& params) { - UNIMPLEMENTED(); + LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset, params.pages, params.page_size); + + std::scoped_lock lock(mutex); + + if (!vm.initialised) + { + return NvResult::BadValue; + } + + try + { + auto allocation{allocation_map[params.offset]}; + + if (allocation.page_size != params.page_size || allocation.size != (static_cast(params.pages) * params.page_size)) + { + return NvResult::BadValue; + } + + for (const auto & mapping : allocation.mappings) + { + FreeMappingLocked(mapping->offset); + } + + // Unset sparse flag if required + if (allocation.sparse) + { + system.GetVideo().Unmap(gmmu, params.offset, allocation.size); + } + + auto & allocator{params.page_size == VM::YUZU_PAGESIZE ? *vm.small_page_allocator : *vm.big_page_allocator}; + u32 page_size_bits{params.page_size == VM::YUZU_PAGESIZE ? VM::PAGE_SIZE_BITS : vm.big_page_size_bits}; + + allocator.Free(static_cast(params.offset >> page_size_bits), static_cast(allocation.size >> page_size_bits)); + allocation_map.erase(params.offset); + } + catch (const std::out_of_range &) + { + return NvResult::BadValue; + } return NvResult::Success; } diff --git a/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 078f6580..88ee1294 100644 --- a/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/nxemu-os/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -71,6 +71,9 @@ NvResult nvhost_ctrl_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span case 0x6: return WrapFixedInlOut(this, &nvhost_ctrl_gpu::GetTPCMasks3, input, output, inline_output); + case 0x13: + LOG_DEBUG(Service_NVDRV, "(STUBBED) called."); + return NvResult::NotImplemented; default: break; } diff --git a/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image.cpp index c249b9af..2c865309 100644 --- a/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -196,7 +196,7 @@ Id Texture(EmitContext& ctx, IR::TextureInstInfo info, [[maybe_unused]] const IR } Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& index) { - if (!index.IsImmediate() || index.U32() != 0) { + if (!index.IsEmpty() && (!index.IsImmediate() || index.U32() != 0)) { throw NotImplementedException("Indirect image indexing"); } if (info.type == TextureType::Buffer) { @@ -215,7 +215,7 @@ Id TextureImage(EmitContext& ctx, IR::TextureInstInfo info, const IR::Value& ind } std::pair Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) { - if (!index.IsImmediate() || index.U32() != 0) { + if (!index.IsEmpty() && (!index.IsImmediate() || index.U32() != 0)) { throw NotImplementedException("Indirect image indexing"); } if (info.type == TextureType::Buffer) { diff --git a/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp b/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp index 20451aad..0f852174 100644 --- a/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp +++ b/src/yuzu_shader_recompiler/backend/spirv/emit_spirv_image_atomic.cpp @@ -25,7 +25,7 @@ std::pair AtomicArgs(EmitContext& ctx) { Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value, Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) { - if (!index.IsImmediate() || index.U32() != 0) { + if (!index.IsEmpty() && (!index.IsImmediate() || index.U32() != 0)) { // TODO: handle layers throw NotImplementedException("Image indexing"); }