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 | |||
| 183 | print_input(output, src1, swizzle.negate_src1, | 183 | print_input(output, src1, swizzle.negate_src1, |
| 184 | SelectorToString(swizzle.src1_selector)); | 184 | SelectorToString(swizzle.src1_selector)); |
| 185 | AlignToColumn(kInputOperandColumnWidth); | 185 | AlignToColumn(kInputOperandColumnWidth); |
| 186 | if (src_is_inverted) { | 186 | print_input(output, src2, swizzle.negate_src2, |
| 187 | print_input(output, src2, swizzle.negate_src2, | 187 | SelectorToString(swizzle.src2_selector), true, |
| 188 | SelectorToString(swizzle.src2_selector)); | 188 | src_is_inverted ? "" : instr.mad.AddressRegisterName()); |
| 189 | } else { | ||
| 190 | print_input(output, src2, swizzle.negate_src2, | ||
| 191 | SelectorToString(swizzle.src2_selector), true, | ||
| 192 | instr.mad.AddressRegisterName()); | ||
| 193 | } | ||
| 194 | AlignToColumn(kInputOperandColumnWidth); | 189 | AlignToColumn(kInputOperandColumnWidth); |
| 195 | if (src_is_inverted) { | 190 | print_input(output, src3, swizzle.negate_src3, |
| 196 | print_input(output, src3, swizzle.negate_src3, | 191 | SelectorToString(swizzle.src3_selector), true, |
| 197 | SelectorToString(swizzle.src3_selector), true, | 192 | src_is_inverted ? instr.mad.AddressRegisterName() : ""); |
| 198 | instr.mad.AddressRegisterName()); | ||
| 199 | } else { | ||
| 200 | print_input(output, src3, swizzle.negate_src3, | ||
| 201 | SelectorToString(swizzle.src3_selector)); | ||
| 202 | } | ||
| 203 | AlignToColumn(kInputOperandColumnWidth); | 193 | AlignToColumn(kInputOperandColumnWidth); |
| 204 | break; | 194 | break; |
| 205 | } | 195 | } |
| @@ -222,16 +212,15 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 222 | SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); | 212 | SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); |
| 223 | print_input(output, src1, swizzle.negate_src1, | 213 | print_input(output, src1, swizzle.negate_src1, |
| 224 | swizzle.SelectorToString(false), true, | 214 | swizzle.SelectorToString(false), true, |
| 225 | instr.common.AddressRegisterName()); | 215 | src_is_inverted ? "" : instr.common.AddressRegisterName()); |
| 226 | AlignToColumn(kInputOperandColumnWidth); | 216 | AlignToColumn(kInputOperandColumnWidth); |
| 227 | } | 217 | } |
| 228 | 218 | ||
| 229 | // TODO: In some cases, the Address Register is used as an index for SRC2 | ||
| 230 | // instead of SRC1 | ||
| 231 | if (opcode_info.subtype & OpCode::Info::Src2) { | 219 | if (opcode_info.subtype & OpCode::Info::Src2) { |
| 232 | SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); | 220 | SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); |
| 233 | print_input(output, src2, swizzle.negate_src2, | 221 | print_input(output, src2, swizzle.negate_src2, |
| 234 | swizzle.SelectorToString(true)); | 222 | swizzle.SelectorToString(true), true, |
| 223 | src_is_inverted ? instr.common.AddressRegisterName() : ""); | ||
| 235 | AlignToColumn(kInputOperandColumnWidth); | 224 | AlignToColumn(kInputOperandColumnWidth); |
| 236 | } | 225 | } |
| 237 | break; | 226 | break; |
| @@ -247,7 +236,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 247 | 236 | ||
| 248 | switch (opcode.EffectiveOpCode()) { | 237 | switch (opcode.EffectiveOpCode()) { |
| 249 | case OpCode::Id::LOOP: | 238 | case OpCode::Id::LOOP: |
| 250 | output << "(unknown instruction format)"; | 239 | output << 'i' << instr.flow_control.int_uniform_id << " (end on 0x" |
| 240 | << std::setw(4) << std::right << std::setfill('0') << std::hex | ||
| 241 | << (4 * instr.flow_control.dest_offset) << ")"; | ||
| 251 | break; | 242 | break; |
| 252 | 243 | ||
| 253 | default: | 244 | default: |
| @@ -255,7 +246,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 255 | output << '('; | 246 | output << '('; |
| 256 | 247 | ||
| 257 | if (instr.flow_control.op != instr.flow_control.JustY) { | 248 | if (instr.flow_control.op != instr.flow_control.JustY) { |
| 258 | if (instr.flow_control.refx) | 249 | if (!instr.flow_control.refx) |
| 259 | output << '!'; | 250 | output << '!'; |
| 260 | output << "cc.x"; | 251 | output << "cc.x"; |
| 261 | } | 252 | } |
| @@ -267,13 +258,17 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con | |||
| 267 | } | 258 | } |
| 268 | 259 | ||
| 269 | if (instr.flow_control.op != instr.flow_control.JustX) { | 260 | if (instr.flow_control.op != instr.flow_control.JustX) { |
| 270 | if (instr.flow_control.refy) | 261 | if (!instr.flow_control.refy) |
| 271 | output << '!'; | 262 | output << '!'; |
| 272 | output << "cc.y"; | 263 | output << "cc.y"; |
| 273 | } | 264 | } |
| 274 | 265 | ||
| 275 | output << ") "; | 266 | output << ") "; |
| 276 | } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { | 267 | } else if (opcode_info.subtype & OpCode::Info::HasUniformIndex) { |
| 268 | if (opcode.EffectiveOpCode() == OpCode::Id::JMPU && | ||
| 269 | (instr.flow_control.num_instructions & 1) == 1) { | ||
| 270 | output << '!'; | ||
| 271 | } | ||
| 277 | output << 'b' << instr.flow_control.bool_uniform_id << ' '; | 272 | output << 'b' << instr.flow_control.bool_uniform_id << ' '; |
| 278 | } | 273 | } |
| 279 | 274 | ||
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 | |||
| 149 | 149 | ||
| 150 | if (base_address == 0 && target_address == 0) { | 150 | if (base_address == 0 && target_address == 0) { |
| 151 | // Calculate the address at which to map the memory block. | 151 | // Calculate the address at which to map the memory block. |
| 152 | target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address); | 152 | target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value(); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | // Map the memory block into the target process | 155 | // 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) { | |||
| 86 | // The shared font has to be relocated to the new address before being passed to the | 86 | // The shared font has to be relocated to the new address before being passed to the |
| 87 | // application. | 87 | // application. |
| 88 | VAddr target_address = | 88 | VAddr target_address = |
| 89 | Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); | 89 | Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address).value(); |
| 90 | if (!shared_font_relocated) { | 90 | if (!shared_font_relocated) { |
| 91 | BCFNT::RelocateSharedFont(shared_font_mem, target_address); | 91 | BCFNT::RelocateSharedFont(shared_font_mem, target_address); |
| 92 | shared_font_relocated = true; | 92 | 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) { | |||
| 475 | 475 | ||
| 476 | // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever | 476 | // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever |
| 477 | // possible/likely | 477 | // possible/likely |
| 478 | Memory::RasterizerFlushRegion( | 478 | Memory::RasterizerFlushVirtualRegion(command.dma_request.source_address, |
| 479 | Memory::VirtualToPhysicalAddress(command.dma_request.source_address), | 479 | command.dma_request.size, Memory::FlushMode::Flush); |
| 480 | command.dma_request.size); | 480 | Memory::RasterizerFlushVirtualRegion(command.dma_request.dest_address, |
| 481 | Memory::RasterizerFlushAndInvalidateRegion( | 481 | command.dma_request.size, |
| 482 | Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), | 482 | Memory::FlushMode::FlushAndInvalidate); |
| 483 | command.dma_request.size); | ||
| 484 | 483 | ||
| 485 | // TODO(Subv): These memory accesses should not go through the application's memory mapping. | 484 | // TODO(Subv): These memory accesses should not go through the application's memory mapping. |
| 486 | // They should go through the GSP module's memory mapping. | 485 | // 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) { | |||
| 587 | // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( | 587 | // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( |
| 588 | u32 total_output_size = | 588 | u32 total_output_size = |
| 589 | conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); | 589 | conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); |
| 590 | Memory::RasterizerFlushAndInvalidateRegion( | 590 | Memory::RasterizerFlushVirtualRegion(conversion.dst.address, total_output_size, |
| 591 | Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); | 591 | Memory::FlushMode::FlushAndInvalidate); |
| 592 | 592 | ||
| 593 | HW::Y2R::PerformConversion(conversion); | 593 | HW::Y2R::PerformConversion(conversion); |
| 594 | 594 | ||
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) { | |||
| 83 | LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, | 83 | LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, |
| 84 | (base + size) * PAGE_SIZE); | 84 | (base + size) * PAGE_SIZE); |
| 85 | 85 | ||
| 86 | u32 end = base + size; | 86 | RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, |
| 87 | FlushMode::FlushAndInvalidate); | ||
| 87 | 88 | ||
| 89 | u32 end = base + size; | ||
| 88 | while (base != end) { | 90 | while (base != end) { |
| 89 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); | 91 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); |
| 90 | 92 | ||
| 91 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | ||
| 92 | // null here | ||
| 93 | if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory || | ||
| 94 | current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) { | ||
| 95 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS), | ||
| 96 | PAGE_SIZE); | ||
| 97 | } | ||
| 98 | |||
| 99 | current_page_table->attributes[base] = type; | 93 | current_page_table->attributes[base] = type; |
| 100 | current_page_table->pointers[base] = memory; | 94 | current_page_table->pointers[base] = memory; |
| 101 | current_page_table->cached_res_count[base] = 0; | 95 | current_page_table->cached_res_count[base] = 0; |
| @@ -196,7 +190,7 @@ T Read(const VAddr vaddr) { | |||
| 196 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); | 190 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); |
| 197 | break; | 191 | break; |
| 198 | case PageType::RasterizerCachedMemory: { | 192 | case PageType::RasterizerCachedMemory: { |
| 199 | RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); | 193 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); |
| 200 | 194 | ||
| 201 | T value; | 195 | T value; |
| 202 | std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); | 196 | std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); |
| @@ -205,8 +199,7 @@ T Read(const VAddr vaddr) { | |||
| 205 | case PageType::Special: | 199 | case PageType::Special: |
| 206 | return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); | 200 | return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); |
| 207 | case PageType::RasterizerCachedSpecial: { | 201 | case PageType::RasterizerCachedSpecial: { |
| 208 | RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); | 202 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); |
| 209 | |||
| 210 | return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); | 203 | return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); |
| 211 | } | 204 | } |
| 212 | default: | 205 | default: |
| @@ -236,8 +229,7 @@ void Write(const VAddr vaddr, const T data) { | |||
| 236 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); | 229 | ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); |
| 237 | break; | 230 | break; |
| 238 | case PageType::RasterizerCachedMemory: { | 231 | case PageType::RasterizerCachedMemory: { |
| 239 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); | 232 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate); |
| 240 | |||
| 241 | std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); | 233 | std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); |
| 242 | break; | 234 | break; |
| 243 | } | 235 | } |
| @@ -245,8 +237,7 @@ void Write(const VAddr vaddr, const T data) { | |||
| 245 | WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); | 237 | WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); |
| 246 | break; | 238 | break; |
| 247 | case PageType::RasterizerCachedSpecial: { | 239 | case PageType::RasterizerCachedSpecial: { |
| 248 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); | 240 | RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate); |
| 249 | |||
| 250 | WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); | 241 | WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); |
| 251 | break; | 242 | break; |
| 252 | } | 243 | } |
| @@ -275,7 +266,8 @@ bool IsValidVirtualAddress(const VAddr vaddr) { | |||
| 275 | } | 266 | } |
| 276 | 267 | ||
| 277 | bool IsValidPhysicalAddress(const PAddr paddr) { | 268 | bool IsValidPhysicalAddress(const PAddr paddr) { |
| 278 | return IsValidVirtualAddress(PhysicalToVirtualAddress(paddr)); | 269 | boost::optional<VAddr> vaddr = PhysicalToVirtualAddress(paddr); |
| 270 | return vaddr && IsValidVirtualAddress(*vaddr); | ||
| 279 | } | 271 | } |
| 280 | 272 | ||
| 281 | u8* GetPointer(const VAddr vaddr) { | 273 | u8* GetPointer(const VAddr vaddr) { |
| @@ -308,7 +300,8 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) { | |||
| 308 | 300 | ||
| 309 | u8* GetPhysicalPointer(PAddr address) { | 301 | u8* GetPhysicalPointer(PAddr address) { |
| 310 | // TODO(Subv): This call should not go through the application's memory mapping. | 302 | // TODO(Subv): This call should not go through the application's memory mapping. |
| 311 | return GetPointer(PhysicalToVirtualAddress(address)); | 303 | boost::optional<VAddr> vaddr = PhysicalToVirtualAddress(address); |
| 304 | return vaddr ? GetPointer(*vaddr) : nullptr; | ||
| 312 | } | 305 | } |
| 313 | 306 | ||
| 314 | void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | 307 | void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { |
| @@ -319,8 +312,12 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | |||
| 319 | u32 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; | 312 | u32 num_pages = ((start + size - 1) >> PAGE_BITS) - (start >> PAGE_BITS) + 1; |
| 320 | PAddr paddr = start; | 313 | PAddr paddr = start; |
| 321 | 314 | ||
| 322 | for (unsigned i = 0; i < num_pages; ++i) { | 315 | for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) { |
| 323 | VAddr vaddr = PhysicalToVirtualAddress(paddr); | 316 | boost::optional<VAddr> maybe_vaddr = PhysicalToVirtualAddress(paddr); |
| 317 | if (!maybe_vaddr) | ||
| 318 | continue; | ||
| 319 | VAddr vaddr = *maybe_vaddr; | ||
| 320 | |||
| 324 | u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; | 321 | u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; |
| 325 | ASSERT_MSG(count_delta <= UINT8_MAX - res_count, | 322 | ASSERT_MSG(count_delta <= UINT8_MAX - res_count, |
| 326 | "Rasterizer resource cache counter overflow!"); | 323 | "Rasterizer resource cache counter overflow!"); |
| @@ -368,7 +365,6 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { | |||
| 368 | UNREACHABLE(); | 365 | UNREACHABLE(); |
| 369 | } | 366 | } |
| 370 | } | 367 | } |
| 371 | paddr += PAGE_SIZE; | ||
| 372 | } | 368 | } |
| 373 | } | 369 | } |
| 374 | 370 | ||
| @@ -379,11 +375,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) { | |||
| 379 | } | 375 | } |
| 380 | 376 | ||
| 381 | void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { | 377 | void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { |
| 378 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | ||
| 379 | // null here | ||
| 382 | if (VideoCore::g_renderer != nullptr) { | 380 | if (VideoCore::g_renderer != nullptr) { |
| 383 | VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); | 381 | VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); |
| 384 | } | 382 | } |
| 385 | } | 383 | } |
| 386 | 384 | ||
| 385 | void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { | ||
| 386 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | ||
| 387 | // null here | ||
| 388 | if (VideoCore::g_renderer != nullptr) { | ||
| 389 | VAddr end = start + size; | ||
| 390 | |||
| 391 | auto CheckRegion = [&](VAddr region_start, VAddr region_end) { | ||
| 392 | if (start >= region_end || end <= region_start) { | ||
| 393 | // No overlap with region | ||
| 394 | return; | ||
| 395 | } | ||
| 396 | |||
| 397 | VAddr overlap_start = std::max(start, region_start); | ||
| 398 | VAddr overlap_end = std::min(end, region_end); | ||
| 399 | |||
| 400 | PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value(); | ||
| 401 | u32 overlap_size = overlap_end - overlap_start; | ||
| 402 | |||
| 403 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); | ||
| 404 | switch (mode) { | ||
| 405 | case FlushMode::Flush: | ||
| 406 | rasterizer->FlushRegion(physical_start, overlap_size); | ||
| 407 | break; | ||
| 408 | case FlushMode::FlushAndInvalidate: | ||
| 409 | rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size); | ||
| 410 | break; | ||
| 411 | } | ||
| 412 | }; | ||
| 413 | |||
| 414 | CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END); | ||
| 415 | CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END); | ||
| 416 | CheckRegion(VRAM_VADDR, VRAM_VADDR_END); | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 387 | u8 Read8(const VAddr addr) { | 420 | u8 Read8(const VAddr addr) { |
| 388 | return Read<u8>(addr); | 421 | return Read<u8>(addr); |
| 389 | } | 422 | } |
| @@ -430,16 +463,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { | |||
| 430 | break; | 463 | break; |
| 431 | } | 464 | } |
| 432 | case PageType::RasterizerCachedMemory: { | 465 | case PageType::RasterizerCachedMemory: { |
| 433 | RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); | 466 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); |
| 434 | |||
| 435 | std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); | 467 | std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); |
| 436 | break; | 468 | break; |
| 437 | } | 469 | } |
| 438 | case PageType::RasterizerCachedSpecial: { | 470 | case PageType::RasterizerCachedSpecial: { |
| 439 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); | 471 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); |
| 440 | 472 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); | |
| 441 | RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); | ||
| 442 | |||
| 443 | GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); | 473 | GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); |
| 444 | break; | 474 | break; |
| 445 | } | 475 | } |
| @@ -500,18 +530,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size | |||
| 500 | break; | 530 | break; |
| 501 | } | 531 | } |
| 502 | case PageType::RasterizerCachedMemory: { | 532 | case PageType::RasterizerCachedMemory: { |
| 503 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), | 533 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); |
| 504 | copy_amount); | ||
| 505 | |||
| 506 | std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); | 534 | std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); |
| 507 | break; | 535 | break; |
| 508 | } | 536 | } |
| 509 | case PageType::RasterizerCachedSpecial: { | 537 | case PageType::RasterizerCachedSpecial: { |
| 510 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); | 538 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); |
| 511 | 539 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); | |
| 512 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), | ||
| 513 | copy_amount); | ||
| 514 | |||
| 515 | GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); | 540 | GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); |
| 516 | break; | 541 | break; |
| 517 | } | 542 | } |
| @@ -557,18 +582,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { | |||
| 557 | break; | 582 | break; |
| 558 | } | 583 | } |
| 559 | case PageType::RasterizerCachedMemory: { | 584 | case PageType::RasterizerCachedMemory: { |
| 560 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), | 585 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); |
| 561 | copy_amount); | ||
| 562 | |||
| 563 | std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); | 586 | std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); |
| 564 | break; | 587 | break; |
| 565 | } | 588 | } |
| 566 | case PageType::RasterizerCachedSpecial: { | 589 | case PageType::RasterizerCachedSpecial: { |
| 567 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); | 590 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); |
| 568 | 591 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate); | |
| 569 | RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), | ||
| 570 | copy_amount); | ||
| 571 | |||
| 572 | GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); | 592 | GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); |
| 573 | break; | 593 | break; |
| 574 | } | 594 | } |
| @@ -613,15 +633,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { | |||
| 613 | break; | 633 | break; |
| 614 | } | 634 | } |
| 615 | case PageType::RasterizerCachedMemory: { | 635 | case PageType::RasterizerCachedMemory: { |
| 616 | RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); | 636 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); |
| 617 | |||
| 618 | WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); | 637 | WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); |
| 619 | break; | 638 | break; |
| 620 | } | 639 | } |
| 621 | case PageType::RasterizerCachedSpecial: { | 640 | case PageType::RasterizerCachedSpecial: { |
| 622 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); | 641 | DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); |
| 623 | 642 | RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush); | |
| 624 | RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); | ||
| 625 | 643 | ||
| 626 | std::vector<u8> buffer(copy_amount); | 644 | std::vector<u8> buffer(copy_amount); |
| 627 | GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); | 645 | 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) | |||
| 680 | mmio_handler->Write64(addr, data); | 698 | mmio_handler->Write64(addr, data); |
| 681 | } | 699 | } |
| 682 | 700 | ||
| 683 | PAddr VirtualToPhysicalAddress(const VAddr addr) { | 701 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { |
| 684 | if (addr == 0) { | 702 | if (addr == 0) { |
| 685 | return 0; | 703 | return 0; |
| 686 | } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { | 704 | } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { |
| @@ -697,12 +715,20 @@ PAddr VirtualToPhysicalAddress(const VAddr addr) { | |||
| 697 | return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR; | 715 | return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR; |
| 698 | } | 716 | } |
| 699 | 717 | ||
| 700 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); | 718 | return boost::none; |
| 701 | // To help with debugging, set bit on address so that it's obviously invalid. | 719 | } |
| 702 | return addr | 0x80000000; | 720 | |
| 721 | PAddr VirtualToPhysicalAddress(const VAddr addr) { | ||
| 722 | auto paddr = TryVirtualToPhysicalAddress(addr); | ||
| 723 | if (!paddr) { | ||
| 724 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); | ||
| 725 | // To help with debugging, set bit on address so that it's obviously invalid. | ||
| 726 | return addr | 0x80000000; | ||
| 727 | } | ||
| 728 | return *paddr; | ||
| 703 | } | 729 | } |
| 704 | 730 | ||
| 705 | VAddr PhysicalToVirtualAddress(const PAddr addr) { | 731 | boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) { |
| 706 | if (addr == 0) { | 732 | if (addr == 0) { |
| 707 | return 0; | 733 | return 0; |
| 708 | } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { | 734 | } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { |
| @@ -717,9 +743,7 @@ VAddr PhysicalToVirtualAddress(const PAddr addr) { | |||
| 717 | return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR; | 743 | return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR; |
| 718 | } | 744 | } |
| 719 | 745 | ||
| 720 | LOG_ERROR(HW_Memory, "Unknown physical address @ 0x%08X", addr); | 746 | return boost::none; |
| 721 | // To help with debugging, set bit on address so that it's obviously invalid. | ||
| 722 | return addr | 0x80000000; | ||
| 723 | } | 747 | } |
| 724 | 748 | ||
| 725 | } // namespace | 749 | } // 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 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <boost/optional.hpp> | ||
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | 12 | ||
| 12 | namespace Memory { | 13 | namespace Memory { |
| @@ -148,15 +149,23 @@ u8* GetPointer(VAddr virtual_address); | |||
| 148 | std::string ReadCString(VAddr virtual_address, std::size_t max_length); | 149 | std::string ReadCString(VAddr virtual_address, std::size_t max_length); |
| 149 | 150 | ||
| 150 | /** | 151 | /** |
| 151 | * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical | 152 | * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical |
| 152 | * address. This should be used by services to translate addresses for use by the hardware. | 153 | * address. This should be used by services to translate addresses for use by the hardware. |
| 153 | */ | 154 | */ |
| 155 | boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr); | ||
| 156 | |||
| 157 | /** | ||
| 158 | * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical | ||
| 159 | * address. This should be used by services to translate addresses for use by the hardware. | ||
| 160 | * | ||
| 161 | * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure. | ||
| 162 | */ | ||
| 154 | PAddr VirtualToPhysicalAddress(VAddr addr); | 163 | PAddr VirtualToPhysicalAddress(VAddr addr); |
| 155 | 164 | ||
| 156 | /** | 165 | /** |
| 157 | * Undoes a mapping performed by VirtualToPhysicalAddress(). | 166 | * Undoes a mapping performed by VirtualToPhysicalAddress(). |
| 158 | */ | 167 | */ |
| 159 | VAddr PhysicalToVirtualAddress(PAddr addr); | 168 | boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); |
| 160 | 169 | ||
| 161 | /** | 170 | /** |
| 162 | * Gets a pointer to the memory region beginning at the specified physical address. | 171 | * Gets a pointer to the memory region beginning at the specified physical address. |
| @@ -181,6 +190,19 @@ void RasterizerFlushRegion(PAddr start, u32 size); | |||
| 181 | */ | 190 | */ |
| 182 | void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); | 191 | void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); |
| 183 | 192 | ||
| 193 | enum class FlushMode { | ||
| 194 | /// Write back modified surfaces to RAM | ||
| 195 | Flush, | ||
| 196 | /// Write back modified surfaces to RAM, and also remove them from the cache | ||
| 197 | FlushAndInvalidate, | ||
| 198 | }; | ||
| 199 | |||
| 200 | /** | ||
| 201 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | ||
| 202 | * address region. | ||
| 203 | */ | ||
| 204 | void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); | ||
| 205 | |||
| 184 | /** | 206 | /** |
| 185 | * Dynarmic has an optimization to memory accesses when the pointer to the page exists that | 207 | * Dynarmic has an optimization to memory accesses when the pointer to the page exists that |
| 186 | * can be used by setting up the current page table as a callback. This function is used to | 208 | * 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; | |||
| 19 | class Room::RoomImpl { | 19 | class Room::RoomImpl { |
| 20 | public: | 20 | public: |
| 21 | // This MAC address is used to generate a 'Nintendo' like Mac address. | 21 | // This MAC address is used to generate a 'Nintendo' like Mac address. |
| 22 | const MacAddress NintendoOUI = {0x00, 0x1F, 0x32, 0x00, 0x00, 0x00}; | 22 | const MacAddress NintendoOUI; |
| 23 | std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress | 23 | std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress |
| 24 | 24 | ||
| 25 | ENetHost* server = nullptr; ///< Network interface. | 25 | ENetHost* server = nullptr; ///< Network interface. |
| @@ -36,7 +36,8 @@ public: | |||
| 36 | using MemberList = std::vector<Member>; | 36 | using MemberList = std::vector<Member>; |
| 37 | MemberList members; ///< Information about the members of this room. | 37 | MemberList members; ///< Information about the members of this room. |
| 38 | 38 | ||
| 39 | RoomImpl() : random_gen(std::random_device()()) {} | 39 | RoomImpl() |
| 40 | : random_gen(std::random_device()()), NintendoOUI{0x00, 0x1F, 0x32, 0x00, 0x00, 0x00} {} | ||
| 40 | 41 | ||
| 41 | /// Thread that receives and dispatches network packets | 42 | /// Thread that receives and dispatches network packets |
| 42 | std::unique_ptr<std::thread> room_thread; | 43 | 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 { | |||
| 24 | using MacAddress = std::array<u8, 6>; | 24 | using MacAddress = std::array<u8, 6>; |
| 25 | /// A special MAC address that tells the room we're joining to assign us a MAC address | 25 | /// A special MAC address that tells the room we're joining to assign us a MAC address |
| 26 | /// automatically. | 26 | /// automatically. |
| 27 | const MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 27 | constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
| 28 | 28 | ||
| 29 | // 802.11 broadcast MAC address | 29 | // 802.11 broadcast MAC address |
| 30 | constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 30 | 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) { | |||
| 117 | 117 | ||
| 118 | // Setup the noise LUT for proctex | 118 | // Setup the noise LUT for proctex |
| 119 | proctex_noise_lut.Create(); | 119 | proctex_noise_lut.Create(); |
| 120 | state.proctex_noise_lut.texture_1d = proctex_noise_lut.handle; | 120 | state.proctex_noise_lut.texture_buffer = proctex_noise_lut.handle; |
| 121 | state.Apply(); | 121 | state.Apply(); |
| 122 | proctex_noise_lut_buffer.Create(); | ||
| 123 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_noise_lut_buffer.handle); | ||
| 124 | glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); | ||
| 122 | glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); | 125 | glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); |
| 123 | glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); | 126 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_noise_lut_buffer.handle); |
| 124 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 125 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 126 | 127 | ||
| 127 | // Setup the color map for proctex | 128 | // Setup the color map for proctex |
| 128 | proctex_color_map.Create(); | 129 | proctex_color_map.Create(); |
| 129 | state.proctex_color_map.texture_1d = proctex_color_map.handle; | 130 | state.proctex_color_map.texture_buffer = proctex_color_map.handle; |
| 130 | state.Apply(); | 131 | state.Apply(); |
| 132 | proctex_color_map_buffer.Create(); | ||
| 133 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_color_map_buffer.handle); | ||
| 134 | glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); | ||
| 131 | glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); | 135 | glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); |
| 132 | glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); | 136 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_color_map_buffer.handle); |
| 133 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 134 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 135 | 137 | ||
| 136 | // Setup the alpha map for proctex | 138 | // Setup the alpha map for proctex |
| 137 | proctex_alpha_map.Create(); | 139 | proctex_alpha_map.Create(); |
| 138 | state.proctex_alpha_map.texture_1d = proctex_alpha_map.handle; | 140 | state.proctex_alpha_map.texture_buffer = proctex_alpha_map.handle; |
| 139 | state.Apply(); | 141 | state.Apply(); |
| 142 | proctex_alpha_map_buffer.Create(); | ||
| 143 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_alpha_map_buffer.handle); | ||
| 144 | glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 2 * 128, nullptr, GL_DYNAMIC_DRAW); | ||
| 140 | glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); | 145 | glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); |
| 141 | glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, 128, 0, GL_RG, GL_FLOAT, nullptr); | 146 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, proctex_alpha_map_buffer.handle); |
| 142 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 143 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 144 | 147 | ||
| 145 | // Setup the LUT for proctex | 148 | // Setup the LUT for proctex |
| 146 | proctex_lut.Create(); | 149 | proctex_lut.Create(); |
| 147 | state.proctex_lut.texture_1d = proctex_lut.handle; | 150 | state.proctex_lut.texture_buffer = proctex_lut.handle; |
| 148 | state.Apply(); | 151 | state.Apply(); |
| 152 | proctex_lut_buffer.Create(); | ||
| 153 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); | ||
| 154 | glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 4 * 256, nullptr, GL_DYNAMIC_DRAW); | ||
| 149 | glActiveTexture(TextureUnits::ProcTexLUT.Enum()); | 155 | glActiveTexture(TextureUnits::ProcTexLUT.Enum()); |
| 150 | glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); | 156 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_lut_buffer.handle); |
| 151 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 152 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 153 | 157 | ||
| 154 | // Setup the difference LUT for proctex | 158 | // Setup the difference LUT for proctex |
| 155 | proctex_diff_lut.Create(); | 159 | proctex_diff_lut.Create(); |
| 156 | state.proctex_diff_lut.texture_1d = proctex_diff_lut.handle; | 160 | state.proctex_diff_lut.texture_buffer = proctex_diff_lut.handle; |
| 157 | state.Apply(); | 161 | state.Apply(); |
| 162 | proctex_diff_lut_buffer.Create(); | ||
| 163 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); | ||
| 164 | glBufferData(GL_TEXTURE_BUFFER, sizeof(GLfloat) * 4 * 256, nullptr, GL_DYNAMIC_DRAW); | ||
| 158 | glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); | 165 | glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); |
| 159 | glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, 256, 0, GL_RGBA, GL_FLOAT, nullptr); | 166 | glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, proctex_diff_lut_buffer.handle); |
| 160 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
| 161 | glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
| 162 | 167 | ||
| 163 | // Sync fixed function OpenGL state | 168 | // Sync fixed function OpenGL state |
| 164 | SyncCullMode(); | 169 | SyncCullMode(); |
| @@ -1387,7 +1392,7 @@ void RasterizerOpenGL::SyncProcTexNoise() { | |||
| 1387 | 1392 | ||
| 1388 | // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap | 1393 | // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap |
| 1389 | static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut, | 1394 | static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntry, 128>& lut, |
| 1390 | std::array<GLvec2, 128>& lut_data, GLenum texture) { | 1395 | std::array<GLvec2, 128>& lut_data, GLuint buffer) { |
| 1391 | std::array<GLvec2, 128> new_data; | 1396 | std::array<GLvec2, 128> new_data; |
| 1392 | std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { | 1397 | std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { |
| 1393 | return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; | 1398 | return GLvec2{entry.ToFloat(), entry.DiffToFloat()}; |
| @@ -1395,24 +1400,24 @@ static void SyncProcTexValueLUT(const std::array<Pica::State::ProcTex::ValueEntr | |||
| 1395 | 1400 | ||
| 1396 | if (new_data != lut_data) { | 1401 | if (new_data != lut_data) { |
| 1397 | lut_data = new_data; | 1402 | lut_data = new_data; |
| 1398 | glActiveTexture(texture); | 1403 | glBindBuffer(GL_TEXTURE_BUFFER, buffer); |
| 1399 | glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RG, GL_FLOAT, lut_data.data()); | 1404 | glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec2), new_data.data()); |
| 1400 | } | 1405 | } |
| 1401 | } | 1406 | } |
| 1402 | 1407 | ||
| 1403 | void RasterizerOpenGL::SyncProcTexNoiseLUT() { | 1408 | void RasterizerOpenGL::SyncProcTexNoiseLUT() { |
| 1404 | SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data, | 1409 | SyncProcTexValueLUT(Pica::g_state.proctex.noise_table, proctex_noise_lut_data, |
| 1405 | TextureUnits::ProcTexNoiseLUT.Enum()); | 1410 | proctex_noise_lut_buffer.handle); |
| 1406 | } | 1411 | } |
| 1407 | 1412 | ||
| 1408 | void RasterizerOpenGL::SyncProcTexColorMap() { | 1413 | void RasterizerOpenGL::SyncProcTexColorMap() { |
| 1409 | SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data, | 1414 | SyncProcTexValueLUT(Pica::g_state.proctex.color_map_table, proctex_color_map_data, |
| 1410 | TextureUnits::ProcTexColorMap.Enum()); | 1415 | proctex_color_map_buffer.handle); |
| 1411 | } | 1416 | } |
| 1412 | 1417 | ||
| 1413 | void RasterizerOpenGL::SyncProcTexAlphaMap() { | 1418 | void RasterizerOpenGL::SyncProcTexAlphaMap() { |
| 1414 | SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data, | 1419 | SyncProcTexValueLUT(Pica::g_state.proctex.alpha_map_table, proctex_alpha_map_data, |
| 1415 | TextureUnits::ProcTexAlphaMap.Enum()); | 1420 | proctex_alpha_map_buffer.handle); |
| 1416 | } | 1421 | } |
| 1417 | 1422 | ||
| 1418 | void RasterizerOpenGL::SyncProcTexLUT() { | 1423 | void RasterizerOpenGL::SyncProcTexLUT() { |
| @@ -1427,8 +1432,8 @@ void RasterizerOpenGL::SyncProcTexLUT() { | |||
| 1427 | 1432 | ||
| 1428 | if (new_data != proctex_lut_data) { | 1433 | if (new_data != proctex_lut_data) { |
| 1429 | proctex_lut_data = new_data; | 1434 | proctex_lut_data = new_data; |
| 1430 | glActiveTexture(TextureUnits::ProcTexLUT.Enum()); | 1435 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_lut_buffer.handle); |
| 1431 | glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, proctex_lut_data.data()); | 1436 | glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); |
| 1432 | } | 1437 | } |
| 1433 | } | 1438 | } |
| 1434 | 1439 | ||
| @@ -1444,8 +1449,8 @@ void RasterizerOpenGL::SyncProcTexDiffLUT() { | |||
| 1444 | 1449 | ||
| 1445 | if (new_data != proctex_diff_lut_data) { | 1450 | if (new_data != proctex_diff_lut_data) { |
| 1446 | proctex_diff_lut_data = new_data; | 1451 | proctex_diff_lut_data = new_data; |
| 1447 | glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); | 1452 | glBindBuffer(GL_TEXTURE_BUFFER, proctex_diff_lut_buffer.handle); |
| 1448 | glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, proctex_diff_lut_data.data()); | 1453 | glBufferSubData(GL_TEXTURE_BUFFER, 0, new_data.size() * sizeof(GLvec4), new_data.data()); |
| 1449 | } | 1454 | } |
| 1450 | } | 1455 | } |
| 1451 | 1456 | ||
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: | |||
| 287 | OGLTexture fog_lut; | 287 | OGLTexture fog_lut; |
| 288 | std::array<GLvec2, 128> fog_lut_data{}; | 288 | std::array<GLvec2, 128> fog_lut_data{}; |
| 289 | 289 | ||
| 290 | OGLBuffer proctex_noise_lut_buffer; | ||
| 290 | OGLTexture proctex_noise_lut; | 291 | OGLTexture proctex_noise_lut; |
| 291 | std::array<GLvec2, 128> proctex_noise_lut_data{}; | 292 | std::array<GLvec2, 128> proctex_noise_lut_data{}; |
| 292 | 293 | ||
| 294 | OGLBuffer proctex_color_map_buffer; | ||
| 293 | OGLTexture proctex_color_map; | 295 | OGLTexture proctex_color_map; |
| 294 | std::array<GLvec2, 128> proctex_color_map_data{}; | 296 | std::array<GLvec2, 128> proctex_color_map_data{}; |
| 295 | 297 | ||
| 298 | OGLBuffer proctex_alpha_map_buffer; | ||
| 296 | OGLTexture proctex_alpha_map; | 299 | OGLTexture proctex_alpha_map; |
| 297 | std::array<GLvec2, 128> proctex_alpha_map_data{}; | 300 | std::array<GLvec2, 128> proctex_alpha_map_data{}; |
| 298 | 301 | ||
| 302 | OGLBuffer proctex_lut_buffer; | ||
| 299 | OGLTexture proctex_lut; | 303 | OGLTexture proctex_lut; |
| 300 | std::array<GLvec4, 256> proctex_lut_data{}; | 304 | std::array<GLvec4, 256> proctex_lut_data{}; |
| 301 | 305 | ||
| 306 | OGLBuffer proctex_diff_lut_buffer; | ||
| 302 | OGLTexture proctex_diff_lut; | 307 | OGLTexture proctex_diff_lut; |
| 303 | std::array<GLvec4, 256> proctex_diff_lut_data{}; | 308 | std::array<GLvec4, 256> proctex_diff_lut_data{}; |
| 304 | }; | 309 | }; |
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( | |||
| 542 | config.GetDepthBufferPhysicalAddress(), | 542 | config.GetDepthBufferPhysicalAddress(), |
| 543 | fb_area * Pica::FramebufferRegs::BytesPerDepthPixel(config.depth_format)); | 543 | fb_area * Pica::FramebufferRegs::BytesPerDepthPixel(config.depth_format)); |
| 544 | bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0; | 544 | bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0; |
| 545 | bool using_depth_fb = | 545 | bool depth_write_enable = regs.framebuffer.output_merger.depth_write_enable && |
| 546 | config.GetDepthBufferPhysicalAddress() != 0 && | 546 | regs.framebuffer.framebuffer.allow_depth_stencil_write; |
| 547 | (regs.framebuffer.output_merger.depth_test_enable || | 547 | bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && |
| 548 | regs.framebuffer.output_merger.depth_write_enable || !framebuffers_overlap); | 548 | (regs.framebuffer.output_merger.depth_test_enable || depth_write_enable || |
| 549 | !framebuffers_overlap); | ||
| 549 | 550 | ||
| 550 | if (framebuffers_overlap && using_color_fb && using_depth_fb) { | 551 | if (framebuffers_overlap && using_color_fb && using_depth_fb) { |
| 551 | LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " | 552 | 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) { | |||
| 886 | // coord=1.0 is lut[127]+lut_diff[127]. For other indices, the result is interpolated using | 886 | // coord=1.0 is lut[127]+lut_diff[127]. For other indices, the result is interpolated using |
| 887 | // value entries and difference entries. | 887 | // value entries and difference entries. |
| 888 | out += R"( | 888 | out += R"( |
| 889 | float ProcTexLookupLUT(sampler1D lut, float coord) { | 889 | float ProcTexLookupLUT(samplerBuffer lut, float coord) { |
| 890 | coord *= 128; | 890 | coord *= 128; |
| 891 | float index_i = clamp(floor(coord), 0.0, 127.0); | 891 | float index_i = clamp(floor(coord), 0.0, 127.0); |
| 892 | float index_f = coord - index_i; // fract() cannot be used here because 128.0 needs to be | 892 | float index_f = coord - index_i; // fract() cannot be used here because 128.0 needs to be |
| 893 | // extracted as index_i = 127.0 and index_f = 1.0 | 893 | // extracted as index_i = 127.0 and index_f = 1.0 |
| 894 | vec2 entry = texelFetch(lut, int(index_i), 0).rg; | 894 | vec2 entry = texelFetch(lut, int(index_i)).rg; |
| 895 | return clamp(entry.r + entry.g * index_f, 0.0, 1.0); | 895 | return clamp(entry.r + entry.g * index_f, 0.0, 1.0); |
| 896 | } | 896 | } |
| 897 | )"; | 897 | )"; |
| @@ -979,14 +979,14 @@ float ProcTexNoiseCoef(vec2 x) { | |||
| 979 | out += "int lut_index_i = int(lut_coord) + " + | 979 | out += "int lut_index_i = int(lut_coord) + " + |
| 980 | std::to_string(config.state.proctex.lut_offset) + ";\n"; | 980 | std::to_string(config.state.proctex.lut_offset) + ";\n"; |
| 981 | out += "float lut_index_f = fract(lut_coord);\n"; | 981 | out += "float lut_index_f = fract(lut_coord);\n"; |
| 982 | out += "vec4 final_color = texelFetch(proctex_lut, lut_index_i, 0) + lut_index_f * " | 982 | out += "vec4 final_color = texelFetch(proctex_lut, lut_index_i) + lut_index_f * " |
| 983 | "texelFetch(proctex_diff_lut, lut_index_i, 0);\n"; | 983 | "texelFetch(proctex_diff_lut, lut_index_i);\n"; |
| 984 | break; | 984 | break; |
| 985 | case ProcTexFilter::Nearest: | 985 | case ProcTexFilter::Nearest: |
| 986 | case ProcTexFilter::NearestMipmapLinear: | 986 | case ProcTexFilter::NearestMipmapLinear: |
| 987 | case ProcTexFilter::NearestMipmapNearest: | 987 | case ProcTexFilter::NearestMipmapNearest: |
| 988 | out += "lut_coord += " + std::to_string(config.state.proctex.lut_offset) + ";\n"; | 988 | out += "lut_coord += " + std::to_string(config.state.proctex.lut_offset) + ";\n"; |
| 989 | out += "vec4 final_color = texelFetch(proctex_lut, int(round(lut_coord)), 0);\n"; | 989 | out += "vec4 final_color = texelFetch(proctex_lut, int(round(lut_coord)));\n"; |
| 990 | break; | 990 | break; |
| 991 | } | 991 | } |
| 992 | 992 | ||
| @@ -1053,11 +1053,11 @@ layout (std140) uniform shader_data { | |||
| 1053 | uniform sampler2D tex[3]; | 1053 | uniform sampler2D tex[3]; |
| 1054 | uniform samplerBuffer lighting_lut; | 1054 | uniform samplerBuffer lighting_lut; |
| 1055 | uniform samplerBuffer fog_lut; | 1055 | uniform samplerBuffer fog_lut; |
| 1056 | uniform sampler1D proctex_noise_lut; | 1056 | uniform samplerBuffer proctex_noise_lut; |
| 1057 | uniform sampler1D proctex_color_map; | 1057 | uniform samplerBuffer proctex_color_map; |
| 1058 | uniform sampler1D proctex_alpha_map; | 1058 | uniform samplerBuffer proctex_alpha_map; |
| 1059 | uniform sampler1D proctex_lut; | 1059 | uniform samplerBuffer proctex_lut; |
| 1060 | uniform sampler1D proctex_diff_lut; | 1060 | uniform samplerBuffer proctex_diff_lut; |
| 1061 | 1061 | ||
| 1062 | // Rotate the vector v by the quaternion q | 1062 | // Rotate the vector v by the quaternion q |
| 1063 | vec3 quaternion_rotate(vec4 q, vec3 v) { | 1063 | 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() { | |||
| 56 | 56 | ||
| 57 | fog_lut.texture_buffer = 0; | 57 | fog_lut.texture_buffer = 0; |
| 58 | 58 | ||
| 59 | proctex_lut.texture_1d = 0; | 59 | proctex_lut.texture_buffer = 0; |
| 60 | proctex_diff_lut.texture_1d = 0; | 60 | proctex_diff_lut.texture_buffer = 0; |
| 61 | proctex_color_map.texture_1d = 0; | 61 | proctex_color_map.texture_buffer = 0; |
| 62 | proctex_alpha_map.texture_1d = 0; | 62 | proctex_alpha_map.texture_buffer = 0; |
| 63 | proctex_noise_lut.texture_1d = 0; | 63 | proctex_noise_lut.texture_buffer = 0; |
| 64 | 64 | ||
| 65 | draw.read_framebuffer = 0; | 65 | draw.read_framebuffer = 0; |
| 66 | draw.draw_framebuffer = 0; | 66 | draw.draw_framebuffer = 0; |
| @@ -204,33 +204,33 @@ void OpenGLState::Apply() const { | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | // ProcTex Noise LUT | 206 | // ProcTex Noise LUT |
| 207 | if (proctex_noise_lut.texture_1d != cur_state.proctex_noise_lut.texture_1d) { | 207 | if (proctex_noise_lut.texture_buffer != cur_state.proctex_noise_lut.texture_buffer) { |
| 208 | glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); | 208 | glActiveTexture(TextureUnits::ProcTexNoiseLUT.Enum()); |
| 209 | glBindTexture(GL_TEXTURE_1D, proctex_noise_lut.texture_1d); | 209 | glBindTexture(GL_TEXTURE_BUFFER, proctex_noise_lut.texture_buffer); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | // ProcTex Color Map | 212 | // ProcTex Color Map |
| 213 | if (proctex_color_map.texture_1d != cur_state.proctex_color_map.texture_1d) { | 213 | if (proctex_color_map.texture_buffer != cur_state.proctex_color_map.texture_buffer) { |
| 214 | glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); | 214 | glActiveTexture(TextureUnits::ProcTexColorMap.Enum()); |
| 215 | glBindTexture(GL_TEXTURE_1D, proctex_color_map.texture_1d); | 215 | glBindTexture(GL_TEXTURE_BUFFER, proctex_color_map.texture_buffer); |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | // ProcTex Alpha Map | 218 | // ProcTex Alpha Map |
| 219 | if (proctex_alpha_map.texture_1d != cur_state.proctex_alpha_map.texture_1d) { | 219 | if (proctex_alpha_map.texture_buffer != cur_state.proctex_alpha_map.texture_buffer) { |
| 220 | glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); | 220 | glActiveTexture(TextureUnits::ProcTexAlphaMap.Enum()); |
| 221 | glBindTexture(GL_TEXTURE_1D, proctex_alpha_map.texture_1d); | 221 | glBindTexture(GL_TEXTURE_BUFFER, proctex_alpha_map.texture_buffer); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | // ProcTex LUT | 224 | // ProcTex LUT |
| 225 | if (proctex_lut.texture_1d != cur_state.proctex_lut.texture_1d) { | 225 | if (proctex_lut.texture_buffer != cur_state.proctex_lut.texture_buffer) { |
| 226 | glActiveTexture(TextureUnits::ProcTexLUT.Enum()); | 226 | glActiveTexture(TextureUnits::ProcTexLUT.Enum()); |
| 227 | glBindTexture(GL_TEXTURE_1D, proctex_lut.texture_1d); | 227 | glBindTexture(GL_TEXTURE_BUFFER, proctex_lut.texture_buffer); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | // ProcTex Diff LUT | 230 | // ProcTex Diff LUT |
| 231 | if (proctex_diff_lut.texture_1d != cur_state.proctex_diff_lut.texture_1d) { | 231 | if (proctex_diff_lut.texture_buffer != cur_state.proctex_diff_lut.texture_buffer) { |
| 232 | glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); | 232 | glActiveTexture(TextureUnits::ProcTexDiffLUT.Enum()); |
| 233 | glBindTexture(GL_TEXTURE_1D, proctex_diff_lut.texture_1d); | 233 | glBindTexture(GL_TEXTURE_BUFFER, proctex_diff_lut.texture_buffer); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | // Framebuffer | 236 | // Framebuffer |
| @@ -274,16 +274,16 @@ void OpenGLState::ResetTexture(GLuint handle) { | |||
| 274 | cur_state.lighting_lut.texture_buffer = 0; | 274 | cur_state.lighting_lut.texture_buffer = 0; |
| 275 | if (cur_state.fog_lut.texture_buffer == handle) | 275 | if (cur_state.fog_lut.texture_buffer == handle) |
| 276 | cur_state.fog_lut.texture_buffer = 0; | 276 | cur_state.fog_lut.texture_buffer = 0; |
| 277 | if (cur_state.proctex_noise_lut.texture_1d == handle) | 277 | if (cur_state.proctex_noise_lut.texture_buffer == handle) |
| 278 | cur_state.proctex_noise_lut.texture_1d = 0; | 278 | cur_state.proctex_noise_lut.texture_buffer = 0; |
| 279 | if (cur_state.proctex_color_map.texture_1d == handle) | 279 | if (cur_state.proctex_color_map.texture_buffer == handle) |
| 280 | cur_state.proctex_color_map.texture_1d = 0; | 280 | cur_state.proctex_color_map.texture_buffer = 0; |
| 281 | if (cur_state.proctex_alpha_map.texture_1d == handle) | 281 | if (cur_state.proctex_alpha_map.texture_buffer == handle) |
| 282 | cur_state.proctex_alpha_map.texture_1d = 0; | 282 | cur_state.proctex_alpha_map.texture_buffer = 0; |
| 283 | if (cur_state.proctex_lut.texture_1d == handle) | 283 | if (cur_state.proctex_lut.texture_buffer == handle) |
| 284 | cur_state.proctex_lut.texture_1d = 0; | 284 | cur_state.proctex_lut.texture_buffer = 0; |
| 285 | if (cur_state.proctex_diff_lut.texture_1d == handle) | 285 | if (cur_state.proctex_diff_lut.texture_buffer == handle) |
| 286 | cur_state.proctex_diff_lut.texture_1d = 0; | 286 | cur_state.proctex_diff_lut.texture_buffer = 0; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | void OpenGLState::ResetSampler(GLuint handle) { | 289 | 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: | |||
| 95 | } fog_lut; | 95 | } fog_lut; |
| 96 | 96 | ||
| 97 | struct { | 97 | struct { |
| 98 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | 98 | GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER |
| 99 | } proctex_noise_lut; | 99 | } proctex_noise_lut; |
| 100 | 100 | ||
| 101 | struct { | 101 | struct { |
| 102 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | 102 | GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER |
| 103 | } proctex_color_map; | 103 | } proctex_color_map; |
| 104 | 104 | ||
| 105 | struct { | 105 | struct { |
| 106 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | 106 | GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER |
| 107 | } proctex_alpha_map; | 107 | } proctex_alpha_map; |
| 108 | 108 | ||
| 109 | struct { | 109 | struct { |
| 110 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | 110 | GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER |
| 111 | } proctex_lut; | 111 | } proctex_lut; |
| 112 | 112 | ||
| 113 | struct { | 113 | struct { |
| 114 | GLuint texture_1d; // GL_TEXTURE_BINDING_1D | 114 | GLuint texture_buffer; // GL_TEXTURE_BINDING_BUFFER |
| 115 | } proctex_diff_lut; | 115 | } proctex_diff_lut; |
| 116 | 116 | ||
| 117 | struct { | 117 | struct { |