diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp | 41 | ||||
-rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/y2r_u.cpp | 4 | ||||
-rw-r--r-- | src/core/memory.cpp | 128 | ||||
-rw-r--r-- | src/core/memory.h | 34 | ||||
-rw-r--r-- | src/network/room.cpp | 5 | ||||
-rw-r--r-- | src/network/room.h | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 65 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 5 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 9 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 20 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 50 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 10 |
15 files changed, 220 insertions, 168 deletions
diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp index e3f3194db..7f4ec0c52 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp @@ -183,23 +183,13 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); AlignToColumn(kInputOperandColumnWidth); - if (src_is_inverted) { - print_input(output, src2, swizzle.negate_src2, - SelectorToString(swizzle.src2_selector)); - } else { - print_input(output, src2, swizzle.negate_src2, - SelectorToString(swizzle.src2_selector), true, - instr.mad.AddressRegisterName()); - } + print_input(output, src2, swizzle.negate_src2, + SelectorToString(swizzle.src2_selector), true, + src_is_inverted ? "" : instr.mad.AddressRegisterName()); AlignToColumn(kInputOperandColumnWidth); - if (src_is_inverted) { - print_input(output, src3, swizzle.negate_src3, - SelectorToString(swizzle.src3_selector), true, - instr.mad.AddressRegisterName()); - } else { - print_input(output, src3, swizzle.negate_src3, - SelectorToString(swizzle.src3_selector)); - } + print_input(output, src3, swizzle.negate_src3, + SelectorToString(swizzle.src3_selector), true, + src_is_inverted ? instr.mad.AddressRegisterName() : ""); AlignToColumn(kInputOperandColumnWidth); break; } @@ -222,16 +212,15 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), true, - instr.common.AddressRegisterName()); + src_is_inverted ? "" : instr.common.AddressRegisterName()); AlignToColumn(kInputOperandColumnWidth); } - // TODO: In some cases, the Address Register is used as an index for SRC2 - // instead of SRC1 if (opcode_info.subtype & OpCode::Info::Src2) { SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); print_input(output, src2, swizzle.negate_src2, - swizzle.SelectorToString(true)); + swizzle.SelectorToString(true), true, + src_is_inverted ? instr.common.AddressRegisterName() : ""); AlignToColumn(kInputOperandColumnWidth); } break; @@ -247,7 +236,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con switch (opcode.EffectiveOpCode()) { case OpCode::Id::LOOP: - output << "(unknown instruction format)"; + output << 'i' << instr.flow_control.int_uniform_id << " (end on 0x" + << std::setw(4) << std::right << std::setfill('0') << std::hex + << (4 * instr.flow_control.dest_offset) << ")"; break; default: @@ -255,7 +246,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con output << '('; if (instr.flow_control.op != instr.flow_control.JustY) { - if (instr.flow_control.refx) + if (!instr.flow_control.refx) output << '!'; output << "cc.x"; } @@ -267,13 +258,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } if (instr.flow_control.op != instr.flow_control.JustX) { - if (instr.flow_control.refy) + if (!instr.flow_control.refy) output << '!'; output << "cc.y"; } output << ") "; } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { + if (opcode.EffectiveOpCode() == OpCode::Id::JMPU && + (instr.flow_control.num_instructions & 1) == 1) { + output << '!'; + } output << 'b' << instr.flow_control.bool_uniform_id << ' '; } diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 922e5ab58..a7b66142f 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -149,7 +149,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi if (base_address == 0 && target_address == 0) { // Calculate the address at which to map the memory block. - target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address); + target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value(); } // Map the memory block into the target process diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index aad23e900..4e6b7b6f5 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -86,7 +86,7 @@ void GetSharedFont(Service::Interface* self) { // The shared font has to be relocated to the new address before being passed to the // application. VAddr target_address = - Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); + Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address).value(); if (!shared_font_relocated) { BCFNT::RelocateSharedFont(shared_font_mem, target_address); shared_font_relocated = true; diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index bc964ec60..88684b82d 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -475,12 +475,11 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever // possible/likely - Memory::RasterizerFlushRegion( - Memory::VirtualToPhysicalAddress(command.dma_request.source_address), - command.dma_request.size); - Memory::RasterizerFlushAndInvalidateRegion( - Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), - command.dma_request.size); + Memory::RasterizerFlushVirtualRegion(command.dma_request.source_address, + command.dma_request.size, Memory::FlushMode::Flush); + Memory::RasterizerFlushVirtualRegion(command.dma_request.dest_address, + command.dma_request.size, + Memory::FlushMode::FlushAndInvalidate); // TODO(Subv): These memory accesses should not go through the application's memory mapping. // They should go through the GSP module's memory mapping. diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index e73971d5f..57172ddd6 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -587,8 +587,8 @@ static void StartConversion(Interface* self) { // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( u32 total_output_size = conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); - Memory::RasterizerFlushAndInvalidateRegion( - Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); + Memory::RasterizerFlushVirtualRegion(conversion.dst.address, total_output_size, + Memory::FlushMode::FlushAndInvalidate); HW::Y2R::PerformConversion(conversion); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9024f4922..65649d9d7 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) { LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, (base + size) * PAGE_SIZE); - u32 end = base + size; + RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, + FlushMode::FlushAndInvalidate); + u32 end = base + size; while (base != end) { ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); - // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be - // null here - if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory || - current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS), - PAGE_SIZE); - } - current_page_table->attributes[base] = type; current_page_table->pointers[base] = memory; current_page_table->cached_res_count[base] = 0; @@ -196,7 +190,7 @@ T Read(const VAddr vaddr) { ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); break; case PageType::RasterizerCachedMemory: { - RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); + RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); T value; std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); @@ -205,8 +199,7 @@ T Read(const VAddr vaddr) { case PageType::Special: return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); case PageType::RasterizerCachedSpecial: { - RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); - + RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); } default: @@ -236,8 +229,7 @@ void Write(const VAddr vaddr, const T data) { ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); break; case PageType::RasterizerCachedMemory: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); - + RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate); std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); break; } @@ -245,8 +237,7 @@ void Write(const VAddr vaddr, const T data) { WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); break; case PageType::RasterizerCachedSpecial: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); - + RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate); WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); break; } @@ -275,7 +266,8 @@ bool IsValidVirtualAddress(const VAddr vaddr) { } bool IsValidPhysicalAddress(const PAddr paddr) { - return IsValidVirtualAddress(PhysicalToVirtualAddress(paddr)); + boost::optional<VAddr> vaddr = PhysicalToVirtualAddress(paddr); + return vaddr && IsValidVirtualAddress(*vaddr); } u8* GetPointer(const VAddr vaddr) { @@ -308,7 +300,8 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) { u8* GetPhysicalPointer(PAddr address) { // TODO(Subv): This call should not go through the application's memory mapping. - return GetPointer(PhysicalToVirtualAddress(address)); + boost::optional<VAddr> vaddr = PhysicalToVirtualAddress(address); + return vaddr ? GetPointer(*vaddr) : nullptr; } void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { @@ -319,8 +312,12 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { u32 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; PAddr paddr = start; - for (unsigned i = 0; i < num_pages; ++i) { - VAddr vaddr = PhysicalToVirtualAddress(paddr); + for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { + boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); + if (!maybe_vaddr) + continue; + VAddr vaddr = *maybe_vaddr; + u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; ASSERT_MSG(count_delta <= UINT8_MAX - res_count, "Rasterizer resource cache counter overflow!"); @@ -368,7 +365,6 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { UNREACHABLE(); } } - paddr += PAGE_SIZE; } } @@ -379,11 +375,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) { } void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here if (VideoCore::g_renderer != nullptr) { VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); } } +void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here + if (VideoCore::g_renderer != nullptr) { + VAddr end = start + size; + + auto CheckRegion = [&](VAddr region_start, VAddr region_end) { + if (start >= region_end || end <= region_start) { + // No overlap with region + return; + } + + VAddr overlap_start = std::max(start, region_start); + VAddr overlap_end = std::min(end, region_end); + + PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value(); + u32 overlap_size = overlap_end - overlap_start; + + auto* rasterizer = VideoCore::g_renderer->Rasterizer(); + switch (mode) { + case FlushMode::Flush: + rasterizer->FlushRegion(physical_start, overlap_size); + break; + case FlushMode::FlushAndInvalidate: + rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size); + break; + } + }; + + CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END); + CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END); + CheckRegion(VRAM_VADDR, VRAM_VADDR_END); + } +} + u8 Read8(const VAddr addr) { return Read<u8>(addr); } @@ -430,16 +463,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); break; } case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - - RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); break; } @@ -500,18 +530,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), - copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); break; } case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), - copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); break; } @@ -557,18 +582,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), - copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); break; } case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), - copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); break; } @@ -613,15 +633,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); - + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); break; } case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - - RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); std::vector<u8> buffer(copy_amount); GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); @@ -680,7 +698,7 @@ void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) mmio_handler->Write64(addr, data); } -PAddr VirtualToPhysicalAddress(const VAddr addr) { +boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { if (addr == 0) { return 0; } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { @@ -697,12 +715,20 @@ PAddr VirtualToPhysicalAddress(const VAddr addr) { return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR; } - LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); - // To help with debugging, set bit on address so that it's obviously invalid. - return addr | 0x80000000; + return boost::none; +} + +PAddr VirtualToPhysicalAddress(const VAddr addr) { + auto paddr = TryVirtualToPhysicalAddress(addr); + if (!paddr) { + LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); + // To help with debugging, set bit on address so that it's obviously invalid. + return addr | 0x80000000; + } + return *paddr; } -VAddr PhysicalToVirtualAddress(const PAddr addr) { +boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) { if (addr == 0) { return 0; } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { @@ -717,9 +743,7 @@ VAddr PhysicalToVirtualAddress(const PAddr addr) { return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR; } - LOG_ERROR(HW_Memory, "Unknown physical address @ 0x%08X", addr); - // To help with debugging, set bit on address so that it's obviously invalid. - return addr | 0x80000000; + return boost::none; } } // namespace diff --git a/src/core/memory.h b/src/core/memory.h index 71fb278ad..c8c56babd 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -7,6 +7,7 @@ #include <array> #include <cstddef> #include <string> +#include <boost/optional.hpp> #include "common/common_types.h" namespace Memory { @@ -148,15 +149,23 @@ u8* GetPointer(VAddr virtual_address); std::string ReadCString(VAddr virtual_address, std::size_t max_length); /** -* Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical -* address. This should be used by services to translate addresses for use by the hardware. -*/ + * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical + * address. This should be used by services to translate addresses for use by the hardware. + */ +boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr); + +/** + * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical + * address. This should be used by services to translate addresses for use by the hardware. + * + * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure. + */ PAddr VirtualToPhysicalAddress(VAddr addr); /** -* Undoes a mapping performed by VirtualToPhysicalAddress(). -*/ -VAddr PhysicalToVirtualAddress(PAddr addr); + * Undoes a mapping performed by VirtualToPhysicalAddress(). + */ +boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); /** * Gets a pointer to the memory region beginning at the specified physical address. @@ -181,6 +190,19 @@ void RasterizerFlushRegion(PAddr start, u32 size); */ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); +enum class FlushMode { + /// Write back modified surfaces to RAM + Flush, + /// Write back modified surfaces to RAM, and also remove them from the cache + FlushAndInvalidate, +}; + +/** + * Flushes and invalidates any externally cached rasterizer resources touching the given virtual + * address region. + */ +void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); + /** * Dynarmic has an optimization to memory accesses when the pointer to the page exists that * can be used by setting up the current page table as a callback. This function is used to diff --git a/src/network/room.cpp b/src/network/room.cpp index 8b7915bb7..fbbaf8b93 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -19,7 +19,7 @@ static constexpr u32 MaxConcurrentConnections = 10; class Room::RoomImpl { public: // This MAC address is used to generate a 'Nintendo' like Mac address. - const MacAddress NintendoOUI = {0x00, 0x1F, 0x32, 0x00, 0x00, 0x00}; + const MacAddress NintendoOUI; std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress ENetHost* server = nullptr; ///< Network interface. @@ -36,7 +36,8 @@ public: using MemberList = std::vector<Member>; MemberList members; ///< Information about the members of this room. - RoomImpl() : random_gen(std::random_device()()) {} + RoomImpl() + : random_gen(std::random_device()()), NintendoOUI{0x00, 0x1F, 0x32, 0x00, 0x00, 0x00} {} /// Thread that receives and dispatches network packets std::unique_ptr<std::thread> room_thread; diff --git a/src/network/room.h b/src/network/room.h index 54cccf0ae..65b0d008a 100644 --- a/src/network/room.h +++ b/src/network/room.h @@ -24,7 +24,7 @@ struct RoomInformation { using MacAddress = std::array<u8, 6>; /// A special MAC address that tells the room we're joining to assign us a MAC address /// automatically. -const MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 802.11 broadcast MAC address constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ff3f69ba3..1c6c15a58 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -117,48 +117,53 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { // Setup the noise LUT for proctex proctex_noise_lut.Create(); - state.proctex_noise_lut.texture_1d = proctex_noise_lut.handle; + state.proctex_noise_lut.texture_buffer = proctex_noise_lut.handle; state.Apply(); + proctex_noise_lut_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_noise_lut_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_noise_lut_buffer.handle); // Setup the color map for proctex proctex_color_map.Create(); - state.proctex_color_map.texture_1d = proctex_color_map.handle; + state.proctex_color_map.texture_buffer = proctex_color_map.handle; state.Apply(); + proctex_color_map_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_color_map_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_color_map_buffer.handle); // Setup the alpha map for proctex proctex_alpha_map.Create(); - state.proctex_alpha_map.texture_1d = proctex_alpha_map.handle; + state.proctex_alpha_map.texture_buffer = proctex_alpha_map.handle; state.Apply(); + proctex_alpha_map_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_alpha_map_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_alpha_map_buffer.handle); // Setup the LUT for proctex proctex_lut.Create(); - state.proctex_lut.texture_1d = proctex_lut.handle; + state.proctex_lut.texture_buffer = proctex_lut.handle; state.Apply(); + proctex_lut_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 4 * 256, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::ProcTexLUT.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_lut_buffer.handle); // Setup the difference LUT for proctex proctex_diff_lut.Create(); - state.proctex_diff_lut.texture_1d = proctex_diff_lut.handle; + state.proctex_diff_lut.texture_buffer = proctex_diff_lut.handle; state.Apply(); + proctex_diff_lut_buffer.Create(); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); + glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 4 * 256, nullptr, GL_DYNAMIC_DRAW); glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle); // Sync fixed function OpenGL state SyncCullMode(); @@ -1387,7 +1392,7 @@ void RasterizerOpenGL::SyncProcTexNoise() { // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut, - std::array<GLvec2, 128>& lut_data, GLenum texture) { + std::array<GLvec2, 128>& lut_data, GLuint buffer) { std::array<GLvec2, 128> new_data; std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; @@ -1395,24 +1400,24 @@ static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntr if (new_data != lut_data) { lut_data = new_data; - glActiveTexture(texture); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RG, GL_FLOAT, lut_data.data()); + glBindBuffer(GL_TEXTURE_BUFFER, buffer); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); } } void RasterizerOpenGL::SyncProcTexNoiseLUT() { SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data, - TextureUnits::ProcTexNoiseLUT.Enum()); + proctex_noise_lut_buffer.handle); } void RasterizerOpenGL::SyncProcTexColorMap() { SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data, - TextureUnits::ProcTexColorMap.Enum()); + proctex_color_map_buffer.handle); } void RasterizerOpenGL::SyncProcTexAlphaMap() { SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data, - TextureUnits::ProcTexAlphaMap.Enum()); + proctex_alpha_map_buffer.handle); } void RasterizerOpenGL::SyncProcTexLUT() { @@ -1427,8 +1432,8 @@ void RasterizerOpenGL::SyncProcTexLUT() { if (new_data != proctex_lut_data) { proctex_lut_data = new_data; - glActiveTexture(TextureUnits::ProcTexLUT.Enum()); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, proctex_lut_data.data()); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); } } @@ -1444,8 +1449,8 @@ void RasterizerOpenGL::SyncProcTexDiffLUT() { if (new_data != proctex_diff_lut_data) { proctex_diff_lut_data = new_data; - glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, proctex_diff_lut_data.data()); + glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); + glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index a433c1d4a..78e218efe 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -287,18 +287,23 @@ private: OGLTexture fog_lut; std::array<GLvec2, 128> fog_lut_data{}; + OGLBuffer proctex_noise_lut_buffer; OGLTexture proctex_noise_lut; std::array<GLvec2, 128> proctex_noise_lut_data{}; + OGLBuffer proctex_color_map_buffer; OGLTexture proctex_color_map; std::array<GLvec2, 128> proctex_color_map_data{}; + OGLBuffer proctex_alpha_map_buffer; OGLTexture proctex_alpha_map; std::array<GLvec2, 128> proctex_alpha_map_data{}; + OGLBuffer proctex_lut_buffer; OGLTexture proctex_lut; std::array<GLvec4, 256> proctex_lut_data{}; + OGLBuffer proctex_diff_lut_buffer; OGLTexture proctex_diff_lut; std::array<GLvec4, 256> proctex_diff_lut_data{}; }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 8b717e43d..f37894e7a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -542,10 +542,11 @@ RasterizerCacheOpenGL::GetFramebufferSurfaces( config.GetDepthBufferPhysicalAddress(), fb_area * Pica::FramebufferRegs::BytesPerDepthPixel(config.depth_format)); bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0; - bool using_depth_fb = - config.GetDepthBufferPhysicalAddress() != 0 && - (regs.framebuffer.output_merger.depth_test_enable || - regs.framebuffer.output_merger.depth_write_enable || !framebuffers_overlap); + bool depth_write_enable = regs.framebuffer.output_merger.depth_write_enable && + regs.framebuffer.framebuffer.allow_depth_stencil_write; + bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && + (regs.framebuffer.output_merger.depth_test_enable || depth_write_enable || + !framebuffers_overlap); if (framebuffers_overlap && using_color_fb && using_depth_fb) { LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index c93b108fb..bb192affd 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -886,12 +886,12 @@ void AppendProcTexSampler(std::string& out, const PicaShaderConfig& config) { // coord=1.0 is lut[127]+lut_diff[127]. For other indices, the result is interpolated using // value entries and difference entries. out += R"( -float ProcTexLookupLUT(sampler1D lut, float coord) { +float ProcTexLookupLUT(samplerBuffer lut, float coord) { coord *= 128; float index_i = clamp(floor(coord), 0.0, 127.0); float index_f = coord - index_i; // fract() cannot be used here because 128.0 needs to be // extracted as index_i = 127.0 and index_f = 1.0 - vec2 entry = texelFetch(lut, int(index_i), 0).rg; + vec2 entry = texelFetch(lut, int(index_i)).rg; return clamp(entry.r + entry.g * index_f, 0.0, 1.0); } )"; @@ -979,14 +979,14 @@ float ProcTexNoiseCoef(vec2 x) { out += "int lut_index_i = int(lut_coord) + " + std::to_string(config.state.proctex.lut_offset) + ";\n"; out += "float lut_index_f = fract(lut_coord);\n"; - out += "vec4 final_color = texelFetch(proctex_lut, lut_index_i, 0) + lut_index_f * " - "texelFetch(proctex_diff_lut, lut_index_i, 0);\n"; + out += "vec4 final_color = texelFetch(proctex_lut, lut_index_i) + lut_index_f * " + "texelFetch(proctex_diff_lut, lut_index_i);\n"; break; case ProcTexFilter::Nearest: case ProcTexFilter::NearestMipmapLinear: case ProcTexFilter::NearestMipmapNearest: out += "lut_coord += " + std::to_string(config.state.proctex.lut_offset) + ";\n"; - out += "vec4 final_color = texelFetch(proctex_lut, int(round(lut_coord)), 0);\n"; + out += "vec4 final_color = texelFetch(proctex_lut, int(round(lut_coord)));\n"; break; } @@ -1053,11 +1053,11 @@ layout (std140) uniform shader_data { uniform sampler2D tex[3]; uniform samplerBuffer lighting_lut; uniform samplerBuffer fog_lut; -uniform sampler1D proctex_noise_lut; -uniform sampler1D proctex_color_map; -uniform sampler1D proctex_alpha_map; -uniform sampler1D proctex_lut; -uniform sampler1D proctex_diff_lut; +uniform samplerBuffer proctex_noise_lut; +uniform samplerBuffer proctex_color_map; +uniform samplerBuffer proctex_alpha_map; +uniform samplerBuffer proctex_lut; +uniform samplerBuffer proctex_diff_lut; // Rotate the vector v by the quaternion q vec3 quaternion_rotate(vec4 q, vec3 v) { diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index eface2dea..bc9d34b84 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -56,11 +56,11 @@ OpenGLState::OpenGLState() { fog_lut.texture_buffer = 0; - proctex_lut.texture_1d = 0; - proctex_diff_lut.texture_1d = 0; - proctex_color_map.texture_1d = 0; - proctex_alpha_map.texture_1d = 0; - proctex_noise_lut.texture_1d = 0; + proctex_lut.texture_buffer = 0; + proctex_diff_lut.texture_buffer = 0; + proctex_color_map.texture_buffer = 0; + proctex_alpha_map.texture_buffer = 0; + proctex_noise_lut.texture_buffer = 0; draw.read_framebuffer = 0; draw.draw_framebuffer = 0; @@ -204,33 +204,33 @@ void OpenGLState::Apply() const { } // ProcTex Noise LUT - if (proctex_noise_lut.texture_1d != cur_state.proctex_noise_lut.texture_1d) { + if (proctex_noise_lut.texture_buffer != cur_state.proctex_noise_lut.texture_buffer) { glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); - glBindTexture(GL_TEXTURE_1D, proctex_noise_lut.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, proctex_noise_lut.texture_buffer); } // ProcTex Color Map - if (proctex_color_map.texture_1d != cur_state.proctex_color_map.texture_1d) { + if (proctex_color_map.texture_buffer != cur_state.proctex_color_map.texture_buffer) { glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); - glBindTexture(GL_TEXTURE_1D, proctex_color_map.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, proctex_color_map.texture_buffer); } // ProcTex Alpha Map - if (proctex_alpha_map.texture_1d != cur_state.proctex_alpha_map.texture_1d) { + if (proctex_alpha_map.texture_buffer != cur_state.proctex_alpha_map.texture_buffer) { glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); - glBindTexture(GL_TEXTURE_1D, proctex_alpha_map.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, proctex_alpha_map.texture_buffer); } // ProcTex LUT - if (proctex_lut.texture_1d != cur_state.proctex_lut.texture_1d) { + if (proctex_lut.texture_buffer != cur_state.proctex_lut.texture_buffer) { glActiveTexture(TextureUnits::ProcTexLUT.Enum()); - glBindTexture(GL_TEXTURE_1D, proctex_lut.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, proctex_lut.texture_buffer); } // ProcTex Diff LUT - if (proctex_diff_lut.texture_1d != cur_state.proctex_diff_lut.texture_1d) { + if (proctex_diff_lut.texture_buffer != cur_state.proctex_diff_lut.texture_buffer) { glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); - glBindTexture(GL_TEXTURE_1D, proctex_diff_lut.texture_1d); + glBindTexture(GL_TEXTURE_BUFFER, proctex_diff_lut.texture_buffer); } // Framebuffer @@ -274,16 +274,16 @@ void OpenGLState::ResetTexture(GLuint handle) { cur_state.lighting_lut.texture_buffer = 0; if (cur_state.fog_lut.texture_buffer == handle) cur_state.fog_lut.texture_buffer = 0; - if (cur_state.proctex_noise_lut.texture_1d == handle) - cur_state.proctex_noise_lut.texture_1d = 0; - if (cur_state.proctex_color_map.texture_1d == handle) - cur_state.proctex_color_map.texture_1d = 0; - if (cur_state.proctex_alpha_map.texture_1d == handle) - cur_state.proctex_alpha_map.texture_1d = 0; - if (cur_state.proctex_lut.texture_1d == handle) - cur_state.proctex_lut.texture_1d = 0; - if (cur_state.proctex_diff_lut.texture_1d == handle) - cur_state.proctex_diff_lut.texture_1d = 0; + if (cur_state.proctex_noise_lut.texture_buffer == handle) + cur_state.proctex_noise_lut.texture_buffer = 0; + if (cur_state.proctex_color_map.texture_buffer == handle) + cur_state.proctex_color_map.texture_buffer = 0; + if (cur_state.proctex_alpha_map.texture_buffer == handle) + cur_state.proctex_alpha_map.texture_buffer = 0; + if (cur_state.proctex_lut.texture_buffer == handle) + cur_state.proctex_lut.texture_buffer = 0; + if (cur_state.proctex_diff_lut.texture_buffer == handle) + cur_state.proctex_diff_lut.texture_buffer = 0; } void OpenGLState::ResetSampler(GLuint handle) { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 1efcf0811..745a74479 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -95,23 +95,23 @@ public: } fog_lut; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } proctex_noise_lut; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } proctex_color_map; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } proctex_alpha_map; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } proctex_lut; struct { - GLuint texture_1d; // GL_TEXTURE_BINDING_1D + GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER } proctex_diff_lut; struct { |