diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 7 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 5 |
8 files changed, 48 insertions, 16 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index c1eea861d..7d8ed6920 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 11 | #include "video_core/renderer_base.h" | ||
| 12 | #include "video_core/video_core.h" | ||
| 11 | 13 | ||
| 12 | namespace Service::Nvidia::Devices { | 14 | namespace Service::Nvidia::Devices { |
| 13 | 15 | ||
| @@ -154,6 +156,9 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 154 | 156 | ||
| 155 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); | 157 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); |
| 156 | 158 | ||
| 159 | // Remove this memory region from the rasterizer cache. | ||
| 160 | VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); | ||
| 161 | |||
| 157 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); | 162 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); |
| 158 | 163 | ||
| 159 | buffer_mappings.erase(itr->second.offset); | 164 | buffer_mappings.erase(itr->second.offset); |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 23fe98190..2fc7c87e0 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -148,6 +148,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { | 150 | u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { |
| 151 | // TODO(Subv): These flags are unconfirmed. | ||
| 151 | enum FreeFlags { | 152 | enum FreeFlags { |
| 152 | Freed = 0, | 153 | Freed = 0, |
| 153 | NotFreedYet = 1, | 154 | NotFreedYet = 1, |
| @@ -161,15 +162,21 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 161 | auto itr = handles.find(params.handle); | 162 | auto itr = handles.find(params.handle); |
| 162 | ASSERT(itr != handles.end()); | 163 | ASSERT(itr != handles.end()); |
| 163 | 164 | ||
| 165 | ASSERT(itr->second->refcount > 0); | ||
| 166 | |||
| 164 | itr->second->refcount--; | 167 | itr->second->refcount--; |
| 165 | 168 | ||
| 166 | params.refcount = itr->second->refcount; | ||
| 167 | params.size = itr->second->size; | 169 | params.size = itr->second->size; |
| 168 | 170 | ||
| 169 | if (itr->second->refcount == 0) | 171 | if (itr->second->refcount == 0) { |
| 170 | params.flags = Freed; | 172 | params.flags = Freed; |
| 171 | else | 173 | // The address of the nvmap is written to the output if we're finally freeing it, otherwise |
| 174 | // 0 is written. | ||
| 175 | params.address = itr->second->addr; | ||
| 176 | } else { | ||
| 172 | params.flags = NotFreedYet; | 177 | params.flags = NotFreedYet; |
| 178 | params.address = 0; | ||
| 179 | } | ||
| 173 | 180 | ||
| 174 | handles.erase(params.handle); | 181 | handles.erase(params.handle); |
| 175 | 182 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 39fafaa7c..f2eec6409 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -94,7 +94,7 @@ private: | |||
| 94 | struct IocFreeParams { | 94 | struct IocFreeParams { |
| 95 | u32_le handle; | 95 | u32_le handle; |
| 96 | INSERT_PADDING_BYTES(4); | 96 | INSERT_PADDING_BYTES(4); |
| 97 | u64_le refcount; | 97 | u64_le address; |
| 98 | u32_le size; | 98 | u32_le size; |
| 99 | u32_le flags; | 99 | u32_le flags; |
| 100 | }; | 100 | }; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index b8fb49ddf..ff67f2a58 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -493,7 +493,11 @@ public: | |||
| 493 | u32 enable[NumRenderTargets]; | 493 | u32 enable[NumRenderTargets]; |
| 494 | } blend; | 494 | } blend; |
| 495 | 495 | ||
| 496 | INSERT_PADDING_WORDS(0x77); | 496 | INSERT_PADDING_WORDS(0x2D); |
| 497 | |||
| 498 | u32 vb_element_base; | ||
| 499 | |||
| 500 | INSERT_PADDING_WORDS(0x49); | ||
| 497 | 501 | ||
| 498 | struct { | 502 | struct { |
| 499 | u32 tsc_address_high; | 503 | u32 tsc_address_high; |
| @@ -792,6 +796,7 @@ ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); | |||
| 792 | ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); | 796 | ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); |
| 793 | ASSERT_REG_POSITION(depth_test_func, 0x4C3); | 797 | ASSERT_REG_POSITION(depth_test_func, 0x4C3); |
| 794 | ASSERT_REG_POSITION(blend, 0x4CF); | 798 | ASSERT_REG_POSITION(blend, 0x4CF); |
| 799 | ASSERT_REG_POSITION(vb_element_base, 0x50D); | ||
| 795 | ASSERT_REG_POSITION(tsc, 0x557); | 800 | ASSERT_REG_POSITION(tsc, 0x557); |
| 796 | ASSERT_REG_POSITION(tic, 0x55D); | 801 | ASSERT_REG_POSITION(tic, 0x55D); |
| 797 | ASSERT_REG_POSITION(code_address, 0x582); | 802 | ASSERT_REG_POSITION(code_address, 0x582); |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 442138988..c298f0bfb 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -49,7 +49,11 @@ void MaxwellDMA::HandleCopy() { | |||
| 49 | ASSERT(regs.src_params.pos_y == 0); | 49 | ASSERT(regs.src_params.pos_y == 0); |
| 50 | ASSERT(regs.dst_params.pos_x == 0); | 50 | ASSERT(regs.dst_params.pos_x == 0); |
| 51 | ASSERT(regs.dst_params.pos_y == 0); | 51 | ASSERT(regs.dst_params.pos_y == 0); |
| 52 | ASSERT(regs.exec.is_dst_linear != regs.exec.is_src_linear); | 52 | |
| 53 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { | ||
| 54 | Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count); | ||
| 55 | return; | ||
| 56 | } | ||
| 53 | 57 | ||
| 54 | u8* src_buffer = Memory::GetPointer(source_cpu); | 58 | u8* src_buffer = Memory::GetPointer(source_cpu); |
| 55 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | 59 | u8* dst_buffer = Memory::GetPointer(dest_cpu); |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 5cefce9fc..2f814a184 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -100,9 +100,9 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { | |||
| 100 | 100 | ||
| 101 | boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { | 101 | boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { |
| 102 | VAddr base_addr = PageSlot(gpu_addr); | 102 | VAddr base_addr = PageSlot(gpu_addr); |
| 103 | ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); | ||
| 104 | 103 | ||
| 105 | if (base_addr == static_cast<u64>(PageStatus::Allocated)) { | 104 | if (base_addr == static_cast<u64>(PageStatus::Allocated) || |
| 105 | base_addr == static_cast<u64>(PageStatus::Unmapped)) { | ||
| 106 | return {}; | 106 | return {}; |
| 107 | } | 107 | } |
| 108 | 108 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a3c5ad2a9..ca3814cfc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -415,14 +415,16 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 415 | 415 | ||
| 416 | const GLenum primitive_mode{MaxwellToGL::PrimitiveTopology(regs.draw.topology)}; | 416 | const GLenum primitive_mode{MaxwellToGL::PrimitiveTopology(regs.draw.topology)}; |
| 417 | if (is_indexed) { | 417 | if (is_indexed) { |
| 418 | const GLint index_min{static_cast<GLint>(regs.index_array.first)}; | 418 | const GLint base_vertex{static_cast<GLint>(regs.vb_element_base)}; |
| 419 | const GLint index_max{static_cast<GLint>(regs.index_array.first + regs.index_array.count)}; | 419 | |
| 420 | glDrawRangeElementsBaseVertex(primitive_mode, index_min, index_max, regs.index_array.count, | 420 | // Adjust the index buffer offset so it points to the first desired index. |
| 421 | MaxwellToGL::IndexFormat(regs.index_array.format), | 421 | index_buffer_offset += regs.index_array.first * regs.index_array.FormatSizeInBytes(); |
| 422 | reinterpret_cast<const void*>(index_buffer_offset), | 422 | |
| 423 | -index_min); | 423 | glDrawElementsBaseVertex(primitive_mode, regs.index_array.count, |
| 424 | MaxwellToGL::IndexFormat(regs.index_array.format), | ||
| 425 | reinterpret_cast<const void*>(index_buffer_offset), base_vertex); | ||
| 424 | } else { | 426 | } else { |
| 425 | glDrawArrays(primitive_mode, 0, regs.vertex_buffer.count); | 427 | glDrawArrays(primitive_mode, regs.vertex_buffer.first, regs.vertex_buffer.count); |
| 426 | } | 428 | } |
| 427 | 429 | ||
| 428 | // Disable scissor test | 430 | // Disable scissor test |
| @@ -639,7 +641,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program, | |||
| 639 | glProgramUniform1i(program, uniform, current_bindpoint); | 641 | glProgramUniform1i(program, uniform, current_bindpoint); |
| 640 | 642 | ||
| 641 | const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset()); | 643 | const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset()); |
| 642 | ASSERT(texture.enabled); | 644 | |
| 645 | if (!texture.enabled) { | ||
| 646 | state.texture_units[current_bindpoint].texture_2d = 0; | ||
| 647 | continue; | ||
| 648 | } | ||
| 643 | 649 | ||
| 644 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); | 650 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); |
| 645 | Surface surface = res_cache.GetTextureSurface(texture); | 651 | Surface surface = res_cache.GetTextureSurface(texture); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 35ad4f161..851ebc263 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -470,6 +470,11 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) { | |||
| 470 | return {}; | 470 | return {}; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | const auto& gpu = Core::System::GetInstance().GPU(); | ||
| 474 | // Don't try to create any entries in the cache if the address of the texture is invalid. | ||
| 475 | if (gpu.memory_manager->GpuToCpuAddress(params.addr) == boost::none) | ||
| 476 | return {}; | ||
| 477 | |||
| 473 | // Check for an exact match in existing surfaces | 478 | // Check for an exact match in existing surfaces |
| 474 | const auto& surface_key{SurfaceKey::Create(params)}; | 479 | const auto& surface_key{SurfaceKey::Create(params)}; |
| 475 | const auto& search{surface_cache.find(surface_key)}; | 480 | const auto& search{surface_cache.find(surface_key)}; |