From a283eda320ea1a4df5e6370528eb1b2ec64e466c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 6 Mar 2022 11:03:48 +0100 Subject: Shader Decompiler: Fix dangerous behavior of invalid iterator insertion. --- src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/shader_recompiler') diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp index 578bc8c1b..ce42475d4 100644 --- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp +++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp @@ -964,9 +964,9 @@ private: demote_endif_node.type = Type::EndIf; demote_endif_node.data.end_if.merge = return_block_it->data.block; - asl.insert(return_block_it, demote_endif_node); - asl.insert(return_block_it, demote_node); - asl.insert(return_block_it, demote_if_node); + const auto next_it_1 = asl.insert(return_block_it, demote_endif_node); + const auto next_it_2 = asl.insert(next_it_1, demote_node); + asl.insert(next_it_2, demote_if_node); } ObjectPool& stmt_pool; -- cgit v1.2.3 From ba34cf0a691bc73ae6b2d8db6019b1f10d22dde5 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 6 Mar 2022 19:54:40 +0100 Subject: Shader Decompiler: Check for shift when deriving composite samplers. --- src/shader_recompiler/ir_opt/texture_pass.cpp | 34 ++++++++++++++++++++-- src/shader_recompiler/shader_info.h | 4 +++ .../renderer_opengl/gl_compute_pipeline.cpp | 5 ++-- .../renderer_opengl/gl_graphics_pipeline.cpp | 5 ++-- .../renderer_vulkan/vk_compute_pipeline.cpp | 4 +-- .../renderer_vulkan/vk_graphics_pipeline.cpp | 5 ++-- 6 files changed, 46 insertions(+), 11 deletions(-) (limited to 'src/shader_recompiler') diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index 597112ba4..4bad811c2 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -19,8 +19,10 @@ namespace { struct ConstBufferAddr { u32 index; u32 offset; + u32 shift_left; u32 secondary_index; u32 secondary_offset; + u32 secondary_shift_left; IR::U32 dynamic_offset; u32 count; bool has_secondary; @@ -182,6 +184,7 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { switch (inst->GetOpcode()) { default: return std::nullopt; + case IR::Opcode::BitwiseXor32: case IR::Opcode::BitwiseOr32: { std::optional lhs{Track(inst->Arg(0))}; std::optional rhs{Track(inst->Arg(1))}; @@ -194,19 +197,33 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { if (lhs->count > 1 || rhs->count > 1) { return std::nullopt; } - if (lhs->index > rhs->index || lhs->offset > rhs->offset) { + if (lhs->shift_left > 0 || lhs->index > rhs->index || lhs->offset > rhs->offset) { std::swap(lhs, rhs); } return ConstBufferAddr{ .index = lhs->index, .offset = lhs->offset, + .shift_left = lhs->shift_left, .secondary_index = rhs->index, .secondary_offset = rhs->offset, + .secondary_shift_left = rhs->shift_left, .dynamic_offset = {}, .count = 1, .has_secondary = true, }; } + case IR::Opcode::ShiftLeftLogical32: { + const IR::Value shift{inst->Arg(1)}; + if (!shift.IsImmediate()) { + return std::nullopt; + } + std::optional lhs{Track(inst->Arg(0))}; + if (lhs) { + lhs->shift_left = shift.U32(); + } + return lhs; + break; + } case IR::Opcode::GetCbufU32x2: case IR::Opcode::GetCbufU32: break; @@ -222,8 +239,10 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { return ConstBufferAddr{ .index = index.U32(), .offset = offset.U32(), + .shift_left = 0, .secondary_index = 0, .secondary_offset = 0, + .secondary_shift_left = 0, .dynamic_offset = {}, .count = 1, .has_secondary = false, @@ -247,8 +266,10 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { return ConstBufferAddr{ .index = index.U32(), .offset = base_offset, + .shift_left = 0, .secondary_index = 0, .secondary_offset = 0, + .secondary_shift_left = 0, .dynamic_offset = dynamic_offset, .count = 8, .has_secondary = false, @@ -267,8 +288,10 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { addr = ConstBufferAddr{ .index = env.TextureBoundBuffer(), .offset = inst.Arg(0).U32(), + .shift_left = 0, .secondary_index = 0, .secondary_offset = 0, + .secondary_shift_left = 0, .dynamic_offset = {}, .count = 1, .has_secondary = false, @@ -284,8 +307,9 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) { const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index}; const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset}; - const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)}; - const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)}; + const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset) << cbuf.shift_left}; + const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset) + << cbuf.secondary_shift_left}; return env.ReadTextureType(lhs_raw | rhs_raw); } @@ -487,8 +511,10 @@ void TexturePass(Environment& env, IR::Program& program) { .has_secondary = cbuf.has_secondary, .cbuf_index = cbuf.index, .cbuf_offset = cbuf.offset, + .shift_left = cbuf.shift_left, .secondary_cbuf_index = cbuf.secondary_index, .secondary_cbuf_offset = cbuf.secondary_offset, + .secondary_shift_left = cbuf.secondary_shift_left, .count = cbuf.count, .size_shift = DESCRIPTOR_SIZE_SHIFT, }); @@ -499,8 +525,10 @@ void TexturePass(Environment& env, IR::Program& program) { .has_secondary = cbuf.has_secondary, .cbuf_index = cbuf.index, .cbuf_offset = cbuf.offset, + .shift_left = cbuf.shift_left, .secondary_cbuf_index = cbuf.secondary_index, .secondary_cbuf_offset = cbuf.secondary_offset, + .secondary_shift_left = cbuf.secondary_shift_left, .count = cbuf.count, .size_shift = DESCRIPTOR_SIZE_SHIFT, }); diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index f5690805c..cc596da4f 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h @@ -61,8 +61,10 @@ struct TextureBufferDescriptor { bool has_secondary; u32 cbuf_index; u32 cbuf_offset; + u32 shift_left; u32 secondary_cbuf_index; u32 secondary_cbuf_offset; + u32 secondary_shift_left; u32 count; u32 size_shift; }; @@ -85,8 +87,10 @@ struct TextureDescriptor { bool has_secondary; u32 cbuf_index; u32 cbuf_offset; + u32 shift_left; u32 secondary_cbuf_index; u32 secondary_cbuf_offset; + u32 secondary_shift_left; u32 count; u32 size_shift; }; diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index 26b51f442..26d066004 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp @@ -100,8 +100,9 @@ void ComputePipeline::Configure() { const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset}; const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() + secondary_offset}; - const u32 lhs_raw{gpu_memory->Read(addr)}; - const u32 rhs_raw{gpu_memory->Read(separate_addr)}; + const u32 lhs_raw{gpu_memory->Read(addr) << desc.shift_left}; + const u32 rhs_raw{gpu_memory->Read(separate_addr) + << desc.secondary_shift_left}; return TexturePair(lhs_raw | rhs_raw, via_header_index); } } diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index c877d7792..41493a7da 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp @@ -312,8 +312,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { const u32 second_offset{desc.secondary_cbuf_offset + index_offset}; const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address + second_offset}; - const u32 lhs_raw{gpu_memory->Read(addr)}; - const u32 rhs_raw{gpu_memory->Read(separate_addr)}; + const u32 lhs_raw{gpu_memory->Read(addr) << desc.shift_left}; + const u32 rhs_raw{gpu_memory->Read(separate_addr) + << desc.secondary_shift_left}; const u32 raw{lhs_raw | rhs_raw}; return TexturePair(raw, via_header_index); } diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 6447210e2..7906e11a8 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp @@ -126,8 +126,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset}; const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() + secondary_offset}; - const u32 lhs_raw{gpu_memory.Read(addr)}; - const u32 rhs_raw{gpu_memory.Read(separate_addr)}; + const u32 lhs_raw{gpu_memory.Read(addr) << desc.shift_left}; + const u32 rhs_raw{gpu_memory.Read(separate_addr) << desc.secondary_shift_left}; return TexturePair(lhs_raw | rhs_raw, via_header_index); } } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 1e993185f..f47786f48 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -314,8 +314,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { const u32 second_offset{desc.secondary_cbuf_offset + index_offset}; const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address + second_offset}; - const u32 lhs_raw{gpu_memory->Read(addr)}; - const u32 rhs_raw{gpu_memory->Read(separate_addr)}; + const u32 lhs_raw{gpu_memory->Read(addr) << desc.shift_left}; + const u32 rhs_raw{gpu_memory->Read(separate_addr) + << desc.secondary_shift_left}; const u32 raw{lhs_raw | rhs_raw}; return TexturePair(raw, via_header_index); } -- cgit v1.2.3 From 3d02143476cbc92450587c4e56eafe1cb76cd9ad Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 26 Mar 2022 13:40:42 +0100 Subject: Shader Decompiler: implement better tracking for Vulkan samplers. --- src/shader_recompiler/ir_opt/texture_pass.cpp | 68 +++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 9 deletions(-) (limited to 'src/shader_recompiler') diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index 4bad811c2..0726d4d21 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -174,20 +174,41 @@ bool IsTextureInstruction(const IR::Inst& inst) { return IndexedInstruction(inst) != IR::Opcode::Void; } -std::optional TryGetConstBuffer(const IR::Inst* inst); +std::optional TryGetConstBuffer(const IR::Inst* inst, Environment& env); -std::optional Track(const IR::Value& value) { - return IR::BreadthFirstSearch(value, TryGetConstBuffer); +std::optional Track(const IR::Value& value, Environment& env) { + return IR::BreadthFirstSearch( + value, [&env](const IR::Inst* inst) { return TryGetConstBuffer(inst, env); }); } -std::optional TryGetConstBuffer(const IR::Inst* inst) { +std::optional TryGetConstant(IR::Value& value, Environment& env) { + const IR::Inst* inst = value.InstRecursive(); + if (inst->GetOpcode() != IR::Opcode::GetCbufU32) { + return std::nullopt; + } + const IR::Value index{inst->Arg(0)}; + const IR::Value offset{inst->Arg(1)}; + if (!index.IsImmediate()) { + return std::nullopt; + } + if (!offset.IsImmediate()) { + return std::nullopt; + } + const auto index_number = index.U32(); + if (index_number != 1) { + return std::nullopt; + } + const auto offset_number = offset.U32(); + return env.ReadCbufValue(index_number, offset_number); +} + +std::optional TryGetConstBuffer(const IR::Inst* inst, Environment& env) { switch (inst->GetOpcode()) { default: return std::nullopt; - case IR::Opcode::BitwiseXor32: case IR::Opcode::BitwiseOr32: { - std::optional lhs{Track(inst->Arg(0))}; - std::optional rhs{Track(inst->Arg(1))}; + std::optional lhs{Track(inst->Arg(0), env)}; + std::optional rhs{Track(inst->Arg(1), env)}; if (!lhs || !rhs) { return std::nullopt; } @@ -217,13 +238,42 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { if (!shift.IsImmediate()) { return std::nullopt; } - std::optional lhs{Track(inst->Arg(0))}; + std::optional lhs{Track(inst->Arg(0), env)}; if (lhs) { lhs->shift_left = shift.U32(); } return lhs; break; } + case IR::Opcode::BitwiseAnd32: { + IR::Value op1{inst->Arg(0)}; + IR::Value op2{inst->Arg(1)}; + if (op1.IsImmediate()) { + std::swap(op1, op2); + } + if (!op2.IsImmediate() && !op1.IsImmediate()) { + do { + auto try_index = TryGetConstant(op1, env); + if (try_index) { + op1 = op2; + op2 = IR::Value{*try_index}; + break; + } + auto try_index_2 = TryGetConstant(op2, env); + if (try_index_2) { + op2 = IR::Value{*try_index_2}; + break; + } + return std::nullopt; + } while (false); + } + std::optional lhs{Track(op1, env)}; + if (lhs) { + lhs->shift_left = std::countr_zero(op2.U32()); + } + return lhs; + break; + } case IR::Opcode::GetCbufU32x2: case IR::Opcode::GetCbufU32: break; @@ -279,7 +329,7 @@ std::optional TryGetConstBuffer(const IR::Inst* inst) { TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) { ConstBufferAddr addr; if (IsBindless(inst)) { - const std::optional track_addr{Track(inst.Arg(0))}; + const std::optional track_addr{Track(inst.Arg(0), env)}; if (!track_addr) { throw NotImplementedException("Failed to track bindless texture constant buffer"); } -- cgit v1.2.3 From afab6c143cb486c7d14f1509cd04049ad08d3a65 Mon Sep 17 00:00:00 2001 From: Liam White Date: Wed, 13 Apr 2022 21:02:55 +0200 Subject: General: Fix compilation for GCC --- src/common/address_space.h | 10 +++--- src/common/algorithm.h | 2 +- src/common/bit_field.h | 13 +++----- src/common/multi_level_page_table.cpp | 4 +-- src/common/multi_level_page_table.inc | 2 +- src/core/hle/service/nvdrv/core/nvmap.cpp | 38 ++++++++++++++-------- src/core/hle/service/nvdrv/core/nvmap.h | 1 + .../hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 3 ++ src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 8 ++--- .../hle/service/nvdrv/devices/nvhost_nvdec.cpp | 4 +-- src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 4 +-- src/core/hle/service/nvdrv/devices/nvmap.cpp | 2 +- src/core/hle/service/nvdrv/nvdrv.h | 1 + src/core/hle/service/vi/vi.cpp | 1 + src/shader_recompiler/ir_opt/texture_pass.cpp | 2 +- src/video_core/buffer_cache/buffer_cache.h | 3 +- 16 files changed, 56 insertions(+), 42 deletions(-) (limited to 'src/shader_recompiler') diff --git a/src/common/address_space.h b/src/common/address_space.h index fd2f32b7d..8e13935af 100644 --- a/src/common/address_space.h +++ b/src/common/address_space.h @@ -22,7 +22,8 @@ struct EmptyStruct {}; */ template -requires AddressSpaceValid class FlatAddressSpaceMap { +requires AddressSpaceValid +class FlatAddressSpaceMap { private: std::function unmapCallback{}; //!< Callback called when the mappings in an region have changed @@ -40,8 +41,8 @@ protected: Block() = default; - Block(VaType virt, PaType phys, ExtraBlockInfo extraInfo) - : virt(virt), phys(phys), extraInfo(extraInfo) {} + Block(VaType virt_, PaType phys_, ExtraBlockInfo extraInfo_) + : virt(virt_), phys(phys_), extraInfo(extraInfo_) {} constexpr bool Valid() { return virt != UnmappedVa; @@ -102,7 +103,8 @@ public: * initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block */ template -requires AddressSpaceValid class FlatAllocator +requires AddressSpaceValid +class FlatAllocator : public FlatAddressSpaceMap { private: using Base = FlatAddressSpaceMap; diff --git a/src/common/algorithm.h b/src/common/algorithm.h index 055dca142..c27c9241d 100644 --- a/src/common/algorithm.h +++ b/src/common/algorithm.h @@ -27,7 +27,7 @@ template > template T FoldRight(T initial_value, Func&& func, Args&&... args) { T value{initial_value}; - const auto high_func = [&value, &func](T x) { value = func(value, x); }; + const auto high_func = [&value, &func](U x) { value = func(value, x); }; (std::invoke(high_func, std::forward(args)), ...); return value; } diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 368b7b98c..7e1df62b1 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -127,14 +127,11 @@ public: } } - BitField(T val) { - Assign(val); - } - - BitField& operator=(T val) { - Assign(val); - return *this; - } + // This constructor and assignment operator might be considered ambiguous: + // Would they initialize the storage or just the bitfield? + // Hence, delete them. Use the Assign method to set bitfield values! + BitField(T val) = delete; + BitField& operator=(T val) = delete; constexpr BitField() noexcept = default; diff --git a/src/common/multi_level_page_table.cpp b/src/common/multi_level_page_table.cpp index aed04d0b5..3a7a75aa7 100644 --- a/src/common/multi_level_page_table.cpp +++ b/src/common/multi_level_page_table.cpp @@ -1,8 +1,6 @@ #include "common/multi_level_page_table.inc" namespace Common { -template class Common::MultiLevelPageTable; -template class Common::MultiLevelPageTable; -template class Common::MultiLevelPageTable; +template class Common::MultiLevelPageTable; template class Common::MultiLevelPageTable; } // namespace Common diff --git a/src/common/multi_level_page_table.inc b/src/common/multi_level_page_table.inc index 9a68cad93..4def6dba8 100644 --- a/src/common/multi_level_page_table.inc +++ b/src/common/multi_level_page_table.inc @@ -30,7 +30,7 @@ MultiLevelPageTable::MultiLevelPageTable(std::size_t address_space_bit #ifdef _WIN32 void* base{VirtualAlloc(nullptr, alloc_size, MEM_RESERVE, PAGE_READWRITE)}; #else - void* base{mmap(nullptr, alloc_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)}; + void* base{mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)}; if (base == MAP_FAILED) { base = nullptr; diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index 86d825af9..b02dbb9c9 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp @@ -13,7 +13,8 @@ using Core::Memory::YUZU_PAGESIZE; namespace Service::Nvidia::NvCore { -NvMap::Handle::Handle(u64 size, Id id) : size(size), aligned_size(size), orig_size(size), id(id) { +NvMap::Handle::Handle(u64 size_, Id id_) + : size(size_), aligned_size(size), orig_size(size), id(id_) { flags.raw = 0; } @@ -21,19 +22,21 @@ NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) std::scoped_lock lock(mutex); // Handles cannot be allocated twice - if (allocated) + if (allocated) { return NvResult::AccessDenied; + } flags = pFlags; kind = pKind; align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign; // This flag is only applicable for handles with an address passed - if (pAddress) - flags.keep_uncached_after_free = 0; - else + if (pAddress) { + flags.keep_uncached_after_free.Assign(0); + } else { LOG_CRITICAL(Service_NVDRV, "Mapping nvmap handles without a CPU side address is unimplemented!"); + } size = Common::AlignUp(size, YUZU_PAGESIZE); aligned_size = Common::AlignUp(size, align); @@ -48,17 +51,19 @@ NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) NvResult NvMap::Handle::Duplicate(bool internal_session) { // Unallocated handles cannot be duplicated as duplication requires memory accounting (in HOS) - if (!allocated) [[unlikely]] + if (!allocated) [[unlikely]] { return NvResult::BadValue; + } std::scoped_lock lock(mutex); // If we internally use FromId the duplication tracking of handles won't work accurately due to // us not implementing per-process handle refs. - if (internal_session) + if (internal_session) { internal_dupes++; - else + } else { dupes++; + } return NvResult::Success; } @@ -92,8 +97,9 @@ bool NvMap::TryRemoveHandle(const Handle& handle_description) { std::scoped_lock lock(handles_lock); auto it{handles.find(handle_description.id)}; - if (it != handles.end()) + if (it != handles.end()) { handles.erase(it); + } return true; } else { @@ -102,8 +108,9 @@ bool NvMap::TryRemoveHandle(const Handle& handle_description) { } NvResult NvMap::CreateHandle(u64 size, std::shared_ptr& result_out) { - if (!size) [[unlikely]] + if (!size) [[unlikely]] { return NvResult::BadValue; + } u32 id{next_handle_id.fetch_add(HandleIdIncrement, std::memory_order_relaxed)}; auto handle_description{std::make_shared(size, id)}; @@ -133,8 +140,9 @@ VAddr NvMap::GetHandleAddress(Handle::Id handle) { u32 NvMap::PinHandle(NvMap::Handle::Id handle) { auto handle_description{GetHandle(handle)}; - if (!handle_description) [[unlikely]] + if (!handle_description) [[unlikely]] { return 0; + } std::scoped_lock lock(handle_description->mutex); if (!handle_description->pins) { @@ -183,8 +191,9 @@ u32 NvMap::PinHandle(NvMap::Handle::Id handle) { void NvMap::UnpinHandle(Handle::Id handle) { auto handle_description{GetHandle(handle)}; - if (!handle_description) + if (!handle_description) { return; + } std::scoped_lock lock(handle_description->mutex); if (--handle_description->pins < 0) { @@ -226,12 +235,13 @@ std::optional NvMap::FreeHandle(Handle::Id handle, bool interna // Try to remove the shared ptr to the handle from the map, if nothing else is using the // handle then it will now be freed when `handle_description` goes out of scope - if (TryRemoveHandle(*handle_description)) + if (TryRemoveHandle(*handle_description)) { LOG_DEBUG(Service_NVDRV, "Removed nvmap handle: {}", handle); - else + } else { LOG_DEBUG(Service_NVDRV, "Tried to free nvmap handle: {} but didn't as it still has duplicates", handle); + } freeInfo = { .address = handle_description->address, diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index 4f37dcf43..1082bb58d 100644 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h @@ -5,6 +5,7 @@ #pragma once +#include #include #include #include diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index d95a88393..d1beefba6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -188,6 +188,7 @@ NvResult nvhost_as_gpu::AllocateSpace(const std::vector& input, std::vector< allocation_map[params.offset] = { .size = size, + .mappings{}, .page_size = params.page_size, .sparse = (params.flags & MappingFlags::Sparse) != MappingFlags::None, .big_pages = params.page_size != VM::YUZU_PAGESIZE, @@ -474,11 +475,13 @@ void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) { VaRegion{ .offset = vm.small_page_allocator->vaStart << VM::PAGE_SIZE_BITS, .page_size = VM::YUZU_PAGESIZE, + ._pad0_{}, .pages = vm.small_page_allocator->vaLimit - vm.small_page_allocator->vaStart, }, VaRegion{ .offset = vm.big_page_allocator->vaStart << vm.big_page_size_bits, .page_size = vm.big_page_size, + ._pad0_{}, .pages = vm.big_page_allocator->vaLimit - vm.big_page_allocator->vaStart, }, }; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index a84e4d425..7fffb8e48 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -204,12 +204,12 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector event.wait_handle = host1x_syncpoint_manager.RegisterHostAction(fence_id, target_value, [this, slot]() { - auto& event = events[slot]; - if (event.status.exchange(EventState::Signalling, std::memory_order_acq_rel) == + auto& event_ = events[slot]; + if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) == EventState::Waiting) { - event.kevent->GetWritableEvent().Signal(); + event_.kevent->GetWritableEvent().Signal(); } - event.status.store(EventState::Signalled, std::memory_order_release); + event_.status.store(EventState::Signalled, std::memory_order_release); }); return NvResult::Timeout; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 5e3820085..fed537039 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -12,8 +12,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_nvdec::next_id{}; -nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core) - : nvhost_nvdec_common{system_, core, NvCore::ChannelType::NvDec} {} +nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core_) + : nvhost_nvdec_common{system_, core_, NvCore::ChannelType::NvDec} {} nvhost_nvdec::~nvhost_nvdec() = default; NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector& input, diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 490e399f4..2e4ff988c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -11,8 +11,8 @@ namespace Service::Nvidia::Devices { u32 nvhost_vic::next_id{}; -nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core) - : nvhost_nvdec_common{system_, core, NvCore::ChannelType::VIC} {} +nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core_) + : nvhost_nvdec_common{system_, core_, NvCore::ChannelType::VIC} {} nvhost_vic::~nvhost_vic() = default; diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 992c117f1..f84fc8c37 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -269,7 +269,7 @@ NvResult nvmap::IocFree(const std::vector& input, std::vector& output) { params.address = freeInfo->address; params.size = static_cast(freeInfo->size); params.flags.raw = 0; - params.flags.map_uncached = freeInfo->was_uncached; + params.flags.map_uncached.Assign(freeInfo->was_uncached); } else { // This is possible when there's internel dups or other duplicates. } diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 31c45236e..b26254753 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include #include diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index f083811ec..9c917cacf 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -58,6 +58,7 @@ static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size"); class NativeWindow final { public: constexpr explicit NativeWindow(u32 id_) : id{id_} {} + constexpr explicit NativeWindow(const NativeWindow& other) = default; private: const u32 magic = 2; diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp index 0726d4d21..e8be58357 100644 --- a/src/shader_recompiler/ir_opt/texture_pass.cpp +++ b/src/shader_recompiler/ir_opt/texture_pass.cpp @@ -269,7 +269,7 @@ std::optional TryGetConstBuffer(const IR::Inst* inst, Environme } std::optional lhs{Track(op1, env)}; if (lhs) { - lhs->shift_left = std::countr_zero(op2.U32()); + lhs->shift_left = static_cast(std::countr_zero(op2.U32())); } return lhs; break; diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 2e616cee4..8e26b3f95 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1323,7 +1323,8 @@ void BufferCache

::UpdateVertexBuffer(u32 index) { return; } if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) { - address_size = gpu_memory->MaxContinousRange(gpu_addr_begin, address_size); + address_size = + static_cast(gpu_memory->MaxContinousRange(gpu_addr_begin, address_size)); } const u32 size = address_size; // TODO: Analyze stride and number of vertices vertex_buffers[index] = Binding{ -- cgit v1.2.3