diff options
| author | 2020-06-11 21:24:45 -0300 | |
|---|---|---|
| committer | 2020-09-06 05:28:48 -0300 | |
| commit | 9e871937250cb92a13336c6c06186c41f19e1738 (patch) | |
| tree | 5151b85f8c4c26e7a5971b32584723f9910ea67b | |
| parent | Merge pull request #4596 from FearlessTobi/port-5495 (diff) | |
| download | yuzu-9e871937250cb92a13336c6c06186c41f19e1738.tar.gz yuzu-9e871937250cb92a13336c6c06186c41f19e1738.tar.xz yuzu-9e871937250cb92a13336c6c06186c41f19e1738.zip | |
video_core: Remove all Core::System references in renderer
Now that the GPU is initialized when video backends are initialized,
it's no longer needed to query components once the game is running: it
can be done when yuzu is booting.
This allows us to pass components between constructors and in the
process remove all Core::System references in the video backend.
53 files changed, 573 insertions, 633 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index c2c0eec0b..df81e8e2c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -188,7 +188,6 @@ struct System::Impl { | |||
| 188 | if (!gpu_core) { | 188 | if (!gpu_core) { |
| 189 | return ResultStatus::ErrorVideoCore; | 189 | return ResultStatus::ErrorVideoCore; |
| 190 | } | 190 | } |
| 191 | gpu_core->Renderer().Rasterizer().SetupDirtyFlags(); | ||
| 192 | 191 | ||
| 193 | is_powered_on = true; | 192 | is_powered_on = true; |
| 194 | exit_lock = false; | 193 | exit_lock = false; |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index b5dc68902..e7edd733f 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -51,46 +51,43 @@ public: | |||
| 51 | bool is_written = false, bool use_fast_cbuf = false) { | 51 | bool is_written = false, bool use_fast_cbuf = false) { |
| 52 | std::lock_guard lock{mutex}; | 52 | std::lock_guard lock{mutex}; |
| 53 | 53 | ||
| 54 | auto& memory_manager = system.GPU().MemoryManager(); | 54 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 55 | const std::optional<VAddr> cpu_addr_opt = memory_manager.GpuToCpuAddress(gpu_addr); | 55 | if (!cpu_addr) { |
| 56 | if (!cpu_addr_opt) { | ||
| 57 | return GetEmptyBuffer(size); | 56 | return GetEmptyBuffer(size); |
| 58 | } | 57 | } |
| 59 | const VAddr cpu_addr = *cpu_addr_opt; | ||
| 60 | 58 | ||
| 61 | // Cache management is a big overhead, so only cache entries with a given size. | 59 | // Cache management is a big overhead, so only cache entries with a given size. |
| 62 | // TODO: Figure out which size is the best for given games. | 60 | // TODO: Figure out which size is the best for given games. |
| 63 | constexpr std::size_t max_stream_size = 0x800; | 61 | constexpr std::size_t max_stream_size = 0x800; |
| 64 | if (use_fast_cbuf || size < max_stream_size) { | 62 | if (use_fast_cbuf || size < max_stream_size) { |
| 65 | if (!is_written && !IsRegionWritten(cpu_addr, cpu_addr + size - 1)) { | 63 | if (!is_written && !IsRegionWritten(*cpu_addr, *cpu_addr + size - 1)) { |
| 66 | const bool is_granular = memory_manager.IsGranularRange(gpu_addr, size); | 64 | const bool is_granular = gpu_memory.IsGranularRange(gpu_addr, size); |
| 67 | if (use_fast_cbuf) { | 65 | if (use_fast_cbuf) { |
| 68 | u8* dest; | 66 | u8* dest; |
| 69 | if (is_granular) { | 67 | if (is_granular) { |
| 70 | dest = memory_manager.GetPointer(gpu_addr); | 68 | dest = gpu_memory.GetPointer(gpu_addr); |
| 71 | } else { | 69 | } else { |
| 72 | staging_buffer.resize(size); | 70 | staging_buffer.resize(size); |
| 73 | dest = staging_buffer.data(); | 71 | dest = staging_buffer.data(); |
| 74 | memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); | 72 | gpu_memory.ReadBlockUnsafe(gpu_addr, dest, size); |
| 75 | } | 73 | } |
| 76 | return ConstBufferUpload(dest, size); | 74 | return ConstBufferUpload(dest, size); |
| 77 | } | 75 | } |
| 78 | if (is_granular) { | 76 | if (is_granular) { |
| 79 | u8* const host_ptr = memory_manager.GetPointer(gpu_addr); | 77 | u8* const host_ptr = gpu_memory.GetPointer(gpu_addr); |
| 80 | return StreamBufferUpload(size, alignment, [host_ptr, size](u8* dest) { | 78 | return StreamBufferUpload(size, alignment, [host_ptr, size](u8* dest) { |
| 81 | std::memcpy(dest, host_ptr, size); | 79 | std::memcpy(dest, host_ptr, size); |
| 82 | }); | 80 | }); |
| 83 | } else { | 81 | } else { |
| 84 | return StreamBufferUpload( | 82 | return StreamBufferUpload(size, alignment, [this, gpu_addr, size](u8* dest) { |
| 85 | size, alignment, [&memory_manager, gpu_addr, size](u8* dest) { | 83 | gpu_memory.ReadBlockUnsafe(gpu_addr, dest, size); |
| 86 | memory_manager.ReadBlockUnsafe(gpu_addr, dest, size); | 84 | }); |
| 87 | }); | ||
| 88 | } | 85 | } |
| 89 | } | 86 | } |
| 90 | } | 87 | } |
| 91 | 88 | ||
| 92 | Buffer* const block = GetBlock(cpu_addr, size); | 89 | Buffer* const block = GetBlock(*cpu_addr, size); |
| 93 | MapInterval* const map = MapAddress(block, gpu_addr, cpu_addr, size); | 90 | MapInterval* const map = MapAddress(block, gpu_addr, *cpu_addr, size); |
| 94 | if (!map) { | 91 | if (!map) { |
| 95 | return GetEmptyBuffer(size); | 92 | return GetEmptyBuffer(size); |
| 96 | } | 93 | } |
| @@ -106,7 +103,7 @@ public: | |||
| 106 | } | 103 | } |
| 107 | } | 104 | } |
| 108 | 105 | ||
| 109 | return BufferInfo{block->Handle(), block->Offset(cpu_addr), block->Address()}; | 106 | return BufferInfo{block->Handle(), block->Offset(*cpu_addr), block->Address()}; |
| 110 | } | 107 | } |
| 111 | 108 | ||
| 112 | /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. | 109 | /// Uploads from a host memory. Returns the OpenGL buffer where it's located and its offset. |
| @@ -262,9 +259,11 @@ public: | |||
| 262 | virtual BufferInfo GetEmptyBuffer(std::size_t size) = 0; | 259 | virtual BufferInfo GetEmptyBuffer(std::size_t size) = 0; |
| 263 | 260 | ||
| 264 | protected: | 261 | protected: |
| 265 | explicit BufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, | 262 | explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_, |
| 266 | std::unique_ptr<StreamBuffer> stream_buffer) | 263 | Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_, |
| 267 | : rasterizer{rasterizer}, system{system}, stream_buffer{std::move(stream_buffer)} {} | 264 | std::unique_ptr<StreamBuffer> stream_buffer_) |
| 265 | : rasterizer{rasterizer_}, gpu_memory{gpu_memory_}, cpu_memory{cpu_memory_}, | ||
| 266 | stream_buffer{std::move(stream_buffer_)}, stream_buffer_handle{stream_buffer->Handle()} {} | ||
| 268 | 267 | ||
| 269 | ~BufferCache() = default; | 268 | ~BufferCache() = default; |
| 270 | 269 | ||
| @@ -326,14 +325,13 @@ private: | |||
| 326 | MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) { | 325 | MapInterval* MapAddress(Buffer* block, GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size) { |
| 327 | const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); | 326 | const VectorMapInterval overlaps = GetMapsInRange(cpu_addr, size); |
| 328 | if (overlaps.empty()) { | 327 | if (overlaps.empty()) { |
| 329 | auto& memory_manager = system.GPU().MemoryManager(); | ||
| 330 | const VAddr cpu_addr_end = cpu_addr + size; | 328 | const VAddr cpu_addr_end = cpu_addr + size; |
| 331 | if (memory_manager.IsGranularRange(gpu_addr, size)) { | 329 | if (gpu_memory.IsGranularRange(gpu_addr, size)) { |
| 332 | u8* host_ptr = memory_manager.GetPointer(gpu_addr); | 330 | u8* const host_ptr = gpu_memory.GetPointer(gpu_addr); |
| 333 | block->Upload(block->Offset(cpu_addr), size, host_ptr); | 331 | block->Upload(block->Offset(cpu_addr), size, host_ptr); |
| 334 | } else { | 332 | } else { |
| 335 | staging_buffer.resize(size); | 333 | staging_buffer.resize(size); |
| 336 | memory_manager.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); | 334 | gpu_memory.ReadBlockUnsafe(gpu_addr, staging_buffer.data(), size); |
| 337 | block->Upload(block->Offset(cpu_addr), size, staging_buffer.data()); | 335 | block->Upload(block->Offset(cpu_addr), size, staging_buffer.data()); |
| 338 | } | 336 | } |
| 339 | return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr)); | 337 | return Register(MapInterval(cpu_addr, cpu_addr_end, gpu_addr)); |
| @@ -392,7 +390,7 @@ private: | |||
| 392 | continue; | 390 | continue; |
| 393 | } | 391 | } |
| 394 | staging_buffer.resize(size); | 392 | staging_buffer.resize(size); |
| 395 | system.Memory().ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size); | 393 | cpu_memory.ReadBlockUnsafe(interval.lower(), staging_buffer.data(), size); |
| 396 | block->Upload(block->Offset(interval.lower()), size, staging_buffer.data()); | 394 | block->Upload(block->Offset(interval.lower()), size, staging_buffer.data()); |
| 397 | } | 395 | } |
| 398 | } | 396 | } |
| @@ -431,7 +429,7 @@ private: | |||
| 431 | const std::size_t size = map->end - map->start; | 429 | const std::size_t size = map->end - map->start; |
| 432 | staging_buffer.resize(size); | 430 | staging_buffer.resize(size); |
| 433 | block->Download(block->Offset(map->start), size, staging_buffer.data()); | 431 | block->Download(block->Offset(map->start), size, staging_buffer.data()); |
| 434 | system.Memory().WriteBlockUnsafe(map->start, staging_buffer.data(), size); | 432 | cpu_memory.WriteBlockUnsafe(map->start, staging_buffer.data(), size); |
| 435 | map->MarkAsModified(false, 0); | 433 | map->MarkAsModified(false, 0); |
| 436 | } | 434 | } |
| 437 | 435 | ||
| @@ -567,7 +565,8 @@ private: | |||
| 567 | } | 565 | } |
| 568 | 566 | ||
| 569 | VideoCore::RasterizerInterface& rasterizer; | 567 | VideoCore::RasterizerInterface& rasterizer; |
| 570 | Core::System& system; | 568 | Tegra::MemoryManager& gpu_memory; |
| 569 | Core::Memory::Memory& cpu_memory; | ||
| 571 | 570 | ||
| 572 | std::unique_ptr<StreamBuffer> stream_buffer; | 571 | std::unique_ptr<StreamBuffer> stream_buffer; |
| 573 | BufferType stream_buffer_handle; | 572 | BufferType stream_buffer_handle; |
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h index 06cc12d5a..de6991ef6 100644 --- a/src/video_core/fence_manager.h +++ b/src/video_core/fence_manager.h | |||
| @@ -74,8 +74,6 @@ public: | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | void WaitPendingFences() { | 76 | void WaitPendingFences() { |
| 77 | auto& gpu{system.GPU()}; | ||
| 78 | auto& memory_manager{gpu.MemoryManager()}; | ||
| 79 | while (!fences.empty()) { | 77 | while (!fences.empty()) { |
| 80 | TFence& current_fence = fences.front(); | 78 | TFence& current_fence = fences.front(); |
| 81 | if (ShouldWait()) { | 79 | if (ShouldWait()) { |
| @@ -83,8 +81,8 @@ public: | |||
| 83 | } | 81 | } |
| 84 | PopAsyncFlushes(); | 82 | PopAsyncFlushes(); |
| 85 | if (current_fence->IsSemaphore()) { | 83 | if (current_fence->IsSemaphore()) { |
| 86 | memory_manager.template Write<u32>(current_fence->GetAddress(), | 84 | gpu_memory.template Write<u32>(current_fence->GetAddress(), |
| 87 | current_fence->GetPayload()); | 85 | current_fence->GetPayload()); |
| 88 | } else { | 86 | } else { |
| 89 | gpu.IncrementSyncPoint(current_fence->GetPayload()); | 87 | gpu.IncrementSyncPoint(current_fence->GetPayload()); |
| 90 | } | 88 | } |
| @@ -93,13 +91,13 @@ public: | |||
| 93 | } | 91 | } |
| 94 | 92 | ||
| 95 | protected: | 93 | protected: |
| 96 | FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 94 | explicit FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_, |
| 97 | TTextureCache& texture_cache, TTBufferCache& buffer_cache, | 95 | TTextureCache& texture_cache_, TTBufferCache& buffer_cache_, |
| 98 | TQueryCache& query_cache) | 96 | TQueryCache& query_cache_) |
| 99 | : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, | 97 | : rasterizer{rasterizer_}, gpu{gpu_}, gpu_memory{gpu.MemoryManager()}, |
| 100 | buffer_cache{buffer_cache}, query_cache{query_cache} {} | 98 | texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, query_cache{query_cache_} {} |
| 101 | 99 | ||
| 102 | virtual ~FenceManager() {} | 100 | virtual ~FenceManager() = default; |
| 103 | 101 | ||
| 104 | /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is | 102 | /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is |
| 105 | /// true | 103 | /// true |
| @@ -113,16 +111,15 @@ protected: | |||
| 113 | /// Waits until a fence has been signalled by the host GPU. | 111 | /// Waits until a fence has been signalled by the host GPU. |
| 114 | virtual void WaitFence(TFence& fence) = 0; | 112 | virtual void WaitFence(TFence& fence) = 0; |
| 115 | 113 | ||
| 116 | Core::System& system; | ||
| 117 | VideoCore::RasterizerInterface& rasterizer; | 114 | VideoCore::RasterizerInterface& rasterizer; |
| 115 | Tegra::GPU& gpu; | ||
| 116 | Tegra::MemoryManager& gpu_memory; | ||
| 118 | TTextureCache& texture_cache; | 117 | TTextureCache& texture_cache; |
| 119 | TTBufferCache& buffer_cache; | 118 | TTBufferCache& buffer_cache; |
| 120 | TQueryCache& query_cache; | 119 | TQueryCache& query_cache; |
| 121 | 120 | ||
| 122 | private: | 121 | private: |
| 123 | void TryReleasePendingFences() { | 122 | void TryReleasePendingFences() { |
| 124 | auto& gpu{system.GPU()}; | ||
| 125 | auto& memory_manager{gpu.MemoryManager()}; | ||
| 126 | while (!fences.empty()) { | 123 | while (!fences.empty()) { |
| 127 | TFence& current_fence = fences.front(); | 124 | TFence& current_fence = fences.front(); |
| 128 | if (ShouldWait() && !IsFenceSignaled(current_fence)) { | 125 | if (ShouldWait() && !IsFenceSignaled(current_fence)) { |
| @@ -130,8 +127,8 @@ private: | |||
| 130 | } | 127 | } |
| 131 | PopAsyncFlushes(); | 128 | PopAsyncFlushes(); |
| 132 | if (current_fence->IsSemaphore()) { | 129 | if (current_fence->IsSemaphore()) { |
| 133 | memory_manager.template Write<u32>(current_fence->GetAddress(), | 130 | gpu_memory.template Write<u32>(current_fence->GetAddress(), |
| 134 | current_fence->GetPayload()); | 131 | current_fence->GetPayload()); |
| 135 | } else { | 132 | } else { |
| 136 | gpu.IncrementSyncPoint(current_fence->GetPayload()); | 133 | gpu.IncrementSyncPoint(current_fence->GetPayload()); |
| 137 | } | 134 | } |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index acb6e6d46..4bb9256e9 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -28,8 +28,8 @@ namespace Tegra { | |||
| 28 | MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); | 28 | MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192)); |
| 29 | 29 | ||
| 30 | GPU::GPU(Core::System& system_, bool is_async_) | 30 | GPU::GPU(Core::System& system_, bool is_async_) |
| 31 | : system{system_}, dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, | 31 | : system{system_}, memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, |
| 32 | memory_manager{std::make_unique<Tegra::MemoryManager>(system)}, | 32 | dma_pusher{std::make_unique<Tegra::DmaPusher>(system, *this)}, |
| 33 | maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, | 33 | maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)}, |
| 34 | fermi_2d{std::make_unique<Engines::Fermi2D>()}, | 34 | fermi_2d{std::make_unique<Engines::Fermi2D>()}, |
| 35 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, | 35 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index c7d11deb2..2d15d1c6f 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -347,12 +347,11 @@ private: | |||
| 347 | 347 | ||
| 348 | protected: | 348 | protected: |
| 349 | Core::System& system; | 349 | Core::System& system; |
| 350 | std::unique_ptr<Tegra::MemoryManager> memory_manager; | ||
| 350 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; | 351 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; |
| 351 | std::unique_ptr<VideoCore::RendererBase> renderer; | 352 | std::unique_ptr<VideoCore::RendererBase> renderer; |
| 352 | 353 | ||
| 353 | private: | 354 | private: |
| 354 | std::unique_ptr<Tegra::MemoryManager> memory_manager; | ||
| 355 | |||
| 356 | /// Mapping of command subchannels to their bound engine ids | 355 | /// Mapping of command subchannels to their bound engine ids |
| 357 | std::array<EngineID, 8> bound_engines = {}; | 356 | std::array<EngineID, 8> bound_engines = {}; |
| 358 | /// 3D engine | 357 | /// 3D engine |
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h index 0d3a88765..d13a66bb6 100644 --- a/src/video_core/query_cache.h +++ b/src/video_core/query_cache.h | |||
| @@ -95,10 +95,12 @@ template <class QueryCache, class CachedQuery, class CounterStream, class HostCo | |||
| 95 | class QueryPool> | 95 | class QueryPool> |
| 96 | class QueryCacheBase { | 96 | class QueryCacheBase { |
| 97 | public: | 97 | public: |
| 98 | explicit QueryCacheBase(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 98 | explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_, |
| 99 | : system{system}, rasterizer{rasterizer}, streams{{CounterStream{ | 99 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 100 | static_cast<QueryCache&>(*this), | 100 | Tegra::MemoryManager& gpu_memory_) |
| 101 | VideoCore::QueryType::SamplesPassed}}} {} | 101 | : rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, |
| 102 | gpu_memory{gpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this), | ||
| 103 | VideoCore::QueryType::SamplesPassed}}} {} | ||
| 102 | 104 | ||
| 103 | void InvalidateRegion(VAddr addr, std::size_t size) { | 105 | void InvalidateRegion(VAddr addr, std::size_t size) { |
| 104 | std::unique_lock lock{mutex}; | 106 | std::unique_lock lock{mutex}; |
| @@ -118,29 +120,27 @@ public: | |||
| 118 | */ | 120 | */ |
| 119 | void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) { | 121 | void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) { |
| 120 | std::unique_lock lock{mutex}; | 122 | std::unique_lock lock{mutex}; |
| 121 | auto& memory_manager = system.GPU().MemoryManager(); | 123 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 122 | const std::optional<VAddr> cpu_addr_opt = memory_manager.GpuToCpuAddress(gpu_addr); | 124 | ASSERT(cpu_addr); |
| 123 | ASSERT(cpu_addr_opt); | ||
| 124 | VAddr cpu_addr = *cpu_addr_opt; | ||
| 125 | 125 | ||
| 126 | CachedQuery* query = TryGet(cpu_addr); | 126 | CachedQuery* query = TryGet(*cpu_addr); |
| 127 | if (!query) { | 127 | if (!query) { |
| 128 | ASSERT_OR_EXECUTE(cpu_addr_opt, return;); | 128 | ASSERT_OR_EXECUTE(cpu_addr, return;); |
| 129 | const auto host_ptr = memory_manager.GetPointer(gpu_addr); | 129 | u8* const host_ptr = gpu_memory.GetPointer(gpu_addr); |
| 130 | 130 | ||
| 131 | query = Register(type, cpu_addr, host_ptr, timestamp.has_value()); | 131 | query = Register(type, *cpu_addr, host_ptr, timestamp.has_value()); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | query->BindCounter(Stream(type).Current(), timestamp); | 134 | query->BindCounter(Stream(type).Current(), timestamp); |
| 135 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | 135 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { |
| 136 | AsyncFlushQuery(cpu_addr); | 136 | AsyncFlushQuery(*cpu_addr); |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch. | 140 | /// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch. |
| 141 | void UpdateCounters() { | 141 | void UpdateCounters() { |
| 142 | std::unique_lock lock{mutex}; | 142 | std::unique_lock lock{mutex}; |
| 143 | const auto& regs = system.GPU().Maxwell3D().regs; | 143 | const auto& regs = maxwell3d.regs; |
| 144 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); | 144 | Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| @@ -270,8 +270,9 @@ private: | |||
| 270 | static constexpr std::uintptr_t PAGE_SIZE = 4096; | 270 | static constexpr std::uintptr_t PAGE_SIZE = 4096; |
| 271 | static constexpr unsigned PAGE_BITS = 12; | 271 | static constexpr unsigned PAGE_BITS = 12; |
| 272 | 272 | ||
| 273 | Core::System& system; | ||
| 274 | VideoCore::RasterizerInterface& rasterizer; | 273 | VideoCore::RasterizerInterface& rasterizer; |
| 274 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 275 | Tegra::MemoryManager& gpu_memory; | ||
| 275 | 276 | ||
| 276 | std::recursive_mutex mutex; | 277 | std::recursive_mutex mutex; |
| 277 | 278 | ||
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 3cbdac8e7..b3e0919f8 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -106,11 +106,8 @@ public: | |||
| 106 | virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {} | 106 | virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {} |
| 107 | 107 | ||
| 108 | /// Initialize disk cached resources for the game being emulated | 108 | /// Initialize disk cached resources for the game being emulated |
| 109 | virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false, | 109 | virtual void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading, |
| 110 | const DiskResourceLoadCallback& callback = {}) {} | 110 | const DiskResourceLoadCallback& callback) {} |
| 111 | |||
| 112 | /// Initializes renderer dirty flags | ||
| 113 | virtual void SetupDirtyFlags() {} | ||
| 114 | 111 | ||
| 115 | /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver. | 112 | /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver. |
| 116 | GuestDriverProfile& AccessGuestDriverProfile() { | 113 | GuestDriverProfile& AccessGuestDriverProfile() { |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index e866d8f2f..b1c4cd62f 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -59,9 +59,10 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst | |||
| 59 | static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size)); | 59 | static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size)); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, | 62 | OGLBufferCache::OGLBufferCache(VideoCore::RasterizerInterface& rasterizer, |
| 63 | Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory, | ||
| 63 | const Device& device_, std::size_t stream_size) | 64 | const Device& device_, std::size_t stream_size) |
| 64 | : GenericBufferCache{rasterizer, system, | 65 | : GenericBufferCache{rasterizer, gpu_memory, cpu_memory, |
| 65 | std::make_unique<OGLStreamBuffer>(device_, stream_size, true)}, | 66 | std::make_unique<OGLStreamBuffer>(device_, stream_size, true)}, |
| 66 | device{device_} { | 67 | device{device_} { |
| 67 | if (!device.HasFastBufferSubData()) { | 68 | if (!device.HasFastBufferSubData()) { |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 88fdc0536..f75b32e31 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -52,7 +52,8 @@ private: | |||
| 52 | using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>; | 52 | using GenericBufferCache = VideoCommon::BufferCache<Buffer, GLuint, OGLStreamBuffer>; |
| 53 | class OGLBufferCache final : public GenericBufferCache { | 53 | class OGLBufferCache final : public GenericBufferCache { |
| 54 | public: | 54 | public: |
| 55 | explicit OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system, | 55 | explicit OGLBufferCache(VideoCore::RasterizerInterface& rasterizer, |
| 56 | Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory, | ||
| 56 | const Device& device, std::size_t stream_size); | 57 | const Device& device, std::size_t stream_size); |
| 57 | ~OGLBufferCache(); | 58 | ~OGLBufferCache(); |
| 58 | 59 | ||
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp index 3d2588dd2..b532fdcc2 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.cpp +++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp | |||
| @@ -45,11 +45,10 @@ void GLInnerFence::Wait() { | |||
| 45 | glClientWaitSync(sync_object.handle, 0, GL_TIMEOUT_IGNORED); | 45 | glClientWaitSync(sync_object.handle, 0, GL_TIMEOUT_IGNORED); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, | 48 | FenceManagerOpenGL::FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, |
| 49 | VideoCore::RasterizerInterface& rasterizer, | ||
| 50 | TextureCacheOpenGL& texture_cache, | 49 | TextureCacheOpenGL& texture_cache, |
| 51 | OGLBufferCache& buffer_cache, QueryCache& query_cache) | 50 | OGLBufferCache& buffer_cache, QueryCache& query_cache) |
| 52 | : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache) {} | 51 | : GenericFenceManager{rasterizer, gpu, texture_cache, buffer_cache, query_cache} {} |
| 53 | 52 | ||
| 54 | Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) { | 53 | Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) { |
| 55 | return std::make_shared<GLInnerFence>(value, is_stubbed); | 54 | return std::make_shared<GLInnerFence>(value, is_stubbed); |
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h index 1686cf5c8..da1dcdace 100644 --- a/src/video_core/renderer_opengl/gl_fence_manager.h +++ b/src/video_core/renderer_opengl/gl_fence_manager.h | |||
| @@ -37,9 +37,9 @@ using GenericFenceManager = | |||
| 37 | 37 | ||
| 38 | class FenceManagerOpenGL final : public GenericFenceManager { | 38 | class FenceManagerOpenGL final : public GenericFenceManager { |
| 39 | public: | 39 | public: |
| 40 | FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 40 | explicit FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, |
| 41 | TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache, | 41 | TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache, |
| 42 | QueryCache& query_cache); | 42 | QueryCache& query_cache); |
| 43 | 43 | ||
| 44 | protected: | 44 | protected: |
| 45 | Fence CreateFence(u32 value, bool is_stubbed) override; | 45 | Fence CreateFence(u32 value, bool is_stubbed) override; |
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp index d7ba57aca..2bb8ec2b8 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.cpp +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp | |||
| @@ -30,12 +30,13 @@ constexpr GLenum GetTarget(VideoCore::QueryType type) { | |||
| 30 | 30 | ||
| 31 | } // Anonymous namespace | 31 | } // Anonymous namespace |
| 32 | 32 | ||
| 33 | QueryCache::QueryCache(Core::System& system, RasterizerOpenGL& gl_rasterizer) | 33 | QueryCache::QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d, |
| 34 | Tegra::MemoryManager& gpu_memory) | ||
| 34 | : VideoCommon::QueryCacheBase< | 35 | : VideoCommon::QueryCacheBase< |
| 35 | QueryCache, CachedQuery, CounterStream, HostCounter, | 36 | QueryCache, CachedQuery, CounterStream, HostCounter, |
| 36 | std::vector<OGLQuery>>{system, | 37 | std::vector<OGLQuery>>{static_cast<VideoCore::RasterizerInterface&>(rasterizer), |
| 37 | static_cast<VideoCore::RasterizerInterface&>(gl_rasterizer)}, | 38 | maxwell3d, gpu_memory}, |
| 38 | gl_rasterizer{gl_rasterizer} {} | 39 | gl_rasterizer{rasterizer} {} |
| 39 | 40 | ||
| 40 | QueryCache::~QueryCache() = default; | 41 | QueryCache::~QueryCache() = default; |
| 41 | 42 | ||
diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h index d8e7052a1..dd626b66b 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.h +++ b/src/video_core/renderer_opengl/gl_query_cache.h | |||
| @@ -29,7 +29,8 @@ using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>; | |||
| 29 | class QueryCache final : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, | 29 | class QueryCache final : public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, |
| 30 | HostCounter, std::vector<OGLQuery>> { | 30 | HostCounter, std::vector<OGLQuery>> { |
| 31 | public: | 31 | public: |
| 32 | explicit QueryCache(Core::System& system, RasterizerOpenGL& rasterizer); | 32 | explicit QueryCache(RasterizerOpenGL& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d, |
| 33 | Tegra::MemoryManager& gpu_memory); | ||
| 33 | ~QueryCache(); | 34 | ~QueryCache(); |
| 34 | 35 | ||
| 35 | OGLQuery AllocateQuery(VideoCore::QueryType type); | 36 | OGLQuery AllocateQuery(VideoCore::QueryType type); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4af5824cd..bbb2eb17c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -153,16 +153,19 @@ void UpdateBindlessPointers(GLenum target, GLuint64EXT* pointers, std::size_t nu | |||
| 153 | 153 | ||
| 154 | } // Anonymous namespace | 154 | } // Anonymous namespace |
| 155 | 155 | ||
| 156 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 156 | RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_, |
| 157 | const Device& device, ScreenInfo& info, | 157 | Core::Memory::Memory& cpu_memory, const Device& device_, |
| 158 | ProgramManager& program_manager, StateTracker& state_tracker) | 158 | ScreenInfo& screen_info_, ProgramManager& program_manager_, |
| 159 | : RasterizerAccelerated{system.Memory()}, device{device}, texture_cache{system, *this, device, | 159 | StateTracker& state_tracker_) |
| 160 | state_tracker}, | 160 | : RasterizerAccelerated{cpu_memory}, gpu(gpu_), maxwell3d(gpu.Maxwell3D()), |
| 161 | shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, | 161 | kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_), |
| 162 | buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, | 162 | screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_), |
| 163 | fence_manager{system, *this, texture_cache, buffer_cache, query_cache}, system{system}, | 163 | texture_cache(*this, maxwell3d, gpu_memory, device, state_tracker), |
| 164 | screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, | 164 | shader_cache(*this, emu_window, gpu, maxwell3d, kepler_compute, gpu_memory, device), |
| 165 | async_shaders{emu_window} { | 165 | query_cache(*this, maxwell3d, gpu_memory), |
| 166 | buffer_cache(*this, gpu_memory, cpu_memory, device, STREAM_BUFFER_SIZE), | ||
| 167 | fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache), | ||
| 168 | async_shaders(emu_window) { | ||
| 166 | CheckExtensions(); | 169 | CheckExtensions(); |
| 167 | 170 | ||
| 168 | unified_uniform_buffer.Create(); | 171 | unified_uniform_buffer.Create(); |
| @@ -196,8 +199,7 @@ void RasterizerOpenGL::CheckExtensions() { | |||
| 196 | } | 199 | } |
| 197 | 200 | ||
| 198 | void RasterizerOpenGL::SetupVertexFormat() { | 201 | void RasterizerOpenGL::SetupVertexFormat() { |
| 199 | auto& gpu = system.GPU().Maxwell3D(); | 202 | auto& flags = maxwell3d.dirty.flags; |
| 200 | auto& flags = gpu.dirty.flags; | ||
| 201 | if (!flags[Dirty::VertexFormats]) { | 203 | if (!flags[Dirty::VertexFormats]) { |
| 202 | return; | 204 | return; |
| 203 | } | 205 | } |
| @@ -217,7 +219,7 @@ void RasterizerOpenGL::SetupVertexFormat() { | |||
| 217 | } | 219 | } |
| 218 | flags[Dirty::VertexFormat0 + index] = false; | 220 | flags[Dirty::VertexFormat0 + index] = false; |
| 219 | 221 | ||
| 220 | const auto attrib = gpu.regs.vertex_attrib_format[index]; | 222 | const auto attrib = maxwell3d.regs.vertex_attrib_format[index]; |
| 221 | const auto gl_index = static_cast<GLuint>(index); | 223 | const auto gl_index = static_cast<GLuint>(index); |
| 222 | 224 | ||
| 223 | // Disable constant attributes. | 225 | // Disable constant attributes. |
| @@ -241,8 +243,7 @@ void RasterizerOpenGL::SetupVertexFormat() { | |||
| 241 | } | 243 | } |
| 242 | 244 | ||
| 243 | void RasterizerOpenGL::SetupVertexBuffer() { | 245 | void RasterizerOpenGL::SetupVertexBuffer() { |
| 244 | auto& gpu = system.GPU().Maxwell3D(); | 246 | auto& flags = maxwell3d.dirty.flags; |
| 245 | auto& flags = gpu.dirty.flags; | ||
| 246 | if (!flags[Dirty::VertexBuffers]) { | 247 | if (!flags[Dirty::VertexBuffers]) { |
| 247 | return; | 248 | return; |
| 248 | } | 249 | } |
| @@ -253,7 +254,7 @@ void RasterizerOpenGL::SetupVertexBuffer() { | |||
| 253 | const bool use_unified_memory = device.HasVertexBufferUnifiedMemory(); | 254 | const bool use_unified_memory = device.HasVertexBufferUnifiedMemory(); |
| 254 | 255 | ||
| 255 | // Upload all guest vertex arrays sequentially to our buffer | 256 | // Upload all guest vertex arrays sequentially to our buffer |
| 256 | const auto& regs = gpu.regs; | 257 | const auto& regs = maxwell3d.regs; |
| 257 | for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) { | 258 | for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_BINDINGS; ++index) { |
| 258 | if (!flags[Dirty::VertexBuffer0 + index]) { | 259 | if (!flags[Dirty::VertexBuffer0 + index]) { |
| 259 | continue; | 260 | continue; |
| @@ -290,14 +291,13 @@ void RasterizerOpenGL::SetupVertexBuffer() { | |||
| 290 | } | 291 | } |
| 291 | 292 | ||
| 292 | void RasterizerOpenGL::SetupVertexInstances() { | 293 | void RasterizerOpenGL::SetupVertexInstances() { |
| 293 | auto& gpu = system.GPU().Maxwell3D(); | 294 | auto& flags = maxwell3d.dirty.flags; |
| 294 | auto& flags = gpu.dirty.flags; | ||
| 295 | if (!flags[Dirty::VertexInstances]) { | 295 | if (!flags[Dirty::VertexInstances]) { |
| 296 | return; | 296 | return; |
| 297 | } | 297 | } |
| 298 | flags[Dirty::VertexInstances] = false; | 298 | flags[Dirty::VertexInstances] = false; |
| 299 | 299 | ||
| 300 | const auto& regs = gpu.regs; | 300 | const auto& regs = maxwell3d.regs; |
| 301 | for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) { | 301 | for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) { |
| 302 | if (!flags[Dirty::VertexInstance0 + index]) { | 302 | if (!flags[Dirty::VertexInstance0 + index]) { |
| 303 | continue; | 303 | continue; |
| @@ -313,7 +313,7 @@ void RasterizerOpenGL::SetupVertexInstances() { | |||
| 313 | 313 | ||
| 314 | GLintptr RasterizerOpenGL::SetupIndexBuffer() { | 314 | GLintptr RasterizerOpenGL::SetupIndexBuffer() { |
| 315 | MICROPROFILE_SCOPE(OpenGL_Index); | 315 | MICROPROFILE_SCOPE(OpenGL_Index); |
| 316 | const auto& regs = system.GPU().Maxwell3D().regs; | 316 | const auto& regs = maxwell3d.regs; |
| 317 | const std::size_t size = CalculateIndexBufferSize(); | 317 | const std::size_t size = CalculateIndexBufferSize(); |
| 318 | const auto info = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); | 318 | const auto info = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); |
| 319 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, info.handle); | 319 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, info.handle); |
| @@ -322,15 +322,14 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() { | |||
| 322 | 322 | ||
| 323 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | 323 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { |
| 324 | MICROPROFILE_SCOPE(OpenGL_Shader); | 324 | MICROPROFILE_SCOPE(OpenGL_Shader); |
| 325 | auto& gpu = system.GPU().Maxwell3D(); | ||
| 326 | u32 clip_distances = 0; | 325 | u32 clip_distances = 0; |
| 327 | 326 | ||
| 328 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 327 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| 329 | const auto& shader_config = gpu.regs.shader_config[index]; | 328 | const auto& shader_config = maxwell3d.regs.shader_config[index]; |
| 330 | const auto program{static_cast<Maxwell::ShaderProgram>(index)}; | 329 | const auto program{static_cast<Maxwell::ShaderProgram>(index)}; |
| 331 | 330 | ||
| 332 | // Skip stages that are not enabled | 331 | // Skip stages that are not enabled |
| 333 | if (!gpu.regs.IsShaderConfigEnabled(index)) { | 332 | if (!maxwell3d.regs.IsShaderConfigEnabled(index)) { |
| 334 | switch (program) { | 333 | switch (program) { |
| 335 | case Maxwell::ShaderProgram::Geometry: | 334 | case Maxwell::ShaderProgram::Geometry: |
| 336 | program_manager.UseGeometryShader(0); | 335 | program_manager.UseGeometryShader(0); |
| @@ -391,11 +390,11 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 391 | } | 390 | } |
| 392 | 391 | ||
| 393 | SyncClipEnabled(clip_distances); | 392 | SyncClipEnabled(clip_distances); |
| 394 | gpu.dirty.flags[Dirty::Shaders] = false; | 393 | maxwell3d.dirty.flags[Dirty::Shaders] = false; |
| 395 | } | 394 | } |
| 396 | 395 | ||
| 397 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 396 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { |
| 398 | const auto& regs = system.GPU().Maxwell3D().regs; | 397 | const auto& regs = maxwell3d.regs; |
| 399 | 398 | ||
| 400 | std::size_t size = 0; | 399 | std::size_t size = 0; |
| 401 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | 400 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| @@ -413,34 +412,27 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | |||
| 413 | } | 412 | } |
| 414 | 413 | ||
| 415 | std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const { | 414 | std::size_t RasterizerOpenGL::CalculateIndexBufferSize() const { |
| 416 | const auto& regs = system.GPU().Maxwell3D().regs; | 415 | return static_cast<std::size_t>(maxwell3d.regs.index_array.count) * |
| 417 | 416 | static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes()); | |
| 418 | return static_cast<std::size_t>(regs.index_array.count) * | ||
| 419 | static_cast<std::size_t>(regs.index_array.FormatSizeInBytes()); | ||
| 420 | } | 417 | } |
| 421 | 418 | ||
| 422 | void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, | 419 | void RasterizerOpenGL::LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading, |
| 423 | const VideoCore::DiskResourceLoadCallback& callback) { | 420 | const VideoCore::DiskResourceLoadCallback& callback) { |
| 424 | shader_cache.LoadDiskCache(stop_loading, callback); | 421 | shader_cache.LoadDiskCache(title_id, stop_loading, callback); |
| 425 | } | ||
| 426 | |||
| 427 | void RasterizerOpenGL::SetupDirtyFlags() { | ||
| 428 | state_tracker.Initialize(); | ||
| 429 | } | 422 | } |
| 430 | 423 | ||
| 431 | void RasterizerOpenGL::ConfigureFramebuffers() { | 424 | void RasterizerOpenGL::ConfigureFramebuffers() { |
| 432 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); | 425 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); |
| 433 | auto& gpu = system.GPU().Maxwell3D(); | 426 | if (!maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets]) { |
| 434 | if (!gpu.dirty.flags[VideoCommon::Dirty::RenderTargets]) { | ||
| 435 | return; | 427 | return; |
| 436 | } | 428 | } |
| 437 | gpu.dirty.flags[VideoCommon::Dirty::RenderTargets] = false; | 429 | maxwell3d.dirty.flags[VideoCommon::Dirty::RenderTargets] = false; |
| 438 | 430 | ||
| 439 | texture_cache.GuardRenderTargets(true); | 431 | texture_cache.GuardRenderTargets(true); |
| 440 | 432 | ||
| 441 | View depth_surface = texture_cache.GetDepthBufferSurface(true); | 433 | View depth_surface = texture_cache.GetDepthBufferSurface(true); |
| 442 | 434 | ||
| 443 | const auto& regs = gpu.regs; | 435 | const auto& regs = maxwell3d.regs; |
| 444 | UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); | 436 | UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); |
| 445 | 437 | ||
| 446 | // Bind the framebuffer surfaces | 438 | // Bind the framebuffer surfaces |
| @@ -472,8 +464,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() { | |||
| 472 | } | 464 | } |
| 473 | 465 | ||
| 474 | void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil) { | 466 | void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_depth_stencil) { |
| 475 | auto& gpu = system.GPU().Maxwell3D(); | 467 | const auto& regs = maxwell3d.regs; |
| 476 | const auto& regs = gpu.regs; | ||
| 477 | 468 | ||
| 478 | texture_cache.GuardRenderTargets(true); | 469 | texture_cache.GuardRenderTargets(true); |
| 479 | View color_surface; | 470 | View color_surface; |
| @@ -523,12 +514,11 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color, bool using_de | |||
| 523 | } | 514 | } |
| 524 | 515 | ||
| 525 | void RasterizerOpenGL::Clear() { | 516 | void RasterizerOpenGL::Clear() { |
| 526 | const auto& gpu = system.GPU().Maxwell3D(); | 517 | if (!maxwell3d.ShouldExecute()) { |
| 527 | if (!gpu.ShouldExecute()) { | ||
| 528 | return; | 518 | return; |
| 529 | } | 519 | } |
| 530 | 520 | ||
| 531 | const auto& regs = gpu.regs; | 521 | const auto& regs = maxwell3d.regs; |
| 532 | bool use_color{}; | 522 | bool use_color{}; |
| 533 | bool use_depth{}; | 523 | bool use_depth{}; |
| 534 | bool use_stencil{}; | 524 | bool use_stencil{}; |
| @@ -593,7 +583,6 @@ void RasterizerOpenGL::Clear() { | |||
| 593 | 583 | ||
| 594 | void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | 584 | void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { |
| 595 | MICROPROFILE_SCOPE(OpenGL_Drawing); | 585 | MICROPROFILE_SCOPE(OpenGL_Drawing); |
| 596 | auto& gpu = system.GPU().Maxwell3D(); | ||
| 597 | 586 | ||
| 598 | query_cache.UpdateCounters(); | 587 | query_cache.UpdateCounters(); |
| 599 | 588 | ||
| @@ -641,7 +630,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 641 | 630 | ||
| 642 | if (invalidated) { | 631 | if (invalidated) { |
| 643 | // When the stream buffer has been invalidated, we have to consider vertex buffers as dirty | 632 | // When the stream buffer has been invalidated, we have to consider vertex buffers as dirty |
| 644 | auto& dirty = gpu.dirty.flags; | 633 | auto& dirty = maxwell3d.dirty.flags; |
| 645 | dirty[Dirty::VertexBuffers] = true; | 634 | dirty[Dirty::VertexBuffers] = true; |
| 646 | for (int index = Dirty::VertexBuffer0; index <= Dirty::VertexBuffer31; ++index) { | 635 | for (int index = Dirty::VertexBuffer0; index <= Dirty::VertexBuffer31; ++index) { |
| 647 | dirty[index] = true; | 636 | dirty[index] = true; |
| @@ -662,7 +651,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 662 | // Setup emulation uniform buffer. | 651 | // Setup emulation uniform buffer. |
| 663 | if (!device.UseAssemblyShaders()) { | 652 | if (!device.UseAssemblyShaders()) { |
| 664 | MaxwellUniformData ubo; | 653 | MaxwellUniformData ubo; |
| 665 | ubo.SetFromRegs(gpu); | 654 | ubo.SetFromRegs(maxwell3d); |
| 666 | const auto info = | 655 | const auto info = |
| 667 | buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); | 656 | buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); |
| 668 | glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, info.handle, info.offset, | 657 | glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, info.handle, info.offset, |
| @@ -671,7 +660,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 671 | 660 | ||
| 672 | // Setup shaders and their used resources. | 661 | // Setup shaders and their used resources. |
| 673 | texture_cache.GuardSamplers(true); | 662 | texture_cache.GuardSamplers(true); |
| 674 | const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(gpu.regs.draw.topology); | 663 | const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology); |
| 675 | SetupShaders(primitive_mode); | 664 | SetupShaders(primitive_mode); |
| 676 | texture_cache.GuardSamplers(false); | 665 | texture_cache.GuardSamplers(false); |
| 677 | 666 | ||
| @@ -688,14 +677,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 688 | 677 | ||
| 689 | BeginTransformFeedback(primitive_mode); | 678 | BeginTransformFeedback(primitive_mode); |
| 690 | 679 | ||
| 691 | const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance); | 680 | const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance); |
| 692 | const GLsizei num_instances = | 681 | const GLsizei num_instances = |
| 693 | static_cast<GLsizei>(is_instanced ? gpu.mme_draw.instance_count : 1); | 682 | static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1); |
| 694 | if (is_indexed) { | 683 | if (is_indexed) { |
| 695 | const GLint base_vertex = static_cast<GLint>(gpu.regs.vb_element_base); | 684 | const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base); |
| 696 | const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.index_array.count); | 685 | const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count); |
| 697 | const GLvoid* offset = reinterpret_cast<const GLvoid*>(index_buffer_offset); | 686 | const GLvoid* offset = reinterpret_cast<const GLvoid*>(index_buffer_offset); |
| 698 | const GLenum format = MaxwellToGL::IndexFormat(gpu.regs.index_array.format); | 687 | const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format); |
| 699 | if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { | 688 | if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { |
| 700 | glDrawElements(primitive_mode, num_vertices, format, offset); | 689 | glDrawElements(primitive_mode, num_vertices, format, offset); |
| 701 | } else if (num_instances == 1 && base_instance == 0) { | 690 | } else if (num_instances == 1 && base_instance == 0) { |
| @@ -714,8 +703,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 714 | base_instance); | 703 | base_instance); |
| 715 | } | 704 | } |
| 716 | } else { | 705 | } else { |
| 717 | const GLint base_vertex = static_cast<GLint>(gpu.regs.vertex_buffer.first); | 706 | const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first); |
| 718 | const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.vertex_buffer.count); | 707 | const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count); |
| 719 | if (num_instances == 1 && base_instance == 0) { | 708 | if (num_instances == 1 && base_instance == 0) { |
| 720 | glDrawArrays(primitive_mode, base_vertex, num_vertices); | 709 | glDrawArrays(primitive_mode, base_vertex, num_vertices); |
| 721 | } else if (base_instance == 0) { | 710 | } else if (base_instance == 0) { |
| @@ -730,7 +719,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 730 | 719 | ||
| 731 | ++num_queued_commands; | 720 | ++num_queued_commands; |
| 732 | 721 | ||
| 733 | system.GPU().TickWork(); | 722 | gpu.TickWork(); |
| 734 | } | 723 | } |
| 735 | 724 | ||
| 736 | void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | 725 | void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { |
| @@ -753,7 +742,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { | |||
| 753 | 742 | ||
| 754 | buffer_cache.Unmap(); | 743 | buffer_cache.Unmap(); |
| 755 | 744 | ||
| 756 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 745 | const auto& launch_desc = kepler_compute.launch_description; |
| 746 | program_manager.BindCompute(kernel->GetHandle()); | ||
| 757 | glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); | 747 | glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); |
| 758 | ++num_queued_commands; | 748 | ++num_queued_commands; |
| 759 | } | 749 | } |
| @@ -815,17 +805,14 @@ void RasterizerOpenGL::SyncGuestHost() { | |||
| 815 | } | 805 | } |
| 816 | 806 | ||
| 817 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { | 807 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { |
| 818 | auto& gpu{system.GPU()}; | ||
| 819 | if (!gpu.IsAsync()) { | 808 | if (!gpu.IsAsync()) { |
| 820 | auto& memory_manager{gpu.MemoryManager()}; | 809 | gpu_memory.Write<u32>(addr, value); |
| 821 | memory_manager.Write<u32>(addr, value); | ||
| 822 | return; | 810 | return; |
| 823 | } | 811 | } |
| 824 | fence_manager.SignalSemaphore(addr, value); | 812 | fence_manager.SignalSemaphore(addr, value); |
| 825 | } | 813 | } |
| 826 | 814 | ||
| 827 | void RasterizerOpenGL::SignalSyncPoint(u32 value) { | 815 | void RasterizerOpenGL::SignalSyncPoint(u32 value) { |
| 828 | auto& gpu{system.GPU()}; | ||
| 829 | if (!gpu.IsAsync()) { | 816 | if (!gpu.IsAsync()) { |
| 830 | gpu.IncrementSyncPoint(value); | 817 | gpu.IncrementSyncPoint(value); |
| 831 | return; | 818 | return; |
| @@ -834,7 +821,6 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) { | |||
| 834 | } | 821 | } |
| 835 | 822 | ||
| 836 | void RasterizerOpenGL::ReleaseFences() { | 823 | void RasterizerOpenGL::ReleaseFences() { |
| 837 | auto& gpu{system.GPU()}; | ||
| 838 | if (!gpu.IsAsync()) { | 824 | if (!gpu.IsAsync()) { |
| 839 | return; | 825 | return; |
| 840 | } | 826 | } |
| @@ -920,7 +906,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh | |||
| 920 | GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV}; | 906 | GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV}; |
| 921 | 907 | ||
| 922 | MICROPROFILE_SCOPE(OpenGL_UBO); | 908 | MICROPROFILE_SCOPE(OpenGL_UBO); |
| 923 | const auto& stages = system.GPU().Maxwell3D().state.shader_stages; | 909 | const auto& stages = maxwell3d.state.shader_stages; |
| 924 | const auto& shader_stage = stages[stage_index]; | 910 | const auto& shader_stage = stages[stage_index]; |
| 925 | const auto& entries = shader->GetEntries(); | 911 | const auto& entries = shader->GetEntries(); |
| 926 | const bool use_unified = entries.use_unified_uniforms; | 912 | const bool use_unified = entries.use_unified_uniforms; |
| @@ -945,7 +931,7 @@ void RasterizerOpenGL::SetupDrawConstBuffers(std::size_t stage_index, Shader* sh | |||
| 945 | 931 | ||
| 946 | void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) { | 932 | void RasterizerOpenGL::SetupComputeConstBuffers(Shader* kernel) { |
| 947 | MICROPROFILE_SCOPE(OpenGL_UBO); | 933 | MICROPROFILE_SCOPE(OpenGL_UBO); |
| 948 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 934 | const auto& launch_desc = kepler_compute.launch_description; |
| 949 | const auto& entries = kernel->GetEntries(); | 935 | const auto& entries = kernel->GetEntries(); |
| 950 | const bool use_unified = entries.use_unified_uniforms; | 936 | const bool use_unified = entries.use_unified_uniforms; |
| 951 | 937 | ||
| @@ -1018,9 +1004,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh | |||
| 1018 | GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV, | 1004 | GL_GEOMETRY_PROGRAM_NV, GL_FRAGMENT_PROGRAM_NV, |
| 1019 | }; | 1005 | }; |
| 1020 | 1006 | ||
| 1021 | auto& gpu{system.GPU()}; | 1007 | const auto& cbufs{maxwell3d.state.shader_stages[stage_index]}; |
| 1022 | auto& memory_manager{gpu.MemoryManager()}; | ||
| 1023 | const auto& cbufs{gpu.Maxwell3D().state.shader_stages[stage_index]}; | ||
| 1024 | const auto& entries{shader->GetEntries().global_memory_entries}; | 1008 | const auto& entries{shader->GetEntries().global_memory_entries}; |
| 1025 | 1009 | ||
| 1026 | std::array<GLuint64EXT, 32> pointers; | 1010 | std::array<GLuint64EXT, 32> pointers; |
| @@ -1030,8 +1014,8 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh | |||
| 1030 | u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; | 1014 | u32 binding = assembly_shaders ? 0 : device.GetBaseBindings(stage_index).shader_storage_buffer; |
| 1031 | for (const auto& entry : entries) { | 1015 | for (const auto& entry : entries) { |
| 1032 | const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; | 1016 | const GPUVAddr addr{cbufs.const_buffers[entry.cbuf_index].address + entry.cbuf_offset}; |
| 1033 | const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; | 1017 | const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)}; |
| 1034 | const u32 size{memory_manager.Read<u32>(addr + 8)}; | 1018 | const u32 size{gpu_memory.Read<u32>(addr + 8)}; |
| 1035 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); | 1019 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); |
| 1036 | ++binding; | 1020 | ++binding; |
| 1037 | } | 1021 | } |
| @@ -1041,9 +1025,7 @@ void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, Shader* sh | |||
| 1041 | } | 1025 | } |
| 1042 | 1026 | ||
| 1043 | void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { | 1027 | void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { |
| 1044 | auto& gpu{system.GPU()}; | 1028 | const auto& cbufs{kepler_compute.launch_description.const_buffer_config}; |
| 1045 | auto& memory_manager{gpu.MemoryManager()}; | ||
| 1046 | const auto& cbufs{gpu.KeplerCompute().launch_description.const_buffer_config}; | ||
| 1047 | const auto& entries{kernel->GetEntries().global_memory_entries}; | 1029 | const auto& entries{kernel->GetEntries().global_memory_entries}; |
| 1048 | 1030 | ||
| 1049 | std::array<GLuint64EXT, 32> pointers; | 1031 | std::array<GLuint64EXT, 32> pointers; |
| @@ -1052,8 +1034,8 @@ void RasterizerOpenGL::SetupComputeGlobalMemory(Shader* kernel) { | |||
| 1052 | u32 binding = 0; | 1034 | u32 binding = 0; |
| 1053 | for (const auto& entry : entries) { | 1035 | for (const auto& entry : entries) { |
| 1054 | const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; | 1036 | const GPUVAddr addr{cbufs[entry.cbuf_index].Address() + entry.cbuf_offset}; |
| 1055 | const GPUVAddr gpu_addr{memory_manager.Read<u64>(addr)}; | 1037 | const GPUVAddr gpu_addr{gpu_memory.Read<u64>(addr)}; |
| 1056 | const u32 size{memory_manager.Read<u32>(addr + 8)}; | 1038 | const u32 size{gpu_memory.Read<u32>(addr + 8)}; |
| 1057 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); | 1039 | SetupGlobalMemory(binding, entry, gpu_addr, size, &pointers[binding]); |
| 1058 | ++binding; | 1040 | ++binding; |
| 1059 | } | 1041 | } |
| @@ -1077,7 +1059,6 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e | |||
| 1077 | 1059 | ||
| 1078 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { | 1060 | void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader) { |
| 1079 | MICROPROFILE_SCOPE(OpenGL_Texture); | 1061 | MICROPROFILE_SCOPE(OpenGL_Texture); |
| 1080 | const auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 1081 | u32 binding = device.GetBaseBindings(stage_index).sampler; | 1062 | u32 binding = device.GetBaseBindings(stage_index).sampler; |
| 1082 | for (const auto& entry : shader->GetEntries().samplers) { | 1063 | for (const auto& entry : shader->GetEntries().samplers) { |
| 1083 | const auto shader_type = static_cast<ShaderType>(stage_index); | 1064 | const auto shader_type = static_cast<ShaderType>(stage_index); |
| @@ -1090,11 +1071,10 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, Shader* shader | |||
| 1090 | 1071 | ||
| 1091 | void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) { | 1072 | void RasterizerOpenGL::SetupComputeTextures(Shader* kernel) { |
| 1092 | MICROPROFILE_SCOPE(OpenGL_Texture); | 1073 | MICROPROFILE_SCOPE(OpenGL_Texture); |
| 1093 | const auto& compute = system.GPU().KeplerCompute(); | ||
| 1094 | u32 binding = 0; | 1074 | u32 binding = 0; |
| 1095 | for (const auto& entry : kernel->GetEntries().samplers) { | 1075 | for (const auto& entry : kernel->GetEntries().samplers) { |
| 1096 | for (std::size_t i = 0; i < entry.size; ++i) { | 1076 | for (std::size_t i = 0; i < entry.size; ++i) { |
| 1097 | const auto texture = GetTextureInfo(compute, entry, ShaderType::Compute, i); | 1077 | const auto texture = GetTextureInfo(kepler_compute, entry, ShaderType::Compute, i); |
| 1098 | SetupTexture(binding++, texture, entry); | 1078 | SetupTexture(binding++, texture, entry); |
| 1099 | } | 1079 | } |
| 1100 | } | 1080 | } |
| @@ -1118,20 +1098,18 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu | |||
| 1118 | } | 1098 | } |
| 1119 | 1099 | ||
| 1120 | void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) { | 1100 | void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, Shader* shader) { |
| 1121 | const auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 1122 | u32 binding = device.GetBaseBindings(stage_index).image; | 1101 | u32 binding = device.GetBaseBindings(stage_index).image; |
| 1123 | for (const auto& entry : shader->GetEntries().images) { | 1102 | for (const auto& entry : shader->GetEntries().images) { |
| 1124 | const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index); | 1103 | const auto shader_type = static_cast<ShaderType>(stage_index); |
| 1125 | const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic; | 1104 | const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic; |
| 1126 | SetupImage(binding++, tic, entry); | 1105 | SetupImage(binding++, tic, entry); |
| 1127 | } | 1106 | } |
| 1128 | } | 1107 | } |
| 1129 | 1108 | ||
| 1130 | void RasterizerOpenGL::SetupComputeImages(Shader* shader) { | 1109 | void RasterizerOpenGL::SetupComputeImages(Shader* shader) { |
| 1131 | const auto& compute = system.GPU().KeplerCompute(); | ||
| 1132 | u32 binding = 0; | 1110 | u32 binding = 0; |
| 1133 | for (const auto& entry : shader->GetEntries().images) { | 1111 | for (const auto& entry : shader->GetEntries().images) { |
| 1134 | const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic; | 1112 | const auto tic = GetTextureInfo(kepler_compute, entry, ShaderType::Compute).tic; |
| 1135 | SetupImage(binding++, tic, entry); | 1113 | SetupImage(binding++, tic, entry); |
| 1136 | } | 1114 | } |
| 1137 | } | 1115 | } |
| @@ -1151,9 +1129,8 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t | |||
| 1151 | } | 1129 | } |
| 1152 | 1130 | ||
| 1153 | void RasterizerOpenGL::SyncViewport() { | 1131 | void RasterizerOpenGL::SyncViewport() { |
| 1154 | auto& gpu = system.GPU().Maxwell3D(); | 1132 | auto& flags = maxwell3d.dirty.flags; |
| 1155 | auto& flags = gpu.dirty.flags; | 1133 | const auto& regs = maxwell3d.regs; |
| 1156 | const auto& regs = gpu.regs; | ||
| 1157 | 1134 | ||
| 1158 | const bool dirty_viewport = flags[Dirty::Viewports]; | 1135 | const bool dirty_viewport = flags[Dirty::Viewports]; |
| 1159 | const bool dirty_clip_control = flags[Dirty::ClipControl]; | 1136 | const bool dirty_clip_control = flags[Dirty::ClipControl]; |
| @@ -1225,25 +1202,23 @@ void RasterizerOpenGL::SyncViewport() { | |||
| 1225 | } | 1202 | } |
| 1226 | 1203 | ||
| 1227 | void RasterizerOpenGL::SyncDepthClamp() { | 1204 | void RasterizerOpenGL::SyncDepthClamp() { |
| 1228 | auto& gpu = system.GPU().Maxwell3D(); | 1205 | auto& flags = maxwell3d.dirty.flags; |
| 1229 | auto& flags = gpu.dirty.flags; | ||
| 1230 | if (!flags[Dirty::DepthClampEnabled]) { | 1206 | if (!flags[Dirty::DepthClampEnabled]) { |
| 1231 | return; | 1207 | return; |
| 1232 | } | 1208 | } |
| 1233 | flags[Dirty::DepthClampEnabled] = false; | 1209 | flags[Dirty::DepthClampEnabled] = false; |
| 1234 | 1210 | ||
| 1235 | oglEnable(GL_DEPTH_CLAMP, gpu.regs.view_volume_clip_control.depth_clamp_disabled == 0); | 1211 | oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0); |
| 1236 | } | 1212 | } |
| 1237 | 1213 | ||
| 1238 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { | 1214 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { |
| 1239 | auto& gpu = system.GPU().Maxwell3D(); | 1215 | auto& flags = maxwell3d.dirty.flags; |
| 1240 | auto& flags = gpu.dirty.flags; | ||
| 1241 | if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) { | 1216 | if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) { |
| 1242 | return; | 1217 | return; |
| 1243 | } | 1218 | } |
| 1244 | flags[Dirty::ClipDistances] = false; | 1219 | flags[Dirty::ClipDistances] = false; |
| 1245 | 1220 | ||
| 1246 | clip_mask &= gpu.regs.clip_distance_enabled; | 1221 | clip_mask &= maxwell3d.regs.clip_distance_enabled; |
| 1247 | if (clip_mask == last_clip_distance_mask) { | 1222 | if (clip_mask == last_clip_distance_mask) { |
| 1248 | return; | 1223 | return; |
| 1249 | } | 1224 | } |
| @@ -1259,9 +1234,8 @@ void RasterizerOpenGL::SyncClipCoef() { | |||
| 1259 | } | 1234 | } |
| 1260 | 1235 | ||
| 1261 | void RasterizerOpenGL::SyncCullMode() { | 1236 | void RasterizerOpenGL::SyncCullMode() { |
| 1262 | auto& gpu = system.GPU().Maxwell3D(); | 1237 | auto& flags = maxwell3d.dirty.flags; |
| 1263 | auto& flags = gpu.dirty.flags; | 1238 | const auto& regs = maxwell3d.regs; |
| 1264 | const auto& regs = gpu.regs; | ||
| 1265 | 1239 | ||
| 1266 | if (flags[Dirty::CullTest]) { | 1240 | if (flags[Dirty::CullTest]) { |
| 1267 | flags[Dirty::CullTest] = false; | 1241 | flags[Dirty::CullTest] = false; |
| @@ -1276,26 +1250,24 @@ void RasterizerOpenGL::SyncCullMode() { | |||
| 1276 | } | 1250 | } |
| 1277 | 1251 | ||
| 1278 | void RasterizerOpenGL::SyncPrimitiveRestart() { | 1252 | void RasterizerOpenGL::SyncPrimitiveRestart() { |
| 1279 | auto& gpu = system.GPU().Maxwell3D(); | 1253 | auto& flags = maxwell3d.dirty.flags; |
| 1280 | auto& flags = gpu.dirty.flags; | ||
| 1281 | if (!flags[Dirty::PrimitiveRestart]) { | 1254 | if (!flags[Dirty::PrimitiveRestart]) { |
| 1282 | return; | 1255 | return; |
| 1283 | } | 1256 | } |
| 1284 | flags[Dirty::PrimitiveRestart] = false; | 1257 | flags[Dirty::PrimitiveRestart] = false; |
| 1285 | 1258 | ||
| 1286 | if (gpu.regs.primitive_restart.enabled) { | 1259 | if (maxwell3d.regs.primitive_restart.enabled) { |
| 1287 | glEnable(GL_PRIMITIVE_RESTART); | 1260 | glEnable(GL_PRIMITIVE_RESTART); |
| 1288 | glPrimitiveRestartIndex(gpu.regs.primitive_restart.index); | 1261 | glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index); |
| 1289 | } else { | 1262 | } else { |
| 1290 | glDisable(GL_PRIMITIVE_RESTART); | 1263 | glDisable(GL_PRIMITIVE_RESTART); |
| 1291 | } | 1264 | } |
| 1292 | } | 1265 | } |
| 1293 | 1266 | ||
| 1294 | void RasterizerOpenGL::SyncDepthTestState() { | 1267 | void RasterizerOpenGL::SyncDepthTestState() { |
| 1295 | auto& gpu = system.GPU().Maxwell3D(); | 1268 | auto& flags = maxwell3d.dirty.flags; |
| 1296 | auto& flags = gpu.dirty.flags; | 1269 | const auto& regs = maxwell3d.regs; |
| 1297 | 1270 | ||
| 1298 | const auto& regs = gpu.regs; | ||
| 1299 | if (flags[Dirty::DepthMask]) { | 1271 | if (flags[Dirty::DepthMask]) { |
| 1300 | flags[Dirty::DepthMask] = false; | 1272 | flags[Dirty::DepthMask] = false; |
| 1301 | glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); | 1273 | glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); |
| @@ -1313,14 +1285,13 @@ void RasterizerOpenGL::SyncDepthTestState() { | |||
| 1313 | } | 1285 | } |
| 1314 | 1286 | ||
| 1315 | void RasterizerOpenGL::SyncStencilTestState() { | 1287 | void RasterizerOpenGL::SyncStencilTestState() { |
| 1316 | auto& gpu = system.GPU().Maxwell3D(); | 1288 | auto& flags = maxwell3d.dirty.flags; |
| 1317 | auto& flags = gpu.dirty.flags; | ||
| 1318 | if (!flags[Dirty::StencilTest]) { | 1289 | if (!flags[Dirty::StencilTest]) { |
| 1319 | return; | 1290 | return; |
| 1320 | } | 1291 | } |
| 1321 | flags[Dirty::StencilTest] = false; | 1292 | flags[Dirty::StencilTest] = false; |
| 1322 | 1293 | ||
| 1323 | const auto& regs = gpu.regs; | 1294 | const auto& regs = maxwell3d.regs; |
| 1324 | oglEnable(GL_STENCIL_TEST, regs.stencil_enable); | 1295 | oglEnable(GL_STENCIL_TEST, regs.stencil_enable); |
| 1325 | 1296 | ||
| 1326 | glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), | 1297 | glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), |
| @@ -1345,25 +1316,24 @@ void RasterizerOpenGL::SyncStencilTestState() { | |||
| 1345 | } | 1316 | } |
| 1346 | 1317 | ||
| 1347 | void RasterizerOpenGL::SyncRasterizeEnable() { | 1318 | void RasterizerOpenGL::SyncRasterizeEnable() { |
| 1348 | auto& gpu = system.GPU().Maxwell3D(); | 1319 | auto& flags = maxwell3d.dirty.flags; |
| 1349 | auto& flags = gpu.dirty.flags; | ||
| 1350 | if (!flags[Dirty::RasterizeEnable]) { | 1320 | if (!flags[Dirty::RasterizeEnable]) { |
| 1351 | return; | 1321 | return; |
| 1352 | } | 1322 | } |
| 1353 | flags[Dirty::RasterizeEnable] = false; | 1323 | flags[Dirty::RasterizeEnable] = false; |
| 1354 | 1324 | ||
| 1355 | oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); | 1325 | oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0); |
| 1356 | } | 1326 | } |
| 1357 | 1327 | ||
| 1358 | void RasterizerOpenGL::SyncPolygonModes() { | 1328 | void RasterizerOpenGL::SyncPolygonModes() { |
| 1359 | auto& gpu = system.GPU().Maxwell3D(); | 1329 | auto& flags = maxwell3d.dirty.flags; |
| 1360 | auto& flags = gpu.dirty.flags; | ||
| 1361 | if (!flags[Dirty::PolygonModes]) { | 1330 | if (!flags[Dirty::PolygonModes]) { |
| 1362 | return; | 1331 | return; |
| 1363 | } | 1332 | } |
| 1364 | flags[Dirty::PolygonModes] = false; | 1333 | flags[Dirty::PolygonModes] = false; |
| 1365 | 1334 | ||
| 1366 | if (gpu.regs.fill_rectangle) { | 1335 | const auto& regs = maxwell3d.regs; |
| 1336 | if (regs.fill_rectangle) { | ||
| 1367 | if (!GLAD_GL_NV_fill_rectangle) { | 1337 | if (!GLAD_GL_NV_fill_rectangle) { |
| 1368 | LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); | 1338 | LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); |
| 1369 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 1339 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
| @@ -1376,27 +1346,26 @@ void RasterizerOpenGL::SyncPolygonModes() { | |||
| 1376 | return; | 1346 | return; |
| 1377 | } | 1347 | } |
| 1378 | 1348 | ||
| 1379 | if (gpu.regs.polygon_mode_front == gpu.regs.polygon_mode_back) { | 1349 | if (regs.polygon_mode_front == regs.polygon_mode_back) { |
| 1380 | flags[Dirty::PolygonModeFront] = false; | 1350 | flags[Dirty::PolygonModeFront] = false; |
| 1381 | flags[Dirty::PolygonModeBack] = false; | 1351 | flags[Dirty::PolygonModeBack] = false; |
| 1382 | glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); | 1352 | glPolygonMode(GL_FRONT_AND_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_front)); |
| 1383 | return; | 1353 | return; |
| 1384 | } | 1354 | } |
| 1385 | 1355 | ||
| 1386 | if (flags[Dirty::PolygonModeFront]) { | 1356 | if (flags[Dirty::PolygonModeFront]) { |
| 1387 | flags[Dirty::PolygonModeFront] = false; | 1357 | flags[Dirty::PolygonModeFront] = false; |
| 1388 | glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_front)); | 1358 | glPolygonMode(GL_FRONT, MaxwellToGL::PolygonMode(regs.polygon_mode_front)); |
| 1389 | } | 1359 | } |
| 1390 | 1360 | ||
| 1391 | if (flags[Dirty::PolygonModeBack]) { | 1361 | if (flags[Dirty::PolygonModeBack]) { |
| 1392 | flags[Dirty::PolygonModeBack] = false; | 1362 | flags[Dirty::PolygonModeBack] = false; |
| 1393 | glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(gpu.regs.polygon_mode_back)); | 1363 | glPolygonMode(GL_BACK, MaxwellToGL::PolygonMode(regs.polygon_mode_back)); |
| 1394 | } | 1364 | } |
| 1395 | } | 1365 | } |
| 1396 | 1366 | ||
| 1397 | void RasterizerOpenGL::SyncColorMask() { | 1367 | void RasterizerOpenGL::SyncColorMask() { |
| 1398 | auto& gpu = system.GPU().Maxwell3D(); | 1368 | auto& flags = maxwell3d.dirty.flags; |
| 1399 | auto& flags = gpu.dirty.flags; | ||
| 1400 | if (!flags[Dirty::ColorMasks]) { | 1369 | if (!flags[Dirty::ColorMasks]) { |
| 1401 | return; | 1370 | return; |
| 1402 | } | 1371 | } |
| @@ -1405,7 +1374,7 @@ void RasterizerOpenGL::SyncColorMask() { | |||
| 1405 | const bool force = flags[Dirty::ColorMaskCommon]; | 1374 | const bool force = flags[Dirty::ColorMaskCommon]; |
| 1406 | flags[Dirty::ColorMaskCommon] = false; | 1375 | flags[Dirty::ColorMaskCommon] = false; |
| 1407 | 1376 | ||
| 1408 | const auto& regs = gpu.regs; | 1377 | const auto& regs = maxwell3d.regs; |
| 1409 | if (regs.color_mask_common) { | 1378 | if (regs.color_mask_common) { |
| 1410 | if (!force && !flags[Dirty::ColorMask0]) { | 1379 | if (!force && !flags[Dirty::ColorMask0]) { |
| 1411 | return; | 1380 | return; |
| @@ -1430,33 +1399,30 @@ void RasterizerOpenGL::SyncColorMask() { | |||
| 1430 | } | 1399 | } |
| 1431 | 1400 | ||
| 1432 | void RasterizerOpenGL::SyncMultiSampleState() { | 1401 | void RasterizerOpenGL::SyncMultiSampleState() { |
| 1433 | auto& gpu = system.GPU().Maxwell3D(); | 1402 | auto& flags = maxwell3d.dirty.flags; |
| 1434 | auto& flags = gpu.dirty.flags; | ||
| 1435 | if (!flags[Dirty::MultisampleControl]) { | 1403 | if (!flags[Dirty::MultisampleControl]) { |
| 1436 | return; | 1404 | return; |
| 1437 | } | 1405 | } |
| 1438 | flags[Dirty::MultisampleControl] = false; | 1406 | flags[Dirty::MultisampleControl] = false; |
| 1439 | 1407 | ||
| 1440 | const auto& regs = system.GPU().Maxwell3D().regs; | 1408 | const auto& regs = maxwell3d.regs; |
| 1441 | oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); | 1409 | oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); |
| 1442 | oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); | 1410 | oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); |
| 1443 | } | 1411 | } |
| 1444 | 1412 | ||
| 1445 | void RasterizerOpenGL::SyncFragmentColorClampState() { | 1413 | void RasterizerOpenGL::SyncFragmentColorClampState() { |
| 1446 | auto& gpu = system.GPU().Maxwell3D(); | 1414 | auto& flags = maxwell3d.dirty.flags; |
| 1447 | auto& flags = gpu.dirty.flags; | ||
| 1448 | if (!flags[Dirty::FragmentClampColor]) { | 1415 | if (!flags[Dirty::FragmentClampColor]) { |
| 1449 | return; | 1416 | return; |
| 1450 | } | 1417 | } |
| 1451 | flags[Dirty::FragmentClampColor] = false; | 1418 | flags[Dirty::FragmentClampColor] = false; |
| 1452 | 1419 | ||
| 1453 | glClampColor(GL_CLAMP_FRAGMENT_COLOR, gpu.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); | 1420 | glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); |
| 1454 | } | 1421 | } |
| 1455 | 1422 | ||
| 1456 | void RasterizerOpenGL::SyncBlendState() { | 1423 | void RasterizerOpenGL::SyncBlendState() { |
| 1457 | auto& gpu = system.GPU().Maxwell3D(); | 1424 | auto& flags = maxwell3d.dirty.flags; |
| 1458 | auto& flags = gpu.dirty.flags; | 1425 | const auto& regs = maxwell3d.regs; |
| 1459 | const auto& regs = gpu.regs; | ||
| 1460 | 1426 | ||
| 1461 | if (flags[Dirty::BlendColor]) { | 1427 | if (flags[Dirty::BlendColor]) { |
| 1462 | flags[Dirty::BlendColor] = false; | 1428 | flags[Dirty::BlendColor] = false; |
| @@ -1513,14 +1479,13 @@ void RasterizerOpenGL::SyncBlendState() { | |||
| 1513 | } | 1479 | } |
| 1514 | 1480 | ||
| 1515 | void RasterizerOpenGL::SyncLogicOpState() { | 1481 | void RasterizerOpenGL::SyncLogicOpState() { |
| 1516 | auto& gpu = system.GPU().Maxwell3D(); | 1482 | auto& flags = maxwell3d.dirty.flags; |
| 1517 | auto& flags = gpu.dirty.flags; | ||
| 1518 | if (!flags[Dirty::LogicOp]) { | 1483 | if (!flags[Dirty::LogicOp]) { |
| 1519 | return; | 1484 | return; |
| 1520 | } | 1485 | } |
| 1521 | flags[Dirty::LogicOp] = false; | 1486 | flags[Dirty::LogicOp] = false; |
| 1522 | 1487 | ||
| 1523 | const auto& regs = gpu.regs; | 1488 | const auto& regs = maxwell3d.regs; |
| 1524 | if (regs.logic_op.enable) { | 1489 | if (regs.logic_op.enable) { |
| 1525 | glEnable(GL_COLOR_LOGIC_OP); | 1490 | glEnable(GL_COLOR_LOGIC_OP); |
| 1526 | glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); | 1491 | glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); |
| @@ -1530,14 +1495,13 @@ void RasterizerOpenGL::SyncLogicOpState() { | |||
| 1530 | } | 1495 | } |
| 1531 | 1496 | ||
| 1532 | void RasterizerOpenGL::SyncScissorTest() { | 1497 | void RasterizerOpenGL::SyncScissorTest() { |
| 1533 | auto& gpu = system.GPU().Maxwell3D(); | 1498 | auto& flags = maxwell3d.dirty.flags; |
| 1534 | auto& flags = gpu.dirty.flags; | ||
| 1535 | if (!flags[Dirty::Scissors]) { | 1499 | if (!flags[Dirty::Scissors]) { |
| 1536 | return; | 1500 | return; |
| 1537 | } | 1501 | } |
| 1538 | flags[Dirty::Scissors] = false; | 1502 | flags[Dirty::Scissors] = false; |
| 1539 | 1503 | ||
| 1540 | const auto& regs = gpu.regs; | 1504 | const auto& regs = maxwell3d.regs; |
| 1541 | for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { | 1505 | for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { |
| 1542 | if (!flags[Dirty::Scissor0 + index]) { | 1506 | if (!flags[Dirty::Scissor0 + index]) { |
| 1543 | continue; | 1507 | continue; |
| @@ -1556,16 +1520,15 @@ void RasterizerOpenGL::SyncScissorTest() { | |||
| 1556 | } | 1520 | } |
| 1557 | 1521 | ||
| 1558 | void RasterizerOpenGL::SyncPointState() { | 1522 | void RasterizerOpenGL::SyncPointState() { |
| 1559 | auto& gpu = system.GPU().Maxwell3D(); | 1523 | auto& flags = maxwell3d.dirty.flags; |
| 1560 | auto& flags = gpu.dirty.flags; | ||
| 1561 | if (!flags[Dirty::PointSize]) { | 1524 | if (!flags[Dirty::PointSize]) { |
| 1562 | return; | 1525 | return; |
| 1563 | } | 1526 | } |
| 1564 | flags[Dirty::PointSize] = false; | 1527 | flags[Dirty::PointSize] = false; |
| 1565 | 1528 | ||
| 1566 | oglEnable(GL_POINT_SPRITE, gpu.regs.point_sprite_enable); | 1529 | oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable); |
| 1567 | 1530 | ||
| 1568 | if (gpu.regs.vp_point_size.enable) { | 1531 | if (maxwell3d.regs.vp_point_size.enable) { |
| 1569 | // By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled. | 1532 | // By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled. |
| 1570 | glEnable(GL_PROGRAM_POINT_SIZE); | 1533 | glEnable(GL_PROGRAM_POINT_SIZE); |
| 1571 | return; | 1534 | return; |
| @@ -1573,32 +1536,30 @@ void RasterizerOpenGL::SyncPointState() { | |||
| 1573 | 1536 | ||
| 1574 | // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid | 1537 | // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid |
| 1575 | // in OpenGL). | 1538 | // in OpenGL). |
| 1576 | glPointSize(std::max(1.0f, gpu.regs.point_size)); | 1539 | glPointSize(std::max(1.0f, maxwell3d.regs.point_size)); |
| 1577 | glDisable(GL_PROGRAM_POINT_SIZE); | 1540 | glDisable(GL_PROGRAM_POINT_SIZE); |
| 1578 | } | 1541 | } |
| 1579 | 1542 | ||
| 1580 | void RasterizerOpenGL::SyncLineState() { | 1543 | void RasterizerOpenGL::SyncLineState() { |
| 1581 | auto& gpu = system.GPU().Maxwell3D(); | 1544 | auto& flags = maxwell3d.dirty.flags; |
| 1582 | auto& flags = gpu.dirty.flags; | ||
| 1583 | if (!flags[Dirty::LineWidth]) { | 1545 | if (!flags[Dirty::LineWidth]) { |
| 1584 | return; | 1546 | return; |
| 1585 | } | 1547 | } |
| 1586 | flags[Dirty::LineWidth] = false; | 1548 | flags[Dirty::LineWidth] = false; |
| 1587 | 1549 | ||
| 1588 | const auto& regs = gpu.regs; | 1550 | const auto& regs = maxwell3d.regs; |
| 1589 | oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); | 1551 | oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); |
| 1590 | glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); | 1552 | glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); |
| 1591 | } | 1553 | } |
| 1592 | 1554 | ||
| 1593 | void RasterizerOpenGL::SyncPolygonOffset() { | 1555 | void RasterizerOpenGL::SyncPolygonOffset() { |
| 1594 | auto& gpu = system.GPU().Maxwell3D(); | 1556 | auto& flags = maxwell3d.dirty.flags; |
| 1595 | auto& flags = gpu.dirty.flags; | ||
| 1596 | if (!flags[Dirty::PolygonOffset]) { | 1557 | if (!flags[Dirty::PolygonOffset]) { |
| 1597 | return; | 1558 | return; |
| 1598 | } | 1559 | } |
| 1599 | flags[Dirty::PolygonOffset] = false; | 1560 | flags[Dirty::PolygonOffset] = false; |
| 1600 | 1561 | ||
| 1601 | const auto& regs = gpu.regs; | 1562 | const auto& regs = maxwell3d.regs; |
| 1602 | oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); | 1563 | oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); |
| 1603 | oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); | 1564 | oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); |
| 1604 | oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); | 1565 | oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); |
| @@ -1612,14 +1573,13 @@ void RasterizerOpenGL::SyncPolygonOffset() { | |||
| 1612 | } | 1573 | } |
| 1613 | 1574 | ||
| 1614 | void RasterizerOpenGL::SyncAlphaTest() { | 1575 | void RasterizerOpenGL::SyncAlphaTest() { |
| 1615 | auto& gpu = system.GPU().Maxwell3D(); | 1576 | auto& flags = maxwell3d.dirty.flags; |
| 1616 | auto& flags = gpu.dirty.flags; | ||
| 1617 | if (!flags[Dirty::AlphaTest]) { | 1577 | if (!flags[Dirty::AlphaTest]) { |
| 1618 | return; | 1578 | return; |
| 1619 | } | 1579 | } |
| 1620 | flags[Dirty::AlphaTest] = false; | 1580 | flags[Dirty::AlphaTest] = false; |
| 1621 | 1581 | ||
| 1622 | const auto& regs = gpu.regs; | 1582 | const auto& regs = maxwell3d.regs; |
| 1623 | if (regs.alpha_test_enabled && regs.rt_control.count > 1) { | 1583 | if (regs.alpha_test_enabled && regs.rt_control.count > 1) { |
| 1624 | LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested"); | 1584 | LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested"); |
| 1625 | } | 1585 | } |
| @@ -1633,20 +1593,19 @@ void RasterizerOpenGL::SyncAlphaTest() { | |||
| 1633 | } | 1593 | } |
| 1634 | 1594 | ||
| 1635 | void RasterizerOpenGL::SyncFramebufferSRGB() { | 1595 | void RasterizerOpenGL::SyncFramebufferSRGB() { |
| 1636 | auto& gpu = system.GPU().Maxwell3D(); | 1596 | auto& flags = maxwell3d.dirty.flags; |
| 1637 | auto& flags = gpu.dirty.flags; | ||
| 1638 | if (!flags[Dirty::FramebufferSRGB]) { | 1597 | if (!flags[Dirty::FramebufferSRGB]) { |
| 1639 | return; | 1598 | return; |
| 1640 | } | 1599 | } |
| 1641 | flags[Dirty::FramebufferSRGB] = false; | 1600 | flags[Dirty::FramebufferSRGB] = false; |
| 1642 | 1601 | ||
| 1643 | oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb); | 1602 | oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb); |
| 1644 | } | 1603 | } |
| 1645 | 1604 | ||
| 1646 | void RasterizerOpenGL::SyncTransformFeedback() { | 1605 | void RasterizerOpenGL::SyncTransformFeedback() { |
| 1647 | // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal | 1606 | // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal |
| 1648 | // when this is required. | 1607 | // when this is required. |
| 1649 | const auto& regs = system.GPU().Maxwell3D().regs; | 1608 | const auto& regs = maxwell3d.regs; |
| 1650 | 1609 | ||
| 1651 | static constexpr std::size_t STRIDE = 3; | 1610 | static constexpr std::size_t STRIDE = 3; |
| 1652 | std::array<GLint, 128 * STRIDE * Maxwell::NumTransformFeedbackBuffers> attribs; | 1611 | std::array<GLint, 128 * STRIDE * Maxwell::NumTransformFeedbackBuffers> attribs; |
| @@ -1698,7 +1657,7 @@ void RasterizerOpenGL::SyncTransformFeedback() { | |||
| 1698 | } | 1657 | } |
| 1699 | 1658 | ||
| 1700 | void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) { | 1659 | void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) { |
| 1701 | const auto& regs = system.GPU().Maxwell3D().regs; | 1660 | const auto& regs = maxwell3d.regs; |
| 1702 | if (regs.tfb_enabled == 0) { | 1661 | if (regs.tfb_enabled == 0) { |
| 1703 | return; | 1662 | return; |
| 1704 | } | 1663 | } |
| @@ -1741,7 +1700,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) { | |||
| 1741 | } | 1700 | } |
| 1742 | 1701 | ||
| 1743 | void RasterizerOpenGL::EndTransformFeedback() { | 1702 | void RasterizerOpenGL::EndTransformFeedback() { |
| 1744 | const auto& regs = system.GPU().Maxwell3D().regs; | 1703 | const auto& regs = maxwell3d.regs; |
| 1745 | if (regs.tfb_enabled == 0) { | 1704 | if (regs.tfb_enabled == 0) { |
| 1746 | return; | 1705 | return; |
| 1747 | } | 1706 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index ccc6f50f6..f451404b2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -36,8 +36,8 @@ | |||
| 36 | #include "video_core/shader/async_shaders.h" | 36 | #include "video_core/shader/async_shaders.h" |
| 37 | #include "video_core/textures/texture.h" | 37 | #include "video_core/textures/texture.h" |
| 38 | 38 | ||
| 39 | namespace Core { | 39 | namespace Core::Memory { |
| 40 | class System; | 40 | class Memory; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | namespace Core::Frontend { | 43 | namespace Core::Frontend { |
| @@ -55,9 +55,10 @@ struct DrawParameters; | |||
| 55 | 55 | ||
| 56 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { | 56 | class RasterizerOpenGL : public VideoCore::RasterizerAccelerated { |
| 57 | public: | 57 | public: |
| 58 | explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 58 | explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 59 | const Device& device, ScreenInfo& info, | 59 | Core::Memory::Memory& cpu_memory, const Device& device, |
| 60 | ProgramManager& program_manager, StateTracker& state_tracker); | 60 | ScreenInfo& screen_info, ProgramManager& program_manager, |
| 61 | StateTracker& state_tracker); | ||
| 61 | ~RasterizerOpenGL() override; | 62 | ~RasterizerOpenGL() override; |
| 62 | 63 | ||
| 63 | void Draw(bool is_indexed, bool is_instanced) override; | 64 | void Draw(bool is_indexed, bool is_instanced) override; |
| @@ -83,9 +84,8 @@ public: | |||
| 83 | const Tegra::Engines::Fermi2D::Config& copy_config) override; | 84 | const Tegra::Engines::Fermi2D::Config& copy_config) override; |
| 84 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, | 85 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |
| 85 | u32 pixel_stride) override; | 86 | u32 pixel_stride) override; |
| 86 | void LoadDiskResources(const std::atomic_bool& stop_loading, | 87 | void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading, |
| 87 | const VideoCore::DiskResourceLoadCallback& callback) override; | 88 | const VideoCore::DiskResourceLoadCallback& callback) override; |
| 88 | void SetupDirtyFlags() override; | ||
| 89 | 89 | ||
| 90 | /// Returns true when there are commands queued to the OpenGL server. | 90 | /// Returns true when there are commands queued to the OpenGL server. |
| 91 | bool AnyCommandQueued() const { | 91 | bool AnyCommandQueued() const { |
| @@ -237,7 +237,15 @@ private: | |||
| 237 | 237 | ||
| 238 | void SetupShaders(GLenum primitive_mode); | 238 | void SetupShaders(GLenum primitive_mode); |
| 239 | 239 | ||
| 240 | Tegra::GPU& gpu; | ||
| 241 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 242 | Tegra::Engines::KeplerCompute& kepler_compute; | ||
| 243 | Tegra::MemoryManager& gpu_memory; | ||
| 244 | |||
| 240 | const Device& device; | 245 | const Device& device; |
| 246 | ScreenInfo& screen_info; | ||
| 247 | ProgramManager& program_manager; | ||
| 248 | StateTracker& state_tracker; | ||
| 241 | 249 | ||
| 242 | TextureCacheOpenGL texture_cache; | 250 | TextureCacheOpenGL texture_cache; |
| 243 | ShaderCacheOpenGL shader_cache; | 251 | ShaderCacheOpenGL shader_cache; |
| @@ -247,10 +255,6 @@ private: | |||
| 247 | OGLBufferCache buffer_cache; | 255 | OGLBufferCache buffer_cache; |
| 248 | FenceManagerOpenGL fence_manager; | 256 | FenceManagerOpenGL fence_manager; |
| 249 | 257 | ||
| 250 | Core::System& system; | ||
| 251 | ScreenInfo& screen_info; | ||
| 252 | ProgramManager& program_manager; | ||
| 253 | StateTracker& state_tracker; | ||
| 254 | VideoCommon::Shader::AsyncShaders async_shaders; | 258 | VideoCommon::Shader::AsyncShaders async_shaders; |
| 255 | 259 | ||
| 256 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 260 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a07d56ef0..bd56bed0c 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -239,12 +239,11 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory( | |||
| 239 | ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { | 239 | ProgramCode code_b, VideoCommon::Shader::AsyncShaders& async_shaders, VAddr cpu_addr) { |
| 240 | const auto shader_type = GetShaderType(program_type); | 240 | const auto shader_type = GetShaderType(program_type); |
| 241 | 241 | ||
| 242 | auto& gpu = params.system.GPU(); | 242 | auto& gpu = params.gpu; |
| 243 | gpu.ShaderNotify().MarkSharderBuilding(); | 243 | gpu.ShaderNotify().MarkSharderBuilding(); |
| 244 | 244 | ||
| 245 | auto registry = std::make_shared<Registry>(shader_type, gpu.Maxwell3D()); | 245 | auto registry = std::make_shared<Registry>(shader_type, gpu.Maxwell3D()); |
| 246 | if (!async_shaders.IsShaderAsync(params.system.GPU()) || | 246 | if (!async_shaders.IsShaderAsync(gpu) || !params.device.UseAsynchronousShaders()) { |
| 247 | !params.device.UseAsynchronousShaders()) { | ||
| 248 | const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); | 247 | const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); |
| 249 | // TODO(Rodrigo): Handle VertexA shaders | 248 | // TODO(Rodrigo): Handle VertexA shaders |
| 250 | // std::optional<ShaderIR> ir_b; | 249 | // std::optional<ShaderIR> ir_b; |
| @@ -287,11 +286,10 @@ std::unique_ptr<Shader> Shader::CreateStageFromMemory( | |||
| 287 | 286 | ||
| 288 | std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, | 287 | std::unique_ptr<Shader> Shader::CreateKernelFromMemory(const ShaderParameters& params, |
| 289 | ProgramCode code) { | 288 | ProgramCode code) { |
| 290 | auto& gpu = params.system.GPU(); | 289 | auto& gpu = params.gpu; |
| 291 | gpu.ShaderNotify().MarkSharderBuilding(); | 290 | gpu.ShaderNotify().MarkSharderBuilding(); |
| 292 | 291 | ||
| 293 | auto& engine = gpu.KeplerCompute(); | 292 | auto registry = std::make_shared<Registry>(ShaderType::Compute, params.engine); |
| 294 | auto registry = std::make_shared<Registry>(ShaderType::Compute, engine); | ||
| 295 | const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); | 293 | const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); |
| 296 | const u64 uid = params.unique_identifier; | 294 | const u64 uid = params.unique_identifier; |
| 297 | auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); | 295 | auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); |
| @@ -320,15 +318,20 @@ std::unique_ptr<Shader> Shader::CreateFromCache(const ShaderParameters& params, | |||
| 320 | precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program)); | 318 | precompiled_shader.registry, precompiled_shader.entries, precompiled_shader.program)); |
| 321 | } | 319 | } |
| 322 | 320 | ||
| 323 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 321 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, |
| 324 | Core::Frontend::EmuWindow& emu_window, const Device& device) | 322 | Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, |
| 325 | : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, | 323 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 326 | emu_window{emu_window}, device{device}, disk_cache{system} {} | 324 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 325 | Tegra::MemoryManager& gpu_memory_, const Device& device_) | ||
| 326 | : VideoCommon::ShaderCache<Shader>{rasterizer}, emu_window{emu_window_}, gpu{gpu_}, | ||
| 327 | gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, | ||
| 328 | kepler_compute{kepler_compute_}, device{device_} {} | ||
| 327 | 329 | ||
| 328 | ShaderCacheOpenGL::~ShaderCacheOpenGL() = default; | 330 | ShaderCacheOpenGL::~ShaderCacheOpenGL() = default; |
| 329 | 331 | ||
| 330 | void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, | 332 | void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading, |
| 331 | const VideoCore::DiskResourceLoadCallback& callback) { | 333 | const VideoCore::DiskResourceLoadCallback& callback) { |
| 334 | disk_cache.BindTitleID(title_id); | ||
| 332 | const std::optional transferable = disk_cache.LoadTransferable(); | 335 | const std::optional transferable = disk_cache.LoadTransferable(); |
| 333 | if (!transferable) { | 336 | if (!transferable) { |
| 334 | return; | 337 | return; |
| @@ -481,21 +484,19 @@ ProgramSharedPtr ShaderCacheOpenGL::GeneratePrecompiledProgram( | |||
| 481 | 484 | ||
| 482 | Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, | 485 | Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, |
| 483 | VideoCommon::Shader::AsyncShaders& async_shaders) { | 486 | VideoCommon::Shader::AsyncShaders& async_shaders) { |
| 484 | if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { | 487 | if (!maxwell3d.dirty.flags[Dirty::Shaders]) { |
| 485 | auto* last_shader = last_shaders[static_cast<std::size_t>(program)]; | 488 | auto* last_shader = last_shaders[static_cast<std::size_t>(program)]; |
| 486 | if (last_shader->IsBuilt()) { | 489 | if (last_shader->IsBuilt()) { |
| 487 | return last_shader; | 490 | return last_shader; |
| 488 | } | 491 | } |
| 489 | } | 492 | } |
| 490 | 493 | ||
| 491 | auto& memory_manager{system.GPU().MemoryManager()}; | 494 | const GPUVAddr address{GetShaderAddress(maxwell3d, program)}; |
| 492 | const GPUVAddr address{GetShaderAddress(system, program)}; | ||
| 493 | 495 | ||
| 494 | if (device.UseAsynchronousShaders() && async_shaders.HasCompletedWork()) { | 496 | if (device.UseAsynchronousShaders() && async_shaders.HasCompletedWork()) { |
| 495 | auto completed_work = async_shaders.GetCompletedWork(); | 497 | auto completed_work = async_shaders.GetCompletedWork(); |
| 496 | for (auto& work : completed_work) { | 498 | for (auto& work : completed_work) { |
| 497 | Shader* shader = TryGet(work.cpu_address); | 499 | Shader* shader = TryGet(work.cpu_address); |
| 498 | auto& gpu = system.GPU(); | ||
| 499 | gpu.ShaderNotify().MarkShaderComplete(); | 500 | gpu.ShaderNotify().MarkShaderComplete(); |
| 500 | if (shader == nullptr) { | 501 | if (shader == nullptr) { |
| 501 | continue; | 502 | continue; |
| @@ -507,14 +508,13 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, | |||
| 507 | shader->AsyncGLASMBuilt(std::move(work.program.glasm)); | 508 | shader->AsyncGLASMBuilt(std::move(work.program.glasm)); |
| 508 | } | 509 | } |
| 509 | 510 | ||
| 511 | auto& registry = shader->GetRegistry(); | ||
| 512 | |||
| 510 | ShaderDiskCacheEntry entry; | 513 | ShaderDiskCacheEntry entry; |
| 511 | entry.type = work.shader_type; | 514 | entry.type = work.shader_type; |
| 512 | entry.code = std::move(work.code); | 515 | entry.code = std::move(work.code); |
| 513 | entry.code_b = std::move(work.code_b); | 516 | entry.code_b = std::move(work.code_b); |
| 514 | entry.unique_identifier = work.uid; | 517 | entry.unique_identifier = work.uid; |
| 515 | |||
| 516 | auto& registry = shader->GetRegistry(); | ||
| 517 | |||
| 518 | entry.bound_buffer = registry.GetBoundBuffer(); | 518 | entry.bound_buffer = registry.GetBoundBuffer(); |
| 519 | entry.graphics_info = registry.GetGraphicsInfo(); | 519 | entry.graphics_info = registry.GetGraphicsInfo(); |
| 520 | entry.keys = registry.GetKeys(); | 520 | entry.keys = registry.GetKeys(); |
| @@ -525,28 +525,28 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, | |||
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | // Look up shader in the cache based on address | 527 | // Look up shader in the cache based on address |
| 528 | const auto cpu_addr{memory_manager.GpuToCpuAddress(address)}; | 528 | const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(address)}; |
| 529 | if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) { | 529 | if (Shader* const shader{cpu_addr ? TryGet(*cpu_addr) : null_shader.get()}) { |
| 530 | return last_shaders[static_cast<std::size_t>(program)] = shader; | 530 | return last_shaders[static_cast<std::size_t>(program)] = shader; |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | const auto host_ptr{memory_manager.GetPointer(address)}; | 533 | const u8* const host_ptr{gpu_memory.GetPointer(address)}; |
| 534 | 534 | ||
| 535 | // No shader found - create a new one | 535 | // No shader found - create a new one |
| 536 | ProgramCode code{GetShaderCode(memory_manager, address, host_ptr, false)}; | 536 | ProgramCode code{GetShaderCode(gpu_memory, address, host_ptr, false)}; |
| 537 | ProgramCode code_b; | 537 | ProgramCode code_b; |
| 538 | if (program == Maxwell::ShaderProgram::VertexA) { | 538 | if (program == Maxwell::ShaderProgram::VertexA) { |
| 539 | const GPUVAddr address_b{GetShaderAddress(system, Maxwell::ShaderProgram::VertexB)}; | 539 | const GPUVAddr address_b{GetShaderAddress(maxwell3d, Maxwell::ShaderProgram::VertexB)}; |
| 540 | const u8* host_ptr_b = memory_manager.GetPointer(address_b); | 540 | const u8* host_ptr_b = gpu_memory.GetPointer(address_b); |
| 541 | code_b = GetShaderCode(memory_manager, address_b, host_ptr_b, false); | 541 | code_b = GetShaderCode(gpu_memory, address_b, host_ptr_b, false); |
| 542 | } | 542 | } |
| 543 | const std::size_t code_size = code.size() * sizeof(u64); | 543 | const std::size_t code_size = code.size() * sizeof(u64); |
| 544 | 544 | ||
| 545 | const u64 unique_identifier = GetUniqueIdentifier( | 545 | const u64 unique_identifier = GetUniqueIdentifier( |
| 546 | GetShaderType(program), program == Maxwell::ShaderProgram::VertexA, code, code_b); | 546 | GetShaderType(program), program == Maxwell::ShaderProgram::VertexA, code, code_b); |
| 547 | 547 | ||
| 548 | const ShaderParameters params{system, disk_cache, device, | 548 | const ShaderParameters params{gpu, maxwell3d, disk_cache, device, |
| 549 | *cpu_addr, host_ptr, unique_identifier}; | 549 | *cpu_addr, host_ptr, unique_identifier}; |
| 550 | 550 | ||
| 551 | std::unique_ptr<Shader> shader; | 551 | std::unique_ptr<Shader> shader; |
| 552 | const auto found = runtime_cache.find(unique_identifier); | 552 | const auto found = runtime_cache.find(unique_identifier); |
| @@ -568,21 +568,20 @@ Shader* ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program, | |||
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { | 570 | Shader* ShaderCacheOpenGL::GetComputeKernel(GPUVAddr code_addr) { |
| 571 | auto& memory_manager{system.GPU().MemoryManager()}; | 571 | const std::optional<VAddr> cpu_addr{gpu_memory.GpuToCpuAddress(code_addr)}; |
| 572 | const auto cpu_addr{memory_manager.GpuToCpuAddress(code_addr)}; | ||
| 573 | 572 | ||
| 574 | if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) { | 573 | if (Shader* const kernel = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get()) { |
| 575 | return kernel; | 574 | return kernel; |
| 576 | } | 575 | } |
| 577 | 576 | ||
| 578 | const auto host_ptr{memory_manager.GetPointer(code_addr)}; | ||
| 579 | // No kernel found, create a new one | 577 | // No kernel found, create a new one |
| 580 | ProgramCode code{GetShaderCode(memory_manager, code_addr, host_ptr, true)}; | 578 | const u8* host_ptr{gpu_memory.GetPointer(code_addr)}; |
| 579 | ProgramCode code{GetShaderCode(gpu_memory, code_addr, host_ptr, true)}; | ||
| 581 | const std::size_t code_size{code.size() * sizeof(u64)}; | 580 | const std::size_t code_size{code.size() * sizeof(u64)}; |
| 582 | const u64 unique_identifier{GetUniqueIdentifier(ShaderType::Compute, false, code)}; | 581 | const u64 unique_identifier{GetUniqueIdentifier(ShaderType::Compute, false, code)}; |
| 583 | 582 | ||
| 584 | const ShaderParameters params{system, disk_cache, device, | 583 | const ShaderParameters params{gpu, kepler_compute, disk_cache, device, |
| 585 | *cpu_addr, host_ptr, unique_identifier}; | 584 | *cpu_addr, host_ptr, unique_identifier}; |
| 586 | 585 | ||
| 587 | std::unique_ptr<Shader> kernel; | 586 | std::unique_ptr<Shader> kernel; |
| 588 | const auto found = runtime_cache.find(unique_identifier); | 587 | const auto found = runtime_cache.find(unique_identifier); |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 7528ac686..1708af06a 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | #include "video_core/shader/shader_ir.h" | 25 | #include "video_core/shader/shader_ir.h" |
| 26 | #include "video_core/shader_cache.h" | 26 | #include "video_core/shader_cache.h" |
| 27 | 27 | ||
| 28 | namespace Core { | 28 | namespace Tegra { |
| 29 | class System; | 29 | class MemoryManager; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | namespace Core::Frontend { | 32 | namespace Core::Frontend { |
| @@ -57,11 +57,12 @@ struct PrecompiledShader { | |||
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | struct ShaderParameters { | 59 | struct ShaderParameters { |
| 60 | Core::System& system; | 60 | Tegra::GPU& gpu; |
| 61 | Tegra::Engines::ConstBufferEngineInterface& engine; | ||
| 61 | ShaderDiskCacheOpenGL& disk_cache; | 62 | ShaderDiskCacheOpenGL& disk_cache; |
| 62 | const Device& device; | 63 | const Device& device; |
| 63 | VAddr cpu_addr; | 64 | VAddr cpu_addr; |
| 64 | u8* host_ptr; | 65 | const u8* host_ptr; |
| 65 | u64 unique_identifier; | 66 | u64 unique_identifier; |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| @@ -118,12 +119,14 @@ private: | |||
| 118 | 119 | ||
| 119 | class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> { | 120 | class ShaderCacheOpenGL final : public VideoCommon::ShaderCache<Shader> { |
| 120 | public: | 121 | public: |
| 121 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 122 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::Frontend::EmuWindow& emu_window, |
| 122 | Core::Frontend::EmuWindow& emu_window, const Device& device); | 123 | Tegra::GPU& gpu, Tegra::Engines::Maxwell3D& maxwell3d, |
| 124 | Tegra::Engines::KeplerCompute& kepler_compute, | ||
| 125 | Tegra::MemoryManager& gpu_memory, const Device& device); | ||
| 123 | ~ShaderCacheOpenGL() override; | 126 | ~ShaderCacheOpenGL() override; |
| 124 | 127 | ||
| 125 | /// Loads disk cache for the current game | 128 | /// Loads disk cache for the current game |
| 126 | void LoadDiskCache(const std::atomic_bool& stop_loading, | 129 | void LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading, |
| 127 | const VideoCore::DiskResourceLoadCallback& callback); | 130 | const VideoCore::DiskResourceLoadCallback& callback); |
| 128 | 131 | ||
| 129 | /// Gets the current specified shader stage program | 132 | /// Gets the current specified shader stage program |
| @@ -138,9 +141,13 @@ private: | |||
| 138 | const ShaderDiskCacheEntry& entry, const ShaderDiskCachePrecompiled& precompiled_entry, | 141 | const ShaderDiskCacheEntry& entry, const ShaderDiskCachePrecompiled& precompiled_entry, |
| 139 | const std::unordered_set<GLenum>& supported_formats); | 142 | const std::unordered_set<GLenum>& supported_formats); |
| 140 | 143 | ||
| 141 | Core::System& system; | ||
| 142 | Core::Frontend::EmuWindow& emu_window; | 144 | Core::Frontend::EmuWindow& emu_window; |
| 145 | Tegra::GPU& gpu; | ||
| 146 | Tegra::MemoryManager& gpu_memory; | ||
| 147 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 148 | Tegra::Engines::KeplerCompute& kepler_compute; | ||
| 143 | const Device& device; | 149 | const Device& device; |
| 150 | |||
| 144 | ShaderDiskCacheOpenGL disk_cache; | 151 | ShaderDiskCacheOpenGL disk_cache; |
| 145 | std::unordered_map<u64, PrecompiledShader> runtime_cache; | 152 | std::unordered_map<u64, PrecompiledShader> runtime_cache; |
| 146 | 153 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 40c0877c1..166ee34e1 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -206,13 +206,17 @@ bool ShaderDiskCacheEntry::Save(Common::FS::IOFile& file) const { | |||
| 206 | flat_bindless_samplers.size(); | 206 | flat_bindless_samplers.size(); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL(Core::System& system) : system{system} {} | 209 | ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL() = default; |
| 210 | 210 | ||
| 211 | ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default; | 211 | ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default; |
| 212 | 212 | ||
| 213 | void ShaderDiskCacheOpenGL::BindTitleID(u64 title_id_) { | ||
| 214 | title_id = title_id_; | ||
| 215 | } | ||
| 216 | |||
| 213 | std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() { | 217 | std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() { |
| 214 | // Skip games without title id | 218 | // Skip games without title id |
| 215 | const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0; | 219 | const bool has_title_id = title_id != 0; |
| 216 | if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) { | 220 | if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) { |
| 217 | return std::nullopt; | 221 | return std::nullopt; |
| 218 | } | 222 | } |
| @@ -474,7 +478,7 @@ std::string ShaderDiskCacheOpenGL::GetBaseDir() const { | |||
| 474 | } | 478 | } |
| 475 | 479 | ||
| 476 | std::string ShaderDiskCacheOpenGL::GetTitleID() const { | 480 | std::string ShaderDiskCacheOpenGL::GetTitleID() const { |
| 477 | return fmt::format("{:016X}", system.CurrentProcess()->GetTitleID()); | 481 | return fmt::format("{:016X}", title_id); |
| 478 | } | 482 | } |
| 479 | 483 | ||
| 480 | } // namespace OpenGL | 484 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h index db2bb73bc..aef841c1d 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h | |||
| @@ -21,10 +21,6 @@ | |||
| 21 | #include "video_core/engines/shader_type.h" | 21 | #include "video_core/engines/shader_type.h" |
| 22 | #include "video_core/shader/registry.h" | 22 | #include "video_core/shader/registry.h" |
| 23 | 23 | ||
| 24 | namespace Core { | ||
| 25 | class System; | ||
| 26 | } | ||
| 27 | |||
| 28 | namespace Common::FS { | 24 | namespace Common::FS { |
| 29 | class IOFile; | 25 | class IOFile; |
| 30 | } | 26 | } |
| @@ -70,9 +66,12 @@ struct ShaderDiskCachePrecompiled { | |||
| 70 | 66 | ||
| 71 | class ShaderDiskCacheOpenGL { | 67 | class ShaderDiskCacheOpenGL { |
| 72 | public: | 68 | public: |
| 73 | explicit ShaderDiskCacheOpenGL(Core::System& system); | 69 | explicit ShaderDiskCacheOpenGL(); |
| 74 | ~ShaderDiskCacheOpenGL(); | 70 | ~ShaderDiskCacheOpenGL(); |
| 75 | 71 | ||
| 72 | /// Binds a title ID for all future operations. | ||
| 73 | void BindTitleID(u64 title_id); | ||
| 74 | |||
| 76 | /// Loads transferable cache. If file has a old version or on failure, it deletes the file. | 75 | /// Loads transferable cache. If file has a old version or on failure, it deletes the file. |
| 77 | std::optional<std::vector<ShaderDiskCacheEntry>> LoadTransferable(); | 76 | std::optional<std::vector<ShaderDiskCacheEntry>> LoadTransferable(); |
| 78 | 77 | ||
| @@ -157,8 +156,6 @@ private: | |||
| 157 | return LoadArrayFromPrecompiled(&object, 1); | 156 | return LoadArrayFromPrecompiled(&object, 1); |
| 158 | } | 157 | } |
| 159 | 158 | ||
| 160 | Core::System& system; | ||
| 161 | |||
| 162 | // Stores whole precompiled cache which will be read from or saved to the precompiled chache | 159 | // Stores whole precompiled cache which will be read from or saved to the precompiled chache |
| 163 | // file | 160 | // file |
| 164 | FileSys::VectorVfsFile precompiled_cache_virtual_file; | 161 | FileSys::VectorVfsFile precompiled_cache_virtual_file; |
| @@ -168,8 +165,11 @@ private: | |||
| 168 | // Stored transferable shaders | 165 | // Stored transferable shaders |
| 169 | std::unordered_set<u64> stored_transferable; | 166 | std::unordered_set<u64> stored_transferable; |
| 170 | 167 | ||
| 168 | /// Title ID to operate on | ||
| 169 | u64 title_id = 0; | ||
| 170 | |||
| 171 | // The cache has been loaded at boot | 171 | // The cache has been loaded at boot |
| 172 | bool is_usable{}; | 172 | bool is_usable = false; |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | } // namespace OpenGL | 175 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index d24fad3de..6bcf831f2 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
| @@ -214,10 +214,8 @@ void SetupDirtyMisc(Tables& tables) { | |||
| 214 | 214 | ||
| 215 | } // Anonymous namespace | 215 | } // Anonymous namespace |
| 216 | 216 | ||
| 217 | StateTracker::StateTracker(Core::System& system) : system{system} {} | 217 | StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} { |
| 218 | 218 | auto& dirty = gpu.Maxwell3D().dirty; | |
| 219 | void StateTracker::Initialize() { | ||
| 220 | auto& dirty = system.GPU().Maxwell3D().dirty; | ||
| 221 | auto& tables = dirty.tables; | 219 | auto& tables = dirty.tables; |
| 222 | SetupDirtyRenderTargets(tables); | 220 | SetupDirtyRenderTargets(tables); |
| 223 | SetupDirtyColorMasks(tables); | 221 | SetupDirtyColorMasks(tables); |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 0f823288e..9d127548f 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | #include "video_core/dirty_flags.h" | 13 | #include "video_core/dirty_flags.h" |
| 14 | #include "video_core/engines/maxwell_3d.h" | 14 | #include "video_core/engines/maxwell_3d.h" |
| 15 | 15 | ||
| 16 | namespace Core { | 16 | namespace Tegra { |
| 17 | class System; | 17 | class GPU; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | namespace OpenGL { | 20 | namespace OpenGL { |
| @@ -90,9 +90,7 @@ static_assert(Last <= std::numeric_limits<u8>::max()); | |||
| 90 | 90 | ||
| 91 | class StateTracker { | 91 | class StateTracker { |
| 92 | public: | 92 | public: |
| 93 | explicit StateTracker(Core::System& system); | 93 | explicit StateTracker(Tegra::GPU& gpu); |
| 94 | |||
| 95 | void Initialize(); | ||
| 96 | 94 | ||
| 97 | void BindIndexBuffer(GLuint new_index_buffer) { | 95 | void BindIndexBuffer(GLuint new_index_buffer) { |
| 98 | if (index_buffer == new_index_buffer) { | 96 | if (index_buffer == new_index_buffer) { |
| @@ -103,7 +101,6 @@ public: | |||
| 103 | } | 101 | } |
| 104 | 102 | ||
| 105 | void NotifyScreenDrawVertexArray() { | 103 | void NotifyScreenDrawVertexArray() { |
| 106 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 107 | flags[OpenGL::Dirty::VertexFormats] = true; | 104 | flags[OpenGL::Dirty::VertexFormats] = true; |
| 108 | flags[OpenGL::Dirty::VertexFormat0 + 0] = true; | 105 | flags[OpenGL::Dirty::VertexFormat0 + 0] = true; |
| 109 | flags[OpenGL::Dirty::VertexFormat0 + 1] = true; | 106 | flags[OpenGL::Dirty::VertexFormat0 + 1] = true; |
| @@ -117,98 +114,81 @@ public: | |||
| 117 | } | 114 | } |
| 118 | 115 | ||
| 119 | void NotifyPolygonModes() { | 116 | void NotifyPolygonModes() { |
| 120 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 121 | flags[OpenGL::Dirty::PolygonModes] = true; | 117 | flags[OpenGL::Dirty::PolygonModes] = true; |
| 122 | flags[OpenGL::Dirty::PolygonModeFront] = true; | 118 | flags[OpenGL::Dirty::PolygonModeFront] = true; |
| 123 | flags[OpenGL::Dirty::PolygonModeBack] = true; | 119 | flags[OpenGL::Dirty::PolygonModeBack] = true; |
| 124 | } | 120 | } |
| 125 | 121 | ||
| 126 | void NotifyViewport0() { | 122 | void NotifyViewport0() { |
| 127 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 128 | flags[OpenGL::Dirty::Viewports] = true; | 123 | flags[OpenGL::Dirty::Viewports] = true; |
| 129 | flags[OpenGL::Dirty::Viewport0] = true; | 124 | flags[OpenGL::Dirty::Viewport0] = true; |
| 130 | } | 125 | } |
| 131 | 126 | ||
| 132 | void NotifyScissor0() { | 127 | void NotifyScissor0() { |
| 133 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 134 | flags[OpenGL::Dirty::Scissors] = true; | 128 | flags[OpenGL::Dirty::Scissors] = true; |
| 135 | flags[OpenGL::Dirty::Scissor0] = true; | 129 | flags[OpenGL::Dirty::Scissor0] = true; |
| 136 | } | 130 | } |
| 137 | 131 | ||
| 138 | void NotifyColorMask0() { | 132 | void NotifyColorMask0() { |
| 139 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 140 | flags[OpenGL::Dirty::ColorMasks] = true; | 133 | flags[OpenGL::Dirty::ColorMasks] = true; |
| 141 | flags[OpenGL::Dirty::ColorMask0] = true; | 134 | flags[OpenGL::Dirty::ColorMask0] = true; |
| 142 | } | 135 | } |
| 143 | 136 | ||
| 144 | void NotifyBlend0() { | 137 | void NotifyBlend0() { |
| 145 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 146 | flags[OpenGL::Dirty::BlendStates] = true; | 138 | flags[OpenGL::Dirty::BlendStates] = true; |
| 147 | flags[OpenGL::Dirty::BlendState0] = true; | 139 | flags[OpenGL::Dirty::BlendState0] = true; |
| 148 | } | 140 | } |
| 149 | 141 | ||
| 150 | void NotifyFramebuffer() { | 142 | void NotifyFramebuffer() { |
| 151 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 152 | flags[VideoCommon::Dirty::RenderTargets] = true; | 143 | flags[VideoCommon::Dirty::RenderTargets] = true; |
| 153 | } | 144 | } |
| 154 | 145 | ||
| 155 | void NotifyFrontFace() { | 146 | void NotifyFrontFace() { |
| 156 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 157 | flags[OpenGL::Dirty::FrontFace] = true; | 147 | flags[OpenGL::Dirty::FrontFace] = true; |
| 158 | } | 148 | } |
| 159 | 149 | ||
| 160 | void NotifyCullTest() { | 150 | void NotifyCullTest() { |
| 161 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 162 | flags[OpenGL::Dirty::CullTest] = true; | 151 | flags[OpenGL::Dirty::CullTest] = true; |
| 163 | } | 152 | } |
| 164 | 153 | ||
| 165 | void NotifyDepthMask() { | 154 | void NotifyDepthMask() { |
| 166 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 167 | flags[OpenGL::Dirty::DepthMask] = true; | 155 | flags[OpenGL::Dirty::DepthMask] = true; |
| 168 | } | 156 | } |
| 169 | 157 | ||
| 170 | void NotifyDepthTest() { | 158 | void NotifyDepthTest() { |
| 171 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 172 | flags[OpenGL::Dirty::DepthTest] = true; | 159 | flags[OpenGL::Dirty::DepthTest] = true; |
| 173 | } | 160 | } |
| 174 | 161 | ||
| 175 | void NotifyStencilTest() { | 162 | void NotifyStencilTest() { |
| 176 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 177 | flags[OpenGL::Dirty::StencilTest] = true; | 163 | flags[OpenGL::Dirty::StencilTest] = true; |
| 178 | } | 164 | } |
| 179 | 165 | ||
| 180 | void NotifyPolygonOffset() { | 166 | void NotifyPolygonOffset() { |
| 181 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 182 | flags[OpenGL::Dirty::PolygonOffset] = true; | 167 | flags[OpenGL::Dirty::PolygonOffset] = true; |
| 183 | } | 168 | } |
| 184 | 169 | ||
| 185 | void NotifyRasterizeEnable() { | 170 | void NotifyRasterizeEnable() { |
| 186 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 187 | flags[OpenGL::Dirty::RasterizeEnable] = true; | 171 | flags[OpenGL::Dirty::RasterizeEnable] = true; |
| 188 | } | 172 | } |
| 189 | 173 | ||
| 190 | void NotifyFramebufferSRGB() { | 174 | void NotifyFramebufferSRGB() { |
| 191 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 192 | flags[OpenGL::Dirty::FramebufferSRGB] = true; | 175 | flags[OpenGL::Dirty::FramebufferSRGB] = true; |
| 193 | } | 176 | } |
| 194 | 177 | ||
| 195 | void NotifyLogicOp() { | 178 | void NotifyLogicOp() { |
| 196 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 197 | flags[OpenGL::Dirty::LogicOp] = true; | 179 | flags[OpenGL::Dirty::LogicOp] = true; |
| 198 | } | 180 | } |
| 199 | 181 | ||
| 200 | void NotifyClipControl() { | 182 | void NotifyClipControl() { |
| 201 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 202 | flags[OpenGL::Dirty::ClipControl] = true; | 183 | flags[OpenGL::Dirty::ClipControl] = true; |
| 203 | } | 184 | } |
| 204 | 185 | ||
| 205 | void NotifyAlphaTest() { | 186 | void NotifyAlphaTest() { |
| 206 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 207 | flags[OpenGL::Dirty::AlphaTest] = true; | 187 | flags[OpenGL::Dirty::AlphaTest] = true; |
| 208 | } | 188 | } |
| 209 | 189 | ||
| 210 | private: | 190 | private: |
| 211 | Core::System& system; | 191 | Tegra::Engines::Maxwell3D::DirtyState::Flags& flags; |
| 212 | 192 | ||
| 213 | GLuint index_buffer = 0; | 193 | GLuint index_buffer = 0; |
| 214 | }; | 194 | }; |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index f403f388a..a863ef218 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -532,10 +532,12 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const { | |||
| 532 | return texture_view; | 532 | return texture_view; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system, | 535 | TextureCacheOpenGL::TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer, |
| 536 | VideoCore::RasterizerInterface& rasterizer, | 536 | Tegra::Engines::Maxwell3D& maxwell3d, |
| 537 | const Device& device, StateTracker& state_tracker) | 537 | Tegra::MemoryManager& gpu_memory, const Device& device, |
| 538 | : TextureCacheBase{system, rasterizer, device.HasASTC()}, state_tracker{state_tracker} { | 538 | StateTracker& state_tracker_) |
| 539 | : TextureCacheBase{rasterizer, maxwell3d, gpu_memory, device.HasASTC()}, state_tracker{ | ||
| 540 | state_tracker_} { | ||
| 539 | src_framebuffer.Create(); | 541 | src_framebuffer.Create(); |
| 540 | dst_framebuffer.Create(); | 542 | dst_framebuffer.Create(); |
| 541 | } | 543 | } |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index de8f18489..7787134fc 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -129,8 +129,10 @@ private: | |||
| 129 | 129 | ||
| 130 | class TextureCacheOpenGL final : public TextureCacheBase { | 130 | class TextureCacheOpenGL final : public TextureCacheBase { |
| 131 | public: | 131 | public: |
| 132 | explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 132 | explicit TextureCacheOpenGL(VideoCore::RasterizerInterface& rasterizer, |
| 133 | const Device& device, StateTracker& state_tracker); | 133 | Tegra::Engines::Maxwell3D& maxwell3d, |
| 134 | Tegra::MemoryManager& gpu_memory, const Device& device, | ||
| 135 | StateTracker& state_tracker); | ||
| 134 | ~TextureCacheOpenGL(); | 136 | ~TextureCacheOpenGL(); |
| 135 | 137 | ||
| 136 | protected: | 138 | protected: |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index b759c2dba..a4c5b8f74 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -275,11 +275,13 @@ public: | |||
| 275 | } | 275 | } |
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| 278 | RendererOpenGL::RendererOpenGL(Core::System& system_, Core::Frontend::EmuWindow& emu_window_, | 278 | RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, |
| 279 | Tegra::GPU& gpu_, | 279 | Core::Frontend::EmuWindow& emu_window_, |
| 280 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) | 280 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, |
| 281 | : RendererBase{emu_window_, std::move(context_)}, system{system_}, | 281 | std::unique_ptr<Core::Frontend::GraphicsContext> context) |
| 282 | emu_window{emu_window_}, gpu{gpu_}, program_manager{device}, has_debug_tool{HasDebugTool()} {} | 282 | : RendererBase{emu_window_, std::move(context)}, telemetry_session{telemetry_session_}, |
| 283 | emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, program_manager{device}, | ||
| 284 | has_debug_tool{HasDebugTool()} {} | ||
| 283 | 285 | ||
| 284 | RendererOpenGL::~RendererOpenGL() = default; | 286 | RendererOpenGL::~RendererOpenGL() = default; |
| 285 | 287 | ||
| @@ -386,7 +388,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 386 | VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)}; | 388 | VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)}; |
| 387 | const u32 bytes_per_pixel{VideoCore::Surface::GetBytesPerPixel(pixel_format)}; | 389 | const u32 bytes_per_pixel{VideoCore::Surface::GetBytesPerPixel(pixel_format)}; |
| 388 | const u64 size_in_bytes{framebuffer.stride * framebuffer.height * bytes_per_pixel}; | 390 | const u64 size_in_bytes{framebuffer.stride * framebuffer.height * bytes_per_pixel}; |
| 389 | u8* const host_ptr{system.Memory().GetPointer(framebuffer_addr)}; | 391 | u8* const host_ptr{cpu_memory.GetPointer(framebuffer_addr)}; |
| 390 | rasterizer->FlushRegion(ToCacheAddr(host_ptr), size_in_bytes); | 392 | rasterizer->FlushRegion(ToCacheAddr(host_ptr), size_in_bytes); |
| 391 | 393 | ||
| 392 | // TODO(Rodrigo): Read this from HLE | 394 | // TODO(Rodrigo): Read this from HLE |
| @@ -471,7 +473,6 @@ void RendererOpenGL::AddTelemetryFields() { | |||
| 471 | LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); | 473 | LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor); |
| 472 | LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); | 474 | LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model); |
| 473 | 475 | ||
| 474 | auto& telemetry_session = system.TelemetrySession(); | ||
| 475 | constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; | 476 | constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; |
| 476 | telemetry_session.AddField(user_system, "GPU_Vendor", gpu_vendor); | 477 | telemetry_session.AddField(user_system, "GPU_Vendor", gpu_vendor); |
| 477 | telemetry_session.AddField(user_system, "GPU_Model", gpu_model); | 478 | telemetry_session.AddField(user_system, "GPU_Model", gpu_model); |
| @@ -482,8 +483,8 @@ void RendererOpenGL::CreateRasterizer() { | |||
| 482 | if (rasterizer) { | 483 | if (rasterizer) { |
| 483 | return; | 484 | return; |
| 484 | } | 485 | } |
| 485 | rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, device, screen_info, | 486 | rasterizer = std::make_unique<RasterizerOpenGL>(emu_window, gpu, cpu_memory, device, |
| 486 | program_manager, state_tracker); | 487 | screen_info, program_manager, state_tracker); |
| 487 | } | 488 | } |
| 488 | 489 | ||
| 489 | void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | 490 | void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 52ea76b7d..5329577fb 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -16,16 +16,25 @@ | |||
| 16 | 16 | ||
| 17 | namespace Core { | 17 | namespace Core { |
| 18 | class System; | 18 | class System; |
| 19 | } | 19 | class TelemetrySession; |
| 20 | } // namespace Core | ||
| 20 | 21 | ||
| 21 | namespace Core::Frontend { | 22 | namespace Core::Frontend { |
| 22 | class EmuWindow; | 23 | class EmuWindow; |
| 23 | } | 24 | } |
| 24 | 25 | ||
| 26 | namespace Core::Memory { | ||
| 27 | class Memory; | ||
| 28 | } | ||
| 29 | |||
| 25 | namespace Layout { | 30 | namespace Layout { |
| 26 | struct FramebufferLayout; | 31 | struct FramebufferLayout; |
| 27 | } | 32 | } |
| 28 | 33 | ||
| 34 | namespace Tegra { | ||
| 35 | class GPU; | ||
| 36 | } | ||
| 37 | |||
| 29 | namespace OpenGL { | 38 | namespace OpenGL { |
| 30 | 39 | ||
| 31 | /// Structure used for storing information about the textures for the Switch screen | 40 | /// Structure used for storing information about the textures for the Switch screen |
| @@ -56,7 +65,8 @@ class FrameMailbox; | |||
| 56 | 65 | ||
| 57 | class RendererOpenGL final : public VideoCore::RendererBase { | 66 | class RendererOpenGL final : public VideoCore::RendererBase { |
| 58 | public: | 67 | public: |
| 59 | explicit RendererOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 68 | explicit RendererOpenGL(Core::TelemetrySession& telemetry_session, |
| 69 | Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory, | ||
| 60 | Tegra::GPU& gpu, | 70 | Tegra::GPU& gpu, |
| 61 | std::unique_ptr<Core::Frontend::GraphicsContext> context); | 71 | std::unique_ptr<Core::Frontend::GraphicsContext> context); |
| 62 | ~RendererOpenGL() override; | 72 | ~RendererOpenGL() override; |
| @@ -94,12 +104,13 @@ private: | |||
| 94 | 104 | ||
| 95 | bool Present(int timeout_ms); | 105 | bool Present(int timeout_ms); |
| 96 | 106 | ||
| 97 | Core::System& system; | 107 | Core::TelemetrySession& telemetry_session; |
| 98 | Core::Frontend::EmuWindow& emu_window; | 108 | Core::Frontend::EmuWindow& emu_window; |
| 109 | Core::Memory::Memory& cpu_memory; | ||
| 99 | Tegra::GPU& gpu; | 110 | Tegra::GPU& gpu; |
| 100 | const Device device; | ||
| 101 | 111 | ||
| 102 | StateTracker state_tracker{system}; | 112 | const Device device; |
| 113 | StateTracker state_tracker{gpu}; | ||
| 103 | 114 | ||
| 104 | // OpenGL object IDs | 115 | // OpenGL object IDs |
| 105 | OGLBuffer vertex_buffer; | 116 | OGLBuffer vertex_buffer; |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index ae46e0444..0e4583986 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -86,7 +86,7 @@ Common::DynamicLibrary OpenVulkanLibrary() { | |||
| 86 | if (!library.Open(filename.c_str())) { | 86 | if (!library.Open(filename.c_str())) { |
| 87 | // Android devices may not have libvulkan.so.1, only libvulkan.so. | 87 | // Android devices may not have libvulkan.so.1, only libvulkan.so. |
| 88 | filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); | 88 | filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); |
| 89 | library.Open(filename.c_str()); | 89 | (void)library.Open(filename.c_str()); |
| 90 | } | 90 | } |
| 91 | #endif | 91 | #endif |
| 92 | return library; | 92 | return library; |
| @@ -237,10 +237,12 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext | |||
| 237 | 237 | ||
| 238 | } // Anonymous namespace | 238 | } // Anonymous namespace |
| 239 | 239 | ||
| 240 | RendererVulkan::RendererVulkan(Core::System& system_, Core::Frontend::EmuWindow& emu_window, | 240 | RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, |
| 241 | Tegra::GPU& gpu_, | 241 | Core::Frontend::EmuWindow& emu_window, |
| 242 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, | ||
| 242 | std::unique_ptr<Core::Frontend::GraphicsContext> context) | 243 | std::unique_ptr<Core::Frontend::GraphicsContext> context) |
| 243 | : RendererBase{emu_window, std::move(context)}, system{system_}, gpu{gpu_} {} | 244 | : RendererBase{emu_window, std::move(context)}, telemetry_session{telemetry_session_}, |
| 245 | cpu_memory{cpu_memory_}, gpu{gpu_} {} | ||
| 244 | 246 | ||
| 245 | RendererVulkan::~RendererVulkan() { | 247 | RendererVulkan::~RendererVulkan() { |
| 246 | ShutDown(); | 248 | ShutDown(); |
| @@ -304,15 +306,15 @@ bool RendererVulkan::Init() { | |||
| 304 | swapchain = std::make_unique<VKSwapchain>(*surface, *device); | 306 | swapchain = std::make_unique<VKSwapchain>(*surface, *device); |
| 305 | swapchain->Create(framebuffer.width, framebuffer.height, false); | 307 | swapchain->Create(framebuffer.width, framebuffer.height, false); |
| 306 | 308 | ||
| 307 | state_tracker = std::make_unique<StateTracker>(system); | 309 | state_tracker = std::make_unique<StateTracker>(gpu); |
| 308 | 310 | ||
| 309 | scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker); | 311 | scheduler = std::make_unique<VKScheduler>(*device, *resource_manager, *state_tracker); |
| 310 | 312 | ||
| 311 | rasterizer = std::make_unique<RasterizerVulkan>(system, render_window, screen_info, *device, | 313 | rasterizer = std::make_unique<RasterizerVulkan>( |
| 312 | *resource_manager, *memory_manager, | 314 | render_window, gpu, gpu.MemoryManager(), cpu_memory, screen_info, *device, |
| 313 | *state_tracker, *scheduler); | 315 | *resource_manager, *memory_manager, *state_tracker, *scheduler); |
| 314 | 316 | ||
| 315 | blit_screen = std::make_unique<VKBlitScreen>(system, render_window, *rasterizer, *device, | 317 | blit_screen = std::make_unique<VKBlitScreen>(cpu_memory, render_window, *rasterizer, *device, |
| 316 | *resource_manager, *memory_manager, *swapchain, | 318 | *resource_manager, *memory_manager, *swapchain, |
| 317 | *scheduler, screen_info); | 319 | *scheduler, screen_info); |
| 318 | 320 | ||
| @@ -440,8 +442,7 @@ void RendererVulkan::Report() const { | |||
| 440 | LOG_INFO(Render_Vulkan, "Device: {}", model_name); | 442 | LOG_INFO(Render_Vulkan, "Device: {}", model_name); |
| 441 | LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version); | 443 | LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version); |
| 442 | 444 | ||
| 443 | auto& telemetry_session = system.TelemetrySession(); | 445 | static constexpr auto field = Common::Telemetry::FieldType::UserSystem; |
| 444 | constexpr auto field = Common::Telemetry::FieldType::UserSystem; | ||
| 445 | telemetry_session.AddField(field, "GPU_Vendor", vendor_name); | 446 | telemetry_session.AddField(field, "GPU_Vendor", vendor_name); |
| 446 | telemetry_session.AddField(field, "GPU_Model", model_name); | 447 | telemetry_session.AddField(field, "GPU_Model", model_name); |
| 447 | telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name); | 448 | telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name); |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 13debbbc0..ddff77942 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -14,7 +14,15 @@ | |||
| 14 | #include "video_core/renderer_vulkan/wrapper.h" | 14 | #include "video_core/renderer_vulkan/wrapper.h" |
| 15 | 15 | ||
| 16 | namespace Core { | 16 | namespace Core { |
| 17 | class System; | 17 | class TelemetrySession; |
| 18 | } | ||
| 19 | |||
| 20 | namespace Core::Memory { | ||
| 21 | class Memory; | ||
| 22 | } | ||
| 23 | |||
| 24 | namespace Tegra { | ||
| 25 | class GPU; | ||
| 18 | } | 26 | } |
| 19 | 27 | ||
| 20 | namespace Vulkan { | 28 | namespace Vulkan { |
| @@ -38,7 +46,8 @@ struct VKScreenInfo { | |||
| 38 | 46 | ||
| 39 | class RendererVulkan final : public VideoCore::RendererBase { | 47 | class RendererVulkan final : public VideoCore::RendererBase { |
| 40 | public: | 48 | public: |
| 41 | explicit RendererVulkan(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 49 | explicit RendererVulkan(Core::TelemetrySession& telemtry_session, |
| 50 | Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory, | ||
| 42 | Tegra::GPU& gpu, | 51 | Tegra::GPU& gpu, |
| 43 | std::unique_ptr<Core::Frontend::GraphicsContext> context); | 52 | std::unique_ptr<Core::Frontend::GraphicsContext> context); |
| 44 | ~RendererVulkan() override; | 53 | ~RendererVulkan() override; |
| @@ -59,7 +68,8 @@ private: | |||
| 59 | 68 | ||
| 60 | void Report() const; | 69 | void Report() const; |
| 61 | 70 | ||
| 62 | Core::System& system; | 71 | Core::TelemetrySession& telemetry_session; |
| 72 | Core::Memory::Memory& cpu_memory; | ||
| 63 | Tegra::GPU& gpu; | 73 | Tegra::GPU& gpu; |
| 64 | 74 | ||
| 65 | Common::DynamicLibrary library; | 75 | Common::DynamicLibrary library; |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index a551e3de8..2bea7b24d 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -210,14 +210,16 @@ struct VKBlitScreen::BufferData { | |||
| 210 | // Unaligned image data goes here | 210 | // Unaligned image data goes here |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | VKBlitScreen::VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window, | 213 | VKBlitScreen::VKBlitScreen(Core::Memory::Memory& cpu_memory_, |
| 214 | VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, | 214 | Core::Frontend::EmuWindow& render_window_, |
| 215 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, | 215 | VideoCore::RasterizerInterface& rasterizer_, const VKDevice& device_, |
| 216 | VKSwapchain& swapchain, VKScheduler& scheduler, | 216 | VKResourceManager& resource_manager_, VKMemoryManager& memory_manager_, |
| 217 | const VKScreenInfo& screen_info) | 217 | VKSwapchain& swapchain_, VKScheduler& scheduler_, |
| 218 | : system{system}, render_window{render_window}, rasterizer{rasterizer}, device{device}, | 218 | const VKScreenInfo& screen_info_) |
| 219 | resource_manager{resource_manager}, memory_manager{memory_manager}, swapchain{swapchain}, | 219 | : cpu_memory{cpu_memory_}, render_window{render_window_}, |
| 220 | scheduler{scheduler}, image_count{swapchain.GetImageCount()}, screen_info{screen_info} { | 220 | rasterizer{rasterizer_}, device{device_}, resource_manager{resource_manager_}, |
| 221 | memory_manager{memory_manager_}, swapchain{swapchain_}, scheduler{scheduler_}, | ||
| 222 | image_count{swapchain.GetImageCount()}, screen_info{screen_info_} { | ||
| 221 | watches.resize(image_count); | 223 | watches.resize(image_count); |
| 222 | std::generate(watches.begin(), watches.end(), | 224 | std::generate(watches.begin(), watches.end(), |
| 223 | []() { return std::make_unique<VKFenceWatch>(); }); | 225 | []() { return std::make_unique<VKFenceWatch>(); }); |
| @@ -259,7 +261,7 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon | |||
| 259 | const auto pixel_format = | 261 | const auto pixel_format = |
| 260 | VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); | 262 | VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format); |
| 261 | const VAddr framebuffer_addr = framebuffer.address + framebuffer.offset; | 263 | const VAddr framebuffer_addr = framebuffer.address + framebuffer.offset; |
| 262 | const auto host_ptr = system.Memory().GetPointer(framebuffer_addr); | 264 | const auto host_ptr = cpu_memory.GetPointer(framebuffer_addr); |
| 263 | rasterizer.FlushRegion(ToCacheAddr(host_ptr), GetSizeInBytes(framebuffer)); | 265 | rasterizer.FlushRegion(ToCacheAddr(host_ptr), GetSizeInBytes(framebuffer)); |
| 264 | 266 | ||
| 265 | // TODO(Rodrigo): Read this from HLE | 267 | // TODO(Rodrigo): Read this from HLE |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h index 243640fab..838d38f69 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.h +++ b/src/video_core/renderer_vulkan/vk_blit_screen.h | |||
| @@ -15,6 +15,10 @@ namespace Core { | |||
| 15 | class System; | 15 | class System; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | namespace Core::Memory { | ||
| 19 | class Memory; | ||
| 20 | } | ||
| 21 | |||
| 18 | namespace Core::Frontend { | 22 | namespace Core::Frontend { |
| 19 | class EmuWindow; | 23 | class EmuWindow; |
| 20 | } | 24 | } |
| @@ -39,7 +43,8 @@ class VKSwapchain; | |||
| 39 | 43 | ||
| 40 | class VKBlitScreen final { | 44 | class VKBlitScreen final { |
| 41 | public: | 45 | public: |
| 42 | explicit VKBlitScreen(Core::System& system, Core::Frontend::EmuWindow& render_window, | 46 | explicit VKBlitScreen(Core::Memory::Memory& cpu_memory, |
| 47 | Core::Frontend::EmuWindow& render_window, | ||
| 43 | VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, | 48 | VideoCore::RasterizerInterface& rasterizer, const VKDevice& device, |
| 44 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, | 49 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, |
| 45 | VKSwapchain& swapchain, VKScheduler& scheduler, | 50 | VKSwapchain& swapchain, VKScheduler& scheduler, |
| @@ -81,7 +86,7 @@ private: | |||
| 81 | u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, | 86 | u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, |
| 82 | std::size_t image_index) const; | 87 | std::size_t image_index) const; |
| 83 | 88 | ||
| 84 | Core::System& system; | 89 | Core::Memory::Memory& cpu_memory; |
| 85 | Core::Frontend::EmuWindow& render_window; | 90 | Core::Frontend::EmuWindow& render_window; |
| 86 | VideoCore::RasterizerInterface& rasterizer; | 91 | VideoCore::RasterizerInterface& rasterizer; |
| 87 | const VKDevice& device; | 92 | const VKDevice& device; |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 1d2f8b557..d9d3da9ea 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -145,14 +145,15 @@ void Buffer::CopyFrom(const Buffer& src, std::size_t src_offset, std::size_t dst | |||
| 145 | }); | 145 | }); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, | 148 | VKBufferCache::VKBufferCache(VideoCore::RasterizerInterface& rasterizer, |
| 149 | const VKDevice& device, VKMemoryManager& memory_manager, | 149 | Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory, |
| 150 | VKScheduler& scheduler, VKStagingBufferPool& staging_pool) | 150 | const VKDevice& device_, VKMemoryManager& memory_manager_, |
| 151 | : VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, system, | 151 | VKScheduler& scheduler_, VKStagingBufferPool& staging_pool_) |
| 152 | CreateStreamBuffer(device, | 152 | : VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer>{rasterizer, gpu_memory, cpu_memory, |
| 153 | scheduler)}, | 153 | CreateStreamBuffer(device_, |
| 154 | device{device}, memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{ | 154 | scheduler_)}, |
| 155 | staging_pool} {} | 155 | device{device_}, memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{ |
| 156 | staging_pool_} {} | ||
| 156 | 157 | ||
| 157 | VKBufferCache::~VKBufferCache() = default; | 158 | VKBufferCache::~VKBufferCache() = default; |
| 158 | 159 | ||
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 991ee451c..7fb5ceedf 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h | |||
| @@ -13,10 +13,6 @@ | |||
| 13 | #include "video_core/renderer_vulkan/vk_stream_buffer.h" | 13 | #include "video_core/renderer_vulkan/vk_stream_buffer.h" |
| 14 | #include "video_core/renderer_vulkan/wrapper.h" | 14 | #include "video_core/renderer_vulkan/wrapper.h" |
| 15 | 15 | ||
| 16 | namespace Core { | ||
| 17 | class System; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Vulkan { | 16 | namespace Vulkan { |
| 21 | 17 | ||
| 22 | class VKDevice; | 18 | class VKDevice; |
| @@ -53,7 +49,8 @@ private: | |||
| 53 | 49 | ||
| 54 | class VKBufferCache final : public VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer> { | 50 | class VKBufferCache final : public VideoCommon::BufferCache<Buffer, VkBuffer, VKStreamBuffer> { |
| 55 | public: | 51 | public: |
| 56 | explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer, Core::System& system, | 52 | explicit VKBufferCache(VideoCore::RasterizerInterface& rasterizer, |
| 53 | Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory, | ||
| 57 | const VKDevice& device, VKMemoryManager& memory_manager, | 54 | const VKDevice& device, VKMemoryManager& memory_manager, |
| 58 | VKScheduler& scheduler, VKStagingBufferPool& staging_pool); | 55 | VKScheduler& scheduler, VKStagingBufferPool& staging_pool); |
| 59 | ~VKBufferCache(); | 56 | ~VKBufferCache(); |
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp index d7f65d435..55a8348fc 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp | |||
| @@ -71,12 +71,12 @@ bool InnerFence::IsEventSignalled() const { | |||
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | VKFenceManager::VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 74 | VKFenceManager::VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, |
| 75 | const VKDevice& device, VKScheduler& scheduler, | 75 | Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache, |
| 76 | VKTextureCache& texture_cache, VKBufferCache& buffer_cache, | 76 | VKBufferCache& buffer_cache, VKQueryCache& query_cache, |
| 77 | VKQueryCache& query_cache) | 77 | const VKDevice& device_, VKScheduler& scheduler_) |
| 78 | : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache), | 78 | : GenericFenceManager(rasterizer, gpu, texture_cache, buffer_cache, query_cache), |
| 79 | device{device}, scheduler{scheduler} {} | 79 | device{device_}, scheduler{scheduler_} {} |
| 80 | 80 | ||
| 81 | Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) { | 81 | Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) { |
| 82 | return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed); | 82 | return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed); |
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h index 043fe7947..1547d6d30 100644 --- a/src/video_core/renderer_vulkan/vk_fence_manager.h +++ b/src/video_core/renderer_vulkan/vk_fence_manager.h | |||
| @@ -55,10 +55,10 @@ using GenericFenceManager = | |||
| 55 | 55 | ||
| 56 | class VKFenceManager final : public GenericFenceManager { | 56 | class VKFenceManager final : public GenericFenceManager { |
| 57 | public: | 57 | public: |
| 58 | explicit VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 58 | explicit VKFenceManager(VideoCore::RasterizerInterface& rasterizer, Tegra::GPU& gpu, |
| 59 | const VKDevice& device, VKScheduler& scheduler, | 59 | Tegra::MemoryManager& memory_manager, VKTextureCache& texture_cache, |
| 60 | VKTextureCache& texture_cache, VKBufferCache& buffer_cache, | 60 | VKBufferCache& buffer_cache, VKQueryCache& query_cache, |
| 61 | VKQueryCache& query_cache); | 61 | const VKDevice& device, VKScheduler& scheduler); |
| 62 | 62 | ||
| 63 | protected: | 63 | protected: |
| 64 | Fence CreateFence(u32 value, bool is_stubbed) override; | 64 | Fence CreateFence(u32 value, bool is_stubbed) override; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index cfdcdd6ab..5c038f4bc 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -135,64 +135,56 @@ bool ComputePipelineCacheKey::operator==(const ComputePipelineCacheKey& rhs) con | |||
| 135 | return std::memcmp(&rhs, this, sizeof *this) == 0; | 135 | return std::memcmp(&rhs, this, sizeof *this) == 0; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | Shader::Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, | 138 | Shader::Shader(Tegra::Engines::ConstBufferEngineInterface& engine, Tegra::Engines::ShaderType stage, |
| 139 | VideoCommon::Shader::ProgramCode program_code, u32 main_offset) | 139 | GPUVAddr gpu_addr_, VAddr cpu_addr, VideoCommon::Shader::ProgramCode program_code_, |
| 140 | : gpu_addr{gpu_addr}, program_code{std::move(program_code)}, | 140 | u32 main_offset) |
| 141 | registry{stage, GetEngine(system, stage)}, shader_ir{this->program_code, main_offset, | 141 | : gpu_addr(gpu_addr_), program_code(std::move(program_code_)), registry(stage, engine), |
| 142 | compiler_settings, registry}, | 142 | shader_ir(program_code, main_offset, compiler_settings, registry), |
| 143 | entries{GenerateShaderEntries(shader_ir)} {} | 143 | entries(GenerateShaderEntries(shader_ir)) {} |
| 144 | 144 | ||
| 145 | Shader::~Shader() = default; | 145 | Shader::~Shader() = default; |
| 146 | 146 | ||
| 147 | Tegra::Engines::ConstBufferEngineInterface& Shader::GetEngine(Core::System& system, | 147 | VKPipelineCache::VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu_, |
| 148 | Tegra::Engines::ShaderType stage) { | 148 | Tegra::Engines::Maxwell3D& maxwell3d_, |
| 149 | if (stage == ShaderType::Compute) { | 149 | Tegra::Engines::KeplerCompute& kepler_compute_, |
| 150 | return system.GPU().KeplerCompute(); | 150 | Tegra::MemoryManager& gpu_memory_, const VKDevice& device_, |
| 151 | } else { | 151 | VKScheduler& scheduler_, VKDescriptorPool& descriptor_pool_, |
| 152 | return system.GPU().Maxwell3D(); | 152 | VKUpdateDescriptorQueue& update_descriptor_queue_, |
| 153 | } | 153 | VKRenderPassCache& renderpass_cache_) |
| 154 | } | 154 | : VideoCommon::ShaderCache<Shader>{rasterizer}, gpu{gpu_}, maxwell3d{maxwell3d_}, |
| 155 | 155 | kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_}, device{device_}, | |
| 156 | VKPipelineCache::VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, | 156 | scheduler{scheduler_}, descriptor_pool{descriptor_pool_}, |
| 157 | const VKDevice& device, VKScheduler& scheduler, | 157 | update_descriptor_queue{update_descriptor_queue_}, renderpass_cache{renderpass_cache_} {} |
| 158 | VKDescriptorPool& descriptor_pool, | ||
| 159 | VKUpdateDescriptorQueue& update_descriptor_queue, | ||
| 160 | VKRenderPassCache& renderpass_cache) | ||
| 161 | : VideoCommon::ShaderCache<Shader>{rasterizer}, system{system}, device{device}, | ||
| 162 | scheduler{scheduler}, descriptor_pool{descriptor_pool}, | ||
| 163 | update_descriptor_queue{update_descriptor_queue}, renderpass_cache{renderpass_cache} {} | ||
| 164 | 158 | ||
| 165 | VKPipelineCache::~VKPipelineCache() = default; | 159 | VKPipelineCache::~VKPipelineCache() = default; |
| 166 | 160 | ||
| 167 | std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | 161 | std::array<Shader*, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { |
| 168 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 169 | |||
| 170 | std::array<Shader*, Maxwell::MaxShaderProgram> shaders{}; | 162 | std::array<Shader*, Maxwell::MaxShaderProgram> shaders{}; |
| 163 | |||
| 171 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 164 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| 172 | const auto program{static_cast<Maxwell::ShaderProgram>(index)}; | 165 | const auto program{static_cast<Maxwell::ShaderProgram>(index)}; |
| 173 | 166 | ||
| 174 | // Skip stages that are not enabled | 167 | // Skip stages that are not enabled |
| 175 | if (!gpu.regs.IsShaderConfigEnabled(index)) { | 168 | if (!maxwell3d.regs.IsShaderConfigEnabled(index)) { |
| 176 | continue; | 169 | continue; |
| 177 | } | 170 | } |
| 178 | 171 | ||
| 179 | auto& memory_manager{system.GPU().MemoryManager()}; | 172 | const GPUVAddr gpu_addr{GetShaderAddress(maxwell3d, program)}; |
| 180 | const GPUVAddr program_addr{GetShaderAddress(system, program)}; | 173 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 181 | const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr); | ||
| 182 | ASSERT(cpu_addr); | 174 | ASSERT(cpu_addr); |
| 183 | 175 | ||
| 184 | Shader* result = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); | 176 | Shader* result = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); |
| 185 | if (!result) { | 177 | if (!result) { |
| 186 | const auto host_ptr{memory_manager.GetPointer(program_addr)}; | 178 | const u8* const host_ptr{gpu_memory.GetPointer(gpu_addr)}; |
| 187 | 179 | ||
| 188 | // No shader found - create a new one | 180 | // No shader found - create a new one |
| 189 | constexpr u32 stage_offset = STAGE_MAIN_OFFSET; | 181 | static constexpr u32 stage_offset = STAGE_MAIN_OFFSET; |
| 190 | const auto stage = static_cast<ShaderType>(index == 0 ? 0 : index - 1); | 182 | const auto stage = static_cast<ShaderType>(index == 0 ? 0 : index - 1); |
| 191 | ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, false); | 183 | ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, false); |
| 192 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 184 | const std::size_t size_in_bytes = code.size() * sizeof(u64); |
| 193 | 185 | ||
| 194 | auto shader = std::make_unique<Shader>(system, stage, program_addr, std::move(code), | 186 | auto shader = std::make_unique<Shader>(maxwell3d, stage, gpu_addr, *cpu_addr, |
| 195 | stage_offset); | 187 | std::move(code), stage_offset); |
| 196 | result = shader.get(); | 188 | result = shader.get(); |
| 197 | 189 | ||
| 198 | if (cpu_addr) { | 190 | if (cpu_addr) { |
| @@ -215,11 +207,11 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( | |||
| 215 | } | 207 | } |
| 216 | last_graphics_key = key; | 208 | last_graphics_key = key; |
| 217 | 209 | ||
| 218 | if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(system.GPU())) { | 210 | if (device.UseAsynchronousShaders() && async_shaders.IsShaderAsync(gpu)) { |
| 219 | std::unique_lock lock{pipeline_cache}; | 211 | std::unique_lock lock{pipeline_cache}; |
| 220 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | 212 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); |
| 221 | if (is_cache_miss) { | 213 | if (is_cache_miss) { |
| 222 | system.GPU().ShaderNotify().MarkSharderBuilding(); | 214 | gpu.ShaderNotify().MarkSharderBuilding(); |
| 223 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | 215 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |
| 224 | const auto [program, bindings] = DecompileShaders(key.fixed_state); | 216 | const auto [program, bindings] = DecompileShaders(key.fixed_state); |
| 225 | async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool, | 217 | async_shaders.QueueVulkanShader(this, device, scheduler, descriptor_pool, |
| @@ -233,13 +225,13 @@ VKGraphicsPipeline* VKPipelineCache::GetGraphicsPipeline( | |||
| 233 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); | 225 | const auto [pair, is_cache_miss] = graphics_cache.try_emplace(key); |
| 234 | auto& entry = pair->second; | 226 | auto& entry = pair->second; |
| 235 | if (is_cache_miss) { | 227 | if (is_cache_miss) { |
| 236 | system.GPU().ShaderNotify().MarkSharderBuilding(); | 228 | gpu.ShaderNotify().MarkSharderBuilding(); |
| 237 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | 229 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |
| 238 | const auto [program, bindings] = DecompileShaders(key.fixed_state); | 230 | const auto [program, bindings] = DecompileShaders(key.fixed_state); |
| 239 | entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool, | 231 | entry = std::make_unique<VKGraphicsPipeline>(device, scheduler, descriptor_pool, |
| 240 | update_descriptor_queue, renderpass_cache, key, | 232 | update_descriptor_queue, renderpass_cache, key, |
| 241 | bindings, program); | 233 | bindings, program); |
| 242 | system.GPU().ShaderNotify().MarkShaderComplete(); | 234 | gpu.ShaderNotify().MarkShaderComplete(); |
| 243 | } | 235 | } |
| 244 | last_graphics_pipeline = entry.get(); | 236 | last_graphics_pipeline = entry.get(); |
| 245 | return last_graphics_pipeline; | 237 | return last_graphics_pipeline; |
| @@ -255,22 +247,21 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 255 | } | 247 | } |
| 256 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); | 248 | LOG_INFO(Render_Vulkan, "Compile 0x{:016X}", key.Hash()); |
| 257 | 249 | ||
| 258 | auto& memory_manager = system.GPU().MemoryManager(); | 250 | const GPUVAddr gpu_addr = key.shader; |
| 259 | const auto program_addr = key.shader; | ||
| 260 | 251 | ||
| 261 | const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr); | 252 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 262 | ASSERT(cpu_addr); | 253 | ASSERT(cpu_addr); |
| 263 | 254 | ||
| 264 | Shader* shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get(); | 255 | Shader* shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel.get(); |
| 265 | if (!shader) { | 256 | if (!shader) { |
| 266 | // No shader found - create a new one | 257 | // No shader found - create a new one |
| 267 | const auto host_ptr = memory_manager.GetPointer(program_addr); | 258 | const auto host_ptr = gpu_memory.GetPointer(gpu_addr); |
| 268 | 259 | ||
| 269 | ProgramCode code = GetShaderCode(memory_manager, program_addr, host_ptr, true); | 260 | ProgramCode code = GetShaderCode(gpu_memory, gpu_addr, host_ptr, true); |
| 270 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 261 | const std::size_t size_in_bytes = code.size() * sizeof(u64); |
| 271 | 262 | ||
| 272 | auto shader_info = std::make_unique<Shader>(system, ShaderType::Compute, program_addr, | 263 | auto shader_info = std::make_unique<Shader>(kepler_compute, ShaderType::Compute, gpu_addr, |
| 273 | std::move(code), KERNEL_MAIN_OFFSET); | 264 | *cpu_addr, std::move(code), KERNEL_MAIN_OFFSET); |
| 274 | shader = shader_info.get(); | 265 | shader = shader_info.get(); |
| 275 | 266 | ||
| 276 | if (cpu_addr) { | 267 | if (cpu_addr) { |
| @@ -298,7 +289,7 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 298 | } | 289 | } |
| 299 | 290 | ||
| 300 | void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { | 291 | void VKPipelineCache::EmplacePipeline(std::unique_ptr<VKGraphicsPipeline> pipeline) { |
| 301 | system.GPU().ShaderNotify().MarkShaderComplete(); | 292 | gpu.ShaderNotify().MarkShaderComplete(); |
| 302 | std::unique_lock lock{pipeline_cache}; | 293 | std::unique_lock lock{pipeline_cache}; |
| 303 | graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline); | 294 | graphics_cache.at(pipeline->GetCacheKey()) = std::move(pipeline); |
| 304 | } | 295 | } |
| @@ -339,9 +330,6 @@ void VKPipelineCache::OnShaderRemoval(Shader* shader) { | |||
| 339 | 330 | ||
| 340 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> | 331 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> |
| 341 | VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { | 332 | VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { |
| 342 | auto& memory_manager = system.GPU().MemoryManager(); | ||
| 343 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 344 | |||
| 345 | Specialization specialization; | 333 | Specialization specialization; |
| 346 | if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points || | 334 | if (fixed_state.dynamic_state.Topology() == Maxwell::PrimitiveTopology::Points || |
| 347 | device.IsExtExtendedDynamicStateSupported()) { | 335 | device.IsExtExtendedDynamicStateSupported()) { |
| @@ -364,12 +352,12 @@ VKPipelineCache::DecompileShaders(const FixedPipelineState& fixed_state) { | |||
| 364 | const auto program_enum = static_cast<Maxwell::ShaderProgram>(index); | 352 | const auto program_enum = static_cast<Maxwell::ShaderProgram>(index); |
| 365 | 353 | ||
| 366 | // Skip stages that are not enabled | 354 | // Skip stages that are not enabled |
| 367 | if (!gpu.regs.IsShaderConfigEnabled(index)) { | 355 | if (!maxwell3d.regs.IsShaderConfigEnabled(index)) { |
| 368 | continue; | 356 | continue; |
| 369 | } | 357 | } |
| 370 | 358 | ||
| 371 | const GPUVAddr gpu_addr = GetShaderAddress(system, program_enum); | 359 | const GPUVAddr gpu_addr = GetShaderAddress(maxwell3d, program_enum); |
| 372 | const std::optional<VAddr> cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr); | 360 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 373 | Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); | 361 | Shader* const shader = cpu_addr ? TryGet(*cpu_addr) : null_shader.get(); |
| 374 | 362 | ||
| 375 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 | 363 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index c04829e77..1a31fd9f6 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -85,7 +85,8 @@ namespace Vulkan { | |||
| 85 | 85 | ||
| 86 | class Shader { | 86 | class Shader { |
| 87 | public: | 87 | public: |
| 88 | explicit Shader(Core::System& system, Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, | 88 | explicit Shader(Tegra::Engines::ConstBufferEngineInterface& engine, |
| 89 | Tegra::Engines::ShaderType stage, GPUVAddr gpu_addr, VAddr cpu_addr, | ||
| 89 | VideoCommon::Shader::ProgramCode program_code, u32 main_offset); | 90 | VideoCommon::Shader::ProgramCode program_code, u32 main_offset); |
| 90 | ~Shader(); | 91 | ~Shader(); |
| 91 | 92 | ||
| @@ -97,22 +98,19 @@ public: | |||
| 97 | return shader_ir; | 98 | return shader_ir; |
| 98 | } | 99 | } |
| 99 | 100 | ||
| 100 | const VideoCommon::Shader::Registry& GetRegistry() const { | ||
| 101 | return registry; | ||
| 102 | } | ||
| 103 | |||
| 104 | const VideoCommon::Shader::ShaderIR& GetIR() const { | 101 | const VideoCommon::Shader::ShaderIR& GetIR() const { |
| 105 | return shader_ir; | 102 | return shader_ir; |
| 106 | } | 103 | } |
| 107 | 104 | ||
| 105 | const VideoCommon::Shader::Registry& GetRegistry() const { | ||
| 106 | return registry; | ||
| 107 | } | ||
| 108 | |||
| 108 | const ShaderEntries& GetEntries() const { | 109 | const ShaderEntries& GetEntries() const { |
| 109 | return entries; | 110 | return entries; |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | private: | 113 | private: |
| 113 | static Tegra::Engines::ConstBufferEngineInterface& GetEngine(Core::System& system, | ||
| 114 | Tegra::Engines::ShaderType stage); | ||
| 115 | |||
| 116 | GPUVAddr gpu_addr{}; | 114 | GPUVAddr gpu_addr{}; |
| 117 | VideoCommon::Shader::ProgramCode program_code; | 115 | VideoCommon::Shader::ProgramCode program_code; |
| 118 | VideoCommon::Shader::Registry registry; | 116 | VideoCommon::Shader::Registry registry; |
| @@ -122,9 +120,11 @@ private: | |||
| 122 | 120 | ||
| 123 | class VKPipelineCache final : public VideoCommon::ShaderCache<Shader> { | 121 | class VKPipelineCache final : public VideoCommon::ShaderCache<Shader> { |
| 124 | public: | 122 | public: |
| 125 | explicit VKPipelineCache(Core::System& system, RasterizerVulkan& rasterizer, | 123 | explicit VKPipelineCache(RasterizerVulkan& rasterizer, Tegra::GPU& gpu, |
| 126 | const VKDevice& device, VKScheduler& scheduler, | 124 | Tegra::Engines::Maxwell3D& maxwell3d, |
| 127 | VKDescriptorPool& descriptor_pool, | 125 | Tegra::Engines::KeplerCompute& kepler_compute, |
| 126 | Tegra::MemoryManager& gpu_memory, const VKDevice& device, | ||
| 127 | VKScheduler& scheduler, VKDescriptorPool& descriptor_pool, | ||
| 128 | VKUpdateDescriptorQueue& update_descriptor_queue, | 128 | VKUpdateDescriptorQueue& update_descriptor_queue, |
| 129 | VKRenderPassCache& renderpass_cache); | 129 | VKRenderPassCache& renderpass_cache); |
| 130 | ~VKPipelineCache() override; | 130 | ~VKPipelineCache() override; |
| @@ -145,7 +145,11 @@ private: | |||
| 145 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders( | 145 | std::pair<SPIRVProgram, std::vector<VkDescriptorSetLayoutBinding>> DecompileShaders( |
| 146 | const FixedPipelineState& fixed_state); | 146 | const FixedPipelineState& fixed_state); |
| 147 | 147 | ||
| 148 | Core::System& system; | 148 | Tegra::GPU& gpu; |
| 149 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 150 | Tegra::Engines::KeplerCompute& kepler_compute; | ||
| 151 | Tegra::MemoryManager& gpu_memory; | ||
| 152 | |||
| 149 | const VKDevice& device; | 153 | const VKDevice& device; |
| 150 | VKScheduler& scheduler; | 154 | VKScheduler& scheduler; |
| 151 | VKDescriptorPool& descriptor_pool; | 155 | VKDescriptorPool& descriptor_pool; |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 6cd63d090..5a97c959d 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp | |||
| @@ -68,10 +68,11 @@ void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) { | |||
| 68 | usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false; | 68 | usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | VKQueryCache::VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 71 | VKQueryCache::VKQueryCache(VideoCore::RasterizerInterface& rasterizer, |
| 72 | Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, | ||
| 72 | const VKDevice& device, VKScheduler& scheduler) | 73 | const VKDevice& device, VKScheduler& scheduler) |
| 73 | : VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, | 74 | : VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, |
| 74 | QueryPool>{system, rasterizer}, | 75 | QueryPool>{rasterizer, maxwell3d, gpu_memory}, |
| 75 | device{device}, scheduler{scheduler} { | 76 | device{device}, scheduler{scheduler} { |
| 76 | for (std::size_t i = 0; i < static_cast<std::size_t>(VideoCore::NumQueryTypes); ++i) { | 77 | for (std::size_t i = 0; i < static_cast<std::size_t>(VideoCore::NumQueryTypes); ++i) { |
| 77 | query_pools[i].Initialize(device, static_cast<VideoCore::QueryType>(i)); | 78 | query_pools[i].Initialize(device, static_cast<VideoCore::QueryType>(i)); |
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.h b/src/video_core/renderer_vulkan/vk_query_cache.h index 40119e6d3..9be996e55 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.h +++ b/src/video_core/renderer_vulkan/vk_query_cache.h | |||
| @@ -56,7 +56,8 @@ class VKQueryCache final | |||
| 56 | : public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, | 56 | : public VideoCommon::QueryCacheBase<VKQueryCache, CachedQuery, CounterStream, HostCounter, |
| 57 | QueryPool> { | 57 | QueryPool> { |
| 58 | public: | 58 | public: |
| 59 | explicit VKQueryCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 59 | explicit VKQueryCache(VideoCore::RasterizerInterface& rasterizer, |
| 60 | Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, | ||
| 60 | const VKDevice& device, VKScheduler& scheduler); | 61 | const VKDevice& device, VKScheduler& scheduler); |
| 61 | ~VKQueryCache(); | 62 | ~VKQueryCache(); |
| 62 | 63 | ||
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index ff1b52eab..bafebe294 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -381,28 +381,30 @@ void RasterizerVulkan::DrawParameters::Draw(vk::CommandBuffer cmdbuf) const { | |||
| 381 | } | 381 | } |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& renderer, | 384 | RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu_, |
| 385 | VKScreenInfo& screen_info, const VKDevice& device, | 385 | Tegra::MemoryManager& gpu_memory_, |
| 386 | VKResourceManager& resource_manager, | 386 | Core::Memory::Memory& cpu_memory, VKScreenInfo& screen_info_, |
| 387 | VKMemoryManager& memory_manager, StateTracker& state_tracker, | 387 | const VKDevice& device_, VKResourceManager& resource_manager_, |
| 388 | VKScheduler& scheduler) | 388 | VKMemoryManager& memory_manager_, StateTracker& state_tracker_, |
| 389 | : RasterizerAccelerated{system.Memory()}, system{system}, render_window{renderer}, | 389 | VKScheduler& scheduler_) |
| 390 | screen_info{screen_info}, device{device}, resource_manager{resource_manager}, | 390 | : RasterizerAccelerated(cpu_memory), gpu(gpu_), gpu_memory(gpu_memory_), |
| 391 | memory_manager{memory_manager}, state_tracker{state_tracker}, scheduler{scheduler}, | 391 | maxwell3d(gpu.Maxwell3D()), kepler_compute(gpu.KeplerCompute()), screen_info(screen_info_), |
| 392 | device(device_), resource_manager(resource_manager_), memory_manager(memory_manager_), | ||
| 393 | state_tracker(state_tracker_), scheduler(scheduler_), | ||
| 392 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), | 394 | staging_pool(device, memory_manager, scheduler), descriptor_pool(device), |
| 393 | update_descriptor_queue(device, scheduler), renderpass_cache(device), | 395 | update_descriptor_queue(device, scheduler), renderpass_cache(device), |
| 394 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 396 | quad_array_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 395 | quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 397 | quad_indexed_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 396 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 398 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), |
| 397 | texture_cache(system, *this, device, resource_manager, memory_manager, scheduler, | 399 | texture_cache(*this, maxwell3d, gpu_memory, device, resource_manager, memory_manager, |
| 398 | staging_pool), | 400 | scheduler, staging_pool), |
| 399 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, | 401 | pipeline_cache(*this, gpu, maxwell3d, kepler_compute, gpu_memory, device, scheduler, |
| 400 | renderpass_cache), | 402 | descriptor_pool, update_descriptor_queue, renderpass_cache), |
| 401 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), | 403 | buffer_cache(*this, gpu_memory, cpu_memory, device, memory_manager, scheduler, staging_pool), |
| 402 | sampler_cache(device), | 404 | sampler_cache(device), query_cache(*this, maxwell3d, gpu_memory, device, scheduler), |
| 403 | fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), | 405 | fence_manager(*this, gpu, gpu_memory, texture_cache, buffer_cache, query_cache, device, |
| 404 | query_cache(system, *this, device, scheduler), | 406 | scheduler), |
| 405 | wfi_event{device.GetLogical().CreateNewEvent()}, async_shaders{renderer} { | 407 | wfi_event(device.GetLogical().CreateNewEvent()), async_shaders(emu_window) { |
| 406 | scheduler.SetQueryCache(query_cache); | 408 | scheduler.SetQueryCache(query_cache); |
| 407 | if (device.UseAsynchronousShaders()) { | 409 | if (device.UseAsynchronousShaders()) { |
| 408 | async_shaders.AllocateWorkers(); | 410 | async_shaders.AllocateWorkers(); |
| @@ -414,15 +416,13 @@ RasterizerVulkan::~RasterizerVulkan() = default; | |||
| 414 | void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | 416 | void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { |
| 415 | MICROPROFILE_SCOPE(Vulkan_Drawing); | 417 | MICROPROFILE_SCOPE(Vulkan_Drawing); |
| 416 | 418 | ||
| 419 | SCOPE_EXIT({ gpu.TickWork(); }); | ||
| 417 | FlushWork(); | 420 | FlushWork(); |
| 418 | 421 | ||
| 419 | query_cache.UpdateCounters(); | 422 | query_cache.UpdateCounters(); |
| 420 | 423 | ||
| 421 | SCOPE_EXIT({ system.GPU().TickWork(); }); | ||
| 422 | |||
| 423 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 424 | GraphicsPipelineCacheKey key; | 424 | GraphicsPipelineCacheKey key; |
| 425 | key.fixed_state.Fill(gpu.regs, device.IsExtExtendedDynamicStateSupported()); | 425 | key.fixed_state.Fill(maxwell3d.regs, device.IsExtExtendedDynamicStateSupported()); |
| 426 | 426 | ||
| 427 | buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); | 427 | buffer_cache.Map(CalculateGraphicsStreamBufferSize(is_indexed)); |
| 428 | 428 | ||
| @@ -480,8 +480,7 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 480 | void RasterizerVulkan::Clear() { | 480 | void RasterizerVulkan::Clear() { |
| 481 | MICROPROFILE_SCOPE(Vulkan_Clearing); | 481 | MICROPROFILE_SCOPE(Vulkan_Clearing); |
| 482 | 482 | ||
| 483 | const auto& gpu = system.GPU().Maxwell3D(); | 483 | if (!maxwell3d.ShouldExecute()) { |
| 484 | if (!system.GPU().Maxwell3D().ShouldExecute()) { | ||
| 485 | return; | 484 | return; |
| 486 | } | 485 | } |
| 487 | 486 | ||
| @@ -490,7 +489,7 @@ void RasterizerVulkan::Clear() { | |||
| 490 | 489 | ||
| 491 | query_cache.UpdateCounters(); | 490 | query_cache.UpdateCounters(); |
| 492 | 491 | ||
| 493 | const auto& regs = gpu.regs; | 492 | const auto& regs = maxwell3d.regs; |
| 494 | const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || | 493 | const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || |
| 495 | regs.clear_buffers.A; | 494 | regs.clear_buffers.A; |
| 496 | const bool use_depth = regs.clear_buffers.Z; | 495 | const bool use_depth = regs.clear_buffers.Z; |
| @@ -559,7 +558,7 @@ void RasterizerVulkan::DispatchCompute(GPUVAddr code_addr) { | |||
| 559 | 558 | ||
| 560 | query_cache.UpdateCounters(); | 559 | query_cache.UpdateCounters(); |
| 561 | 560 | ||
| 562 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 561 | const auto& launch_desc = kepler_compute.launch_description; |
| 563 | auto& pipeline = pipeline_cache.GetComputePipeline({ | 562 | auto& pipeline = pipeline_cache.GetComputePipeline({ |
| 564 | .shader = code_addr, | 563 | .shader = code_addr, |
| 565 | .shared_memory_size = launch_desc.shared_alloc, | 564 | .shared_memory_size = launch_desc.shared_alloc, |
| @@ -655,16 +654,14 @@ void RasterizerVulkan::SyncGuestHost() { | |||
| 655 | } | 654 | } |
| 656 | 655 | ||
| 657 | void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { | 656 | void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { |
| 658 | auto& gpu{system.GPU()}; | ||
| 659 | if (!gpu.IsAsync()) { | 657 | if (!gpu.IsAsync()) { |
| 660 | gpu.MemoryManager().Write<u32>(addr, value); | 658 | gpu_memory.Write<u32>(addr, value); |
| 661 | return; | 659 | return; |
| 662 | } | 660 | } |
| 663 | fence_manager.SignalSemaphore(addr, value); | 661 | fence_manager.SignalSemaphore(addr, value); |
| 664 | } | 662 | } |
| 665 | 663 | ||
| 666 | void RasterizerVulkan::SignalSyncPoint(u32 value) { | 664 | void RasterizerVulkan::SignalSyncPoint(u32 value) { |
| 667 | auto& gpu{system.GPU()}; | ||
| 668 | if (!gpu.IsAsync()) { | 665 | if (!gpu.IsAsync()) { |
| 669 | gpu.IncrementSyncPoint(value); | 666 | gpu.IncrementSyncPoint(value); |
| 670 | return; | 667 | return; |
| @@ -673,7 +670,6 @@ void RasterizerVulkan::SignalSyncPoint(u32 value) { | |||
| 673 | } | 670 | } |
| 674 | 671 | ||
| 675 | void RasterizerVulkan::ReleaseFences() { | 672 | void RasterizerVulkan::ReleaseFences() { |
| 676 | auto& gpu{system.GPU()}; | ||
| 677 | if (!gpu.IsAsync()) { | 673 | if (!gpu.IsAsync()) { |
| 678 | return; | 674 | return; |
| 679 | } | 675 | } |
| @@ -751,10 +747,6 @@ bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, | |||
| 751 | return true; | 747 | return true; |
| 752 | } | 748 | } |
| 753 | 749 | ||
| 754 | void RasterizerVulkan::SetupDirtyFlags() { | ||
| 755 | state_tracker.Initialize(); | ||
| 756 | } | ||
| 757 | |||
| 758 | void RasterizerVulkan::FlushWork() { | 750 | void RasterizerVulkan::FlushWork() { |
| 759 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; | 751 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; |
| 760 | 752 | ||
| @@ -778,10 +770,9 @@ void RasterizerVulkan::FlushWork() { | |||
| 778 | 770 | ||
| 779 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) { | 771 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments(bool is_clear) { |
| 780 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); | 772 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); |
| 781 | auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 782 | auto& dirty = maxwell3d.dirty.flags; | ||
| 783 | auto& regs = maxwell3d.regs; | ||
| 784 | 773 | ||
| 774 | const auto& regs = maxwell3d.regs; | ||
| 775 | auto& dirty = maxwell3d.dirty.flags; | ||
| 785 | const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets]; | 776 | const bool update_rendertargets = dirty[VideoCommon::Dirty::RenderTargets]; |
| 786 | dirty[VideoCommon::Dirty::RenderTargets] = false; | 777 | dirty[VideoCommon::Dirty::RenderTargets] = false; |
| 787 | 778 | ||
| @@ -844,7 +835,7 @@ std::tuple<VkFramebuffer, VkExtent2D> RasterizerVulkan::ConfigureFramebuffers( | |||
| 844 | return true; | 835 | return true; |
| 845 | }; | 836 | }; |
| 846 | 837 | ||
| 847 | const auto& regs = system.GPU().Maxwell3D().regs; | 838 | const auto& regs = maxwell3d.regs; |
| 848 | const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); | 839 | const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); |
| 849 | for (std::size_t index = 0; index < num_attachments; ++index) { | 840 | for (std::size_t index = 0; index < num_attachments; ++index) { |
| 850 | if (try_push(color_attachments[index])) { | 841 | if (try_push(color_attachments[index])) { |
| @@ -880,13 +871,12 @@ RasterizerVulkan::DrawParameters RasterizerVulkan::SetupGeometry(FixedPipelineSt | |||
| 880 | bool is_instanced) { | 871 | bool is_instanced) { |
| 881 | MICROPROFILE_SCOPE(Vulkan_Geometry); | 872 | MICROPROFILE_SCOPE(Vulkan_Geometry); |
| 882 | 873 | ||
| 883 | const auto& gpu = system.GPU().Maxwell3D(); | 874 | const auto& regs = maxwell3d.regs; |
| 884 | const auto& regs = gpu.regs; | ||
| 885 | 875 | ||
| 886 | SetupVertexArrays(buffer_bindings); | 876 | SetupVertexArrays(buffer_bindings); |
| 887 | 877 | ||
| 888 | const u32 base_instance = regs.vb_base_instance; | 878 | const u32 base_instance = regs.vb_base_instance; |
| 889 | const u32 num_instances = is_instanced ? gpu.mme_draw.instance_count : 1; | 879 | const u32 num_instances = is_instanced ? maxwell3d.mme_draw.instance_count : 1; |
| 890 | const u32 base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first; | 880 | const u32 base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first; |
| 891 | const u32 num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count; | 881 | const u32 num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count; |
| 892 | 882 | ||
| @@ -947,7 +937,7 @@ void RasterizerVulkan::SetupImageTransitions( | |||
| 947 | } | 937 | } |
| 948 | 938 | ||
| 949 | void RasterizerVulkan::UpdateDynamicStates() { | 939 | void RasterizerVulkan::UpdateDynamicStates() { |
| 950 | auto& regs = system.GPU().Maxwell3D().regs; | 940 | auto& regs = maxwell3d.regs; |
| 951 | UpdateViewportsState(regs); | 941 | UpdateViewportsState(regs); |
| 952 | UpdateScissorsState(regs); | 942 | UpdateScissorsState(regs); |
| 953 | UpdateDepthBias(regs); | 943 | UpdateDepthBias(regs); |
| @@ -968,7 +958,7 @@ void RasterizerVulkan::UpdateDynamicStates() { | |||
| 968 | } | 958 | } |
| 969 | 959 | ||
| 970 | void RasterizerVulkan::BeginTransformFeedback() { | 960 | void RasterizerVulkan::BeginTransformFeedback() { |
| 971 | const auto& regs = system.GPU().Maxwell3D().regs; | 961 | const auto& regs = maxwell3d.regs; |
| 972 | if (regs.tfb_enabled == 0) { | 962 | if (regs.tfb_enabled == 0) { |
| 973 | return; | 963 | return; |
| 974 | } | 964 | } |
| @@ -1000,7 +990,7 @@ void RasterizerVulkan::BeginTransformFeedback() { | |||
| 1000 | } | 990 | } |
| 1001 | 991 | ||
| 1002 | void RasterizerVulkan::EndTransformFeedback() { | 992 | void RasterizerVulkan::EndTransformFeedback() { |
| 1003 | const auto& regs = system.GPU().Maxwell3D().regs; | 993 | const auto& regs = maxwell3d.regs; |
| 1004 | if (regs.tfb_enabled == 0) { | 994 | if (regs.tfb_enabled == 0) { |
| 1005 | return; | 995 | return; |
| 1006 | } | 996 | } |
| @@ -1013,7 +1003,7 @@ void RasterizerVulkan::EndTransformFeedback() { | |||
| 1013 | } | 1003 | } |
| 1014 | 1004 | ||
| 1015 | void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) { | 1005 | void RasterizerVulkan::SetupVertexArrays(BufferBindings& buffer_bindings) { |
| 1016 | const auto& regs = system.GPU().Maxwell3D().regs; | 1006 | const auto& regs = maxwell3d.regs; |
| 1017 | 1007 | ||
| 1018 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | 1008 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 1019 | const auto& vertex_array = regs.vertex_array[index]; | 1009 | const auto& vertex_array = regs.vertex_array[index]; |
| @@ -1039,7 +1029,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar | |||
| 1039 | if (params.num_vertices == 0) { | 1029 | if (params.num_vertices == 0) { |
| 1040 | return; | 1030 | return; |
| 1041 | } | 1031 | } |
| 1042 | const auto& regs = system.GPU().Maxwell3D().regs; | 1032 | const auto& regs = maxwell3d.regs; |
| 1043 | switch (regs.draw.topology) { | 1033 | switch (regs.draw.topology) { |
| 1044 | case Maxwell::PrimitiveTopology::Quads: { | 1034 | case Maxwell::PrimitiveTopology::Quads: { |
| 1045 | if (!params.is_indexed) { | 1035 | if (!params.is_indexed) { |
| @@ -1087,8 +1077,7 @@ void RasterizerVulkan::SetupIndexBuffer(BufferBindings& buffer_bindings, DrawPar | |||
| 1087 | 1077 | ||
| 1088 | void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage) { | 1078 | void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, std::size_t stage) { |
| 1089 | MICROPROFILE_SCOPE(Vulkan_ConstBuffers); | 1079 | MICROPROFILE_SCOPE(Vulkan_ConstBuffers); |
| 1090 | const auto& gpu = system.GPU().Maxwell3D(); | 1080 | const auto& shader_stage = maxwell3d.state.shader_stages[stage]; |
| 1091 | const auto& shader_stage = gpu.state.shader_stages[stage]; | ||
| 1092 | for (const auto& entry : entries.const_buffers) { | 1081 | for (const auto& entry : entries.const_buffers) { |
| 1093 | SetupConstBuffer(entry, shader_stage.const_buffers[entry.GetIndex()]); | 1082 | SetupConstBuffer(entry, shader_stage.const_buffers[entry.GetIndex()]); |
| 1094 | } | 1083 | } |
| @@ -1096,8 +1085,7 @@ void RasterizerVulkan::SetupGraphicsConstBuffers(const ShaderEntries& entries, s | |||
| 1096 | 1085 | ||
| 1097 | void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage) { | 1086 | void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, std::size_t stage) { |
| 1098 | MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); | 1087 | MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); |
| 1099 | auto& gpu{system.GPU()}; | 1088 | const auto& cbufs{maxwell3d.state.shader_stages[stage]}; |
| 1100 | const auto cbufs{gpu.Maxwell3D().state.shader_stages[stage]}; | ||
| 1101 | 1089 | ||
| 1102 | for (const auto& entry : entries.global_buffers) { | 1090 | for (const auto& entry : entries.global_buffers) { |
| 1103 | const auto addr = cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset(); | 1091 | const auto addr = cbufs.const_buffers[entry.GetCbufIndex()].address + entry.GetCbufOffset(); |
| @@ -1107,19 +1095,17 @@ void RasterizerVulkan::SetupGraphicsGlobalBuffers(const ShaderEntries& entries, | |||
| 1107 | 1095 | ||
| 1108 | void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) { | 1096 | void RasterizerVulkan::SetupGraphicsUniformTexels(const ShaderEntries& entries, std::size_t stage) { |
| 1109 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1097 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1110 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 1111 | for (const auto& entry : entries.uniform_texels) { | 1098 | for (const auto& entry : entries.uniform_texels) { |
| 1112 | const auto image = GetTextureInfo(gpu, entry, stage).tic; | 1099 | const auto image = GetTextureInfo(maxwell3d, entry, stage).tic; |
| 1113 | SetupUniformTexels(image, entry); | 1100 | SetupUniformTexels(image, entry); |
| 1114 | } | 1101 | } |
| 1115 | } | 1102 | } |
| 1116 | 1103 | ||
| 1117 | void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage) { | 1104 | void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std::size_t stage) { |
| 1118 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1105 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1119 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 1120 | for (const auto& entry : entries.samplers) { | 1106 | for (const auto& entry : entries.samplers) { |
| 1121 | for (std::size_t i = 0; i < entry.size; ++i) { | 1107 | for (std::size_t i = 0; i < entry.size; ++i) { |
| 1122 | const auto texture = GetTextureInfo(gpu, entry, stage, i); | 1108 | const auto texture = GetTextureInfo(maxwell3d, entry, stage, i); |
| 1123 | SetupTexture(texture, entry); | 1109 | SetupTexture(texture, entry); |
| 1124 | } | 1110 | } |
| 1125 | } | 1111 | } |
| @@ -1127,25 +1113,23 @@ void RasterizerVulkan::SetupGraphicsTextures(const ShaderEntries& entries, std:: | |||
| 1127 | 1113 | ||
| 1128 | void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) { | 1114 | void RasterizerVulkan::SetupGraphicsStorageTexels(const ShaderEntries& entries, std::size_t stage) { |
| 1129 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1115 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1130 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 1131 | for (const auto& entry : entries.storage_texels) { | 1116 | for (const auto& entry : entries.storage_texels) { |
| 1132 | const auto image = GetTextureInfo(gpu, entry, stage).tic; | 1117 | const auto image = GetTextureInfo(maxwell3d, entry, stage).tic; |
| 1133 | SetupStorageTexel(image, entry); | 1118 | SetupStorageTexel(image, entry); |
| 1134 | } | 1119 | } |
| 1135 | } | 1120 | } |
| 1136 | 1121 | ||
| 1137 | void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { | 1122 | void RasterizerVulkan::SetupGraphicsImages(const ShaderEntries& entries, std::size_t stage) { |
| 1138 | MICROPROFILE_SCOPE(Vulkan_Images); | 1123 | MICROPROFILE_SCOPE(Vulkan_Images); |
| 1139 | const auto& gpu = system.GPU().Maxwell3D(); | ||
| 1140 | for (const auto& entry : entries.images) { | 1124 | for (const auto& entry : entries.images) { |
| 1141 | const auto tic = GetTextureInfo(gpu, entry, stage).tic; | 1125 | const auto tic = GetTextureInfo(maxwell3d, entry, stage).tic; |
| 1142 | SetupImage(tic, entry); | 1126 | SetupImage(tic, entry); |
| 1143 | } | 1127 | } |
| 1144 | } | 1128 | } |
| 1145 | 1129 | ||
| 1146 | void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) { | 1130 | void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) { |
| 1147 | MICROPROFILE_SCOPE(Vulkan_ConstBuffers); | 1131 | MICROPROFILE_SCOPE(Vulkan_ConstBuffers); |
| 1148 | const auto& launch_desc = system.GPU().KeplerCompute().launch_description; | 1132 | const auto& launch_desc = kepler_compute.launch_description; |
| 1149 | for (const auto& entry : entries.const_buffers) { | 1133 | for (const auto& entry : entries.const_buffers) { |
| 1150 | const auto& config = launch_desc.const_buffer_config[entry.GetIndex()]; | 1134 | const auto& config = launch_desc.const_buffer_config[entry.GetIndex()]; |
| 1151 | const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value(); | 1135 | const std::bitset<8> mask = launch_desc.const_buffer_enable_mask.Value(); |
| @@ -1159,7 +1143,7 @@ void RasterizerVulkan::SetupComputeConstBuffers(const ShaderEntries& entries) { | |||
| 1159 | 1143 | ||
| 1160 | void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) { | 1144 | void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) { |
| 1161 | MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); | 1145 | MICROPROFILE_SCOPE(Vulkan_GlobalBuffers); |
| 1162 | const auto cbufs{system.GPU().KeplerCompute().launch_description.const_buffer_config}; | 1146 | const auto& cbufs{kepler_compute.launch_description.const_buffer_config}; |
| 1163 | for (const auto& entry : entries.global_buffers) { | 1147 | for (const auto& entry : entries.global_buffers) { |
| 1164 | const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()}; | 1148 | const auto addr{cbufs[entry.GetCbufIndex()].Address() + entry.GetCbufOffset()}; |
| 1165 | SetupGlobalBuffer(entry, addr); | 1149 | SetupGlobalBuffer(entry, addr); |
| @@ -1168,19 +1152,17 @@ void RasterizerVulkan::SetupComputeGlobalBuffers(const ShaderEntries& entries) { | |||
| 1168 | 1152 | ||
| 1169 | void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) { | 1153 | void RasterizerVulkan::SetupComputeUniformTexels(const ShaderEntries& entries) { |
| 1170 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1154 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1171 | const auto& gpu = system.GPU().KeplerCompute(); | ||
| 1172 | for (const auto& entry : entries.uniform_texels) { | 1155 | for (const auto& entry : entries.uniform_texels) { |
| 1173 | const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; | 1156 | const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic; |
| 1174 | SetupUniformTexels(image, entry); | 1157 | SetupUniformTexels(image, entry); |
| 1175 | } | 1158 | } |
| 1176 | } | 1159 | } |
| 1177 | 1160 | ||
| 1178 | void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) { | 1161 | void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) { |
| 1179 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1162 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1180 | const auto& gpu = system.GPU().KeplerCompute(); | ||
| 1181 | for (const auto& entry : entries.samplers) { | 1163 | for (const auto& entry : entries.samplers) { |
| 1182 | for (std::size_t i = 0; i < entry.size; ++i) { | 1164 | for (std::size_t i = 0; i < entry.size; ++i) { |
| 1183 | const auto texture = GetTextureInfo(gpu, entry, ComputeShaderIndex, i); | 1165 | const auto texture = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex, i); |
| 1184 | SetupTexture(texture, entry); | 1166 | SetupTexture(texture, entry); |
| 1185 | } | 1167 | } |
| 1186 | } | 1168 | } |
| @@ -1188,18 +1170,16 @@ void RasterizerVulkan::SetupComputeTextures(const ShaderEntries& entries) { | |||
| 1188 | 1170 | ||
| 1189 | void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) { | 1171 | void RasterizerVulkan::SetupComputeStorageTexels(const ShaderEntries& entries) { |
| 1190 | MICROPROFILE_SCOPE(Vulkan_Textures); | 1172 | MICROPROFILE_SCOPE(Vulkan_Textures); |
| 1191 | const auto& gpu = system.GPU().KeplerCompute(); | ||
| 1192 | for (const auto& entry : entries.storage_texels) { | 1173 | for (const auto& entry : entries.storage_texels) { |
| 1193 | const auto image = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; | 1174 | const auto image = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic; |
| 1194 | SetupStorageTexel(image, entry); | 1175 | SetupStorageTexel(image, entry); |
| 1195 | } | 1176 | } |
| 1196 | } | 1177 | } |
| 1197 | 1178 | ||
| 1198 | void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { | 1179 | void RasterizerVulkan::SetupComputeImages(const ShaderEntries& entries) { |
| 1199 | MICROPROFILE_SCOPE(Vulkan_Images); | 1180 | MICROPROFILE_SCOPE(Vulkan_Images); |
| 1200 | const auto& gpu = system.GPU().KeplerCompute(); | ||
| 1201 | for (const auto& entry : entries.images) { | 1181 | for (const auto& entry : entries.images) { |
| 1202 | const auto tic = GetTextureInfo(gpu, entry, ComputeShaderIndex).tic; | 1182 | const auto tic = GetTextureInfo(kepler_compute, entry, ComputeShaderIndex).tic; |
| 1203 | SetupImage(tic, entry); | 1183 | SetupImage(tic, entry); |
| 1204 | } | 1184 | } |
| 1205 | } | 1185 | } |
| @@ -1223,9 +1203,8 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry, | |||
| 1223 | } | 1203 | } |
| 1224 | 1204 | ||
| 1225 | void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address) { | 1205 | void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAddr address) { |
| 1226 | auto& memory_manager{system.GPU().MemoryManager()}; | 1206 | const u64 actual_addr = gpu_memory.Read<u64>(address); |
| 1227 | const auto actual_addr = memory_manager.Read<u64>(address); | 1207 | const u32 size = gpu_memory.Read<u32>(address + 8); |
| 1228 | const auto size = memory_manager.Read<u32>(address + 8); | ||
| 1229 | 1208 | ||
| 1230 | if (size == 0) { | 1209 | if (size == 0) { |
| 1231 | // Sometimes global memory pointers don't have a proper size. Upload a dummy entry | 1210 | // Sometimes global memory pointers don't have a proper size. Upload a dummy entry |
| @@ -1508,7 +1487,7 @@ std::size_t RasterizerVulkan::CalculateComputeStreamBufferSize() const { | |||
| 1508 | } | 1487 | } |
| 1509 | 1488 | ||
| 1510 | std::size_t RasterizerVulkan::CalculateVertexArraysSize() const { | 1489 | std::size_t RasterizerVulkan::CalculateVertexArraysSize() const { |
| 1511 | const auto& regs = system.GPU().Maxwell3D().regs; | 1490 | const auto& regs = maxwell3d.regs; |
| 1512 | 1491 | ||
| 1513 | std::size_t size = 0; | 1492 | std::size_t size = 0; |
| 1514 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | 1493 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| @@ -1523,9 +1502,8 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const { | |||
| 1523 | } | 1502 | } |
| 1524 | 1503 | ||
| 1525 | std::size_t RasterizerVulkan::CalculateIndexBufferSize() const { | 1504 | std::size_t RasterizerVulkan::CalculateIndexBufferSize() const { |
| 1526 | const auto& regs = system.GPU().Maxwell3D().regs; | 1505 | return static_cast<std::size_t>(maxwell3d.regs.index_array.count) * |
| 1527 | return static_cast<std::size_t>(regs.index_array.count) * | 1506 | static_cast<std::size_t>(maxwell3d.regs.index_array.FormatSizeInBytes()); |
| 1528 | static_cast<std::size_t>(regs.index_array.FormatSizeInBytes()); | ||
| 1529 | } | 1507 | } |
| 1530 | 1508 | ||
| 1531 | std::size_t RasterizerVulkan::CalculateConstBufferSize( | 1509 | std::size_t RasterizerVulkan::CalculateConstBufferSize( |
| @@ -1540,7 +1518,7 @@ std::size_t RasterizerVulkan::CalculateConstBufferSize( | |||
| 1540 | } | 1518 | } |
| 1541 | 1519 | ||
| 1542 | RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { | 1520 | RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions) const { |
| 1543 | const auto& regs = system.GPU().Maxwell3D().regs; | 1521 | const auto& regs = maxwell3d.regs; |
| 1544 | const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); | 1522 | const std::size_t num_attachments = static_cast<std::size_t>(regs.rt_control.count); |
| 1545 | 1523 | ||
| 1546 | RenderPassParams params; | 1524 | RenderPassParams params; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index f640ba649..16251d0f6 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -106,7 +106,8 @@ struct ImageView { | |||
| 106 | 106 | ||
| 107 | class RasterizerVulkan final : public VideoCore::RasterizerAccelerated { | 107 | class RasterizerVulkan final : public VideoCore::RasterizerAccelerated { |
| 108 | public: | 108 | public: |
| 109 | explicit RasterizerVulkan(Core::System& system, Core::Frontend::EmuWindow& render_window, | 109 | explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 110 | Tegra::MemoryManager& gpu_memory, Core::Memory::Memory& cpu_memory, | ||
| 110 | VKScreenInfo& screen_info, const VKDevice& device, | 111 | VKScreenInfo& screen_info, const VKDevice& device, |
| 111 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, | 112 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, |
| 112 | StateTracker& state_tracker, VKScheduler& scheduler); | 113 | StateTracker& state_tracker, VKScheduler& scheduler); |
| @@ -135,7 +136,6 @@ public: | |||
| 135 | const Tegra::Engines::Fermi2D::Config& copy_config) override; | 136 | const Tegra::Engines::Fermi2D::Config& copy_config) override; |
| 136 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, | 137 | bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |
| 137 | u32 pixel_stride) override; | 138 | u32 pixel_stride) override; |
| 138 | void SetupDirtyFlags() override; | ||
| 139 | 139 | ||
| 140 | VideoCommon::Shader::AsyncShaders& GetAsyncShaders() { | 140 | VideoCommon::Shader::AsyncShaders& GetAsyncShaders() { |
| 141 | return async_shaders; | 141 | return async_shaders; |
| @@ -279,8 +279,11 @@ private: | |||
| 279 | 279 | ||
| 280 | VkBuffer DefaultBuffer(); | 280 | VkBuffer DefaultBuffer(); |
| 281 | 281 | ||
| 282 | Core::System& system; | 282 | Tegra::GPU& gpu; |
| 283 | Core::Frontend::EmuWindow& render_window; | 283 | Tegra::MemoryManager& gpu_memory; |
| 284 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 285 | Tegra::Engines::KeplerCompute& kepler_compute; | ||
| 286 | |||
| 284 | VKScreenInfo& screen_info; | 287 | VKScreenInfo& screen_info; |
| 285 | const VKDevice& device; | 288 | const VKDevice& device; |
| 286 | VKResourceManager& resource_manager; | 289 | VKResourceManager& resource_manager; |
| @@ -300,8 +303,8 @@ private: | |||
| 300 | VKPipelineCache pipeline_cache; | 303 | VKPipelineCache pipeline_cache; |
| 301 | VKBufferCache buffer_cache; | 304 | VKBufferCache buffer_cache; |
| 302 | VKSamplerCache sampler_cache; | 305 | VKSamplerCache sampler_cache; |
| 303 | VKFenceManager fence_manager; | ||
| 304 | VKQueryCache query_cache; | 306 | VKQueryCache query_cache; |
| 307 | VKFenceManager fence_manager; | ||
| 305 | 308 | ||
| 306 | vk::Buffer default_buffer; | 309 | vk::Buffer default_buffer; |
| 307 | VKMemoryCommit default_buffer_commit; | 310 | VKMemoryCommit default_buffer_commit; |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp index 4bd1009f9..5d2c4a796 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp +++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp | |||
| @@ -132,12 +132,9 @@ void SetupDirtyStencilTestEnable(Tables& tables) { | |||
| 132 | 132 | ||
| 133 | } // Anonymous namespace | 133 | } // Anonymous namespace |
| 134 | 134 | ||
| 135 | StateTracker::StateTracker(Core::System& system) | 135 | StateTracker::StateTracker(Tegra::GPU& gpu) |
| 136 | : system{system}, invalidation_flags{MakeInvalidationFlags()} {} | 136 | : flags{gpu.Maxwell3D().dirty.flags}, invalidation_flags{MakeInvalidationFlags()} { |
| 137 | 137 | auto& tables = gpu.Maxwell3D().dirty.tables; | |
| 138 | void StateTracker::Initialize() { | ||
| 139 | auto& dirty = system.GPU().Maxwell3D().dirty; | ||
| 140 | auto& tables = dirty.tables; | ||
| 141 | SetupDirtyRenderTargets(tables); | 138 | SetupDirtyRenderTargets(tables); |
| 142 | SetupDirtyViewports(tables); | 139 | SetupDirtyViewports(tables); |
| 143 | SetupDirtyScissors(tables); | 140 | SetupDirtyScissors(tables); |
| @@ -155,9 +152,4 @@ void StateTracker::Initialize() { | |||
| 155 | SetupDirtyStencilTestEnable(tables); | 152 | SetupDirtyStencilTestEnable(tables); |
| 156 | } | 153 | } |
| 157 | 154 | ||
| 158 | void StateTracker::InvalidateCommandBufferState() { | ||
| 159 | system.GPU().Maxwell3D().dirty.flags |= invalidation_flags; | ||
| 160 | current_topology = INVALID_TOPOLOGY; | ||
| 161 | } | ||
| 162 | |||
| 163 | } // namespace Vulkan | 155 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 13a6ce786..1de789e57 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h | |||
| @@ -45,11 +45,12 @@ class StateTracker { | |||
| 45 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 45 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 46 | 46 | ||
| 47 | public: | 47 | public: |
| 48 | explicit StateTracker(Core::System& system); | 48 | explicit StateTracker(Tegra::GPU& gpu); |
| 49 | 49 | ||
| 50 | void Initialize(); | 50 | void InvalidateCommandBufferState() { |
| 51 | 51 | flags |= invalidation_flags; | |
| 52 | void InvalidateCommandBufferState(); | 52 | current_topology = INVALID_TOPOLOGY; |
| 53 | } | ||
| 53 | 54 | ||
| 54 | bool TouchViewports() { | 55 | bool TouchViewports() { |
| 55 | return Exchange(Dirty::Viewports, false); | 56 | return Exchange(Dirty::Viewports, false); |
| @@ -121,13 +122,12 @@ private: | |||
| 121 | static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); | 122 | static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u); |
| 122 | 123 | ||
| 123 | bool Exchange(std::size_t id, bool new_value) const noexcept { | 124 | bool Exchange(std::size_t id, bool new_value) const noexcept { |
| 124 | auto& flags = system.GPU().Maxwell3D().dirty.flags; | ||
| 125 | const bool is_dirty = flags[id]; | 125 | const bool is_dirty = flags[id]; |
| 126 | flags[id] = new_value; | 126 | flags[id] = new_value; |
| 127 | return is_dirty; | 127 | return is_dirty; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | Core::System& system; | 130 | Tegra::Engines::Maxwell3D::DirtyState::Flags& flags; |
| 131 | Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags; | 131 | Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags; |
| 132 | Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY; | 132 | Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY; |
| 133 | }; | 133 | }; |
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index a5526a3f5..3c9171a5e 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp | |||
| @@ -57,9 +57,9 @@ u32 GetMemoryType(const VkPhysicalDeviceMemoryProperties& properties, | |||
| 57 | 57 | ||
| 58 | } // Anonymous namespace | 58 | } // Anonymous namespace |
| 59 | 59 | ||
| 60 | VKStreamBuffer::VKStreamBuffer(const VKDevice& device, VKScheduler& scheduler, | 60 | VKStreamBuffer::VKStreamBuffer(const VKDevice& device_, VKScheduler& scheduler_, |
| 61 | VkBufferUsageFlags usage) | 61 | VkBufferUsageFlags usage) |
| 62 | : device{device}, scheduler{scheduler} { | 62 | : device{device_}, scheduler{scheduler_} { |
| 63 | CreateBuffers(usage); | 63 | CreateBuffers(usage); |
| 64 | ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE); | 64 | ReserveWatches(current_watches, WATCHES_INITIAL_RESERVE); |
| 65 | ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE); | 65 | ReserveWatches(previous_watches, WATCHES_INITIAL_RESERVE); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 2c6f54101..06182d909 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -188,13 +188,13 @@ u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, Tegra::Texture::Swizzl | |||
| 188 | 188 | ||
| 189 | } // Anonymous namespace | 189 | } // Anonymous namespace |
| 190 | 190 | ||
| 191 | CachedSurface::CachedSurface(Core::System& system, const VKDevice& device, | 191 | CachedSurface::CachedSurface(const VKDevice& device, VKResourceManager& resource_manager, |
| 192 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, | 192 | VKMemoryManager& memory_manager, VKScheduler& scheduler, |
| 193 | VKScheduler& scheduler, VKStagingBufferPool& staging_pool, | 193 | VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr, |
| 194 | GPUVAddr gpu_addr, const SurfaceParams& params) | 194 | const SurfaceParams& params) |
| 195 | : SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, system{system}, | 195 | : SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, device{device}, |
| 196 | device{device}, resource_manager{resource_manager}, | 196 | resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler}, |
| 197 | memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} { | 197 | staging_pool{staging_pool} { |
| 198 | if (params.IsBuffer()) { | 198 | if (params.IsBuffer()) { |
| 199 | buffer = CreateBuffer(device, params, host_memory_size); | 199 | buffer = CreateBuffer(device, params, host_memory_size); |
| 200 | commit = memory_manager.Commit(buffer, false); | 200 | commit = memory_manager.Commit(buffer, false); |
| @@ -490,19 +490,21 @@ VkImageView CachedSurfaceView::GetAttachment() { | |||
| 490 | return *render_target; | 490 | return *render_target; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | VKTextureCache::VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 493 | VKTextureCache::VKTextureCache(VideoCore::RasterizerInterface& rasterizer, |
| 494 | const VKDevice& device, VKResourceManager& resource_manager, | 494 | Tegra::Engines::Maxwell3D& maxwell3d, |
| 495 | VKMemoryManager& memory_manager, VKScheduler& scheduler, | 495 | Tegra::MemoryManager& gpu_memory, const VKDevice& device_, |
| 496 | VKStagingBufferPool& staging_pool) | 496 | VKResourceManager& resource_manager_, |
| 497 | : TextureCache(system, rasterizer, device.IsOptimalAstcSupported()), device{device}, | 497 | VKMemoryManager& memory_manager_, VKScheduler& scheduler_, |
| 498 | resource_manager{resource_manager}, memory_manager{memory_manager}, scheduler{scheduler}, | 498 | VKStagingBufferPool& staging_pool_) |
| 499 | staging_pool{staging_pool} {} | 499 | : TextureCache(rasterizer, maxwell3d, gpu_memory, device_.IsOptimalAstcSupported()), |
| 500 | device{device_}, resource_manager{resource_manager_}, | ||
| 501 | memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{staging_pool_} {} | ||
| 500 | 502 | ||
| 501 | VKTextureCache::~VKTextureCache() = default; | 503 | VKTextureCache::~VKTextureCache() = default; |
| 502 | 504 | ||
| 503 | Surface VKTextureCache::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) { | 505 | Surface VKTextureCache::CreateSurface(GPUVAddr gpu_addr, const SurfaceParams& params) { |
| 504 | return std::make_shared<CachedSurface>(system, device, resource_manager, memory_manager, | 506 | return std::make_shared<CachedSurface>(device, resource_manager, memory_manager, scheduler, |
| 505 | scheduler, staging_pool, gpu_addr, params); | 507 | staging_pool, gpu_addr, params); |
| 506 | } | 508 | } |
| 507 | 509 | ||
| 508 | void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface, | 510 | void VKTextureCache::ImageCopy(Surface& src_surface, Surface& dst_surface, |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 807e26c8a..e47d02c41 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -15,10 +15,6 @@ | |||
| 15 | #include "video_core/texture_cache/surface_base.h" | 15 | #include "video_core/texture_cache/surface_base.h" |
| 16 | #include "video_core/texture_cache/texture_cache.h" | 16 | #include "video_core/texture_cache/texture_cache.h" |
| 17 | 17 | ||
| 18 | namespace Core { | ||
| 19 | class System; | ||
| 20 | } | ||
| 21 | |||
| 22 | namespace VideoCore { | 18 | namespace VideoCore { |
| 23 | class RasterizerInterface; | 19 | class RasterizerInterface; |
| 24 | } | 20 | } |
| @@ -45,10 +41,10 @@ class CachedSurface final : public VideoCommon::SurfaceBase<View> { | |||
| 45 | friend CachedSurfaceView; | 41 | friend CachedSurfaceView; |
| 46 | 42 | ||
| 47 | public: | 43 | public: |
| 48 | explicit CachedSurface(Core::System& system, const VKDevice& device, | 44 | explicit CachedSurface(const VKDevice& device, VKResourceManager& resource_manager, |
| 49 | VKResourceManager& resource_manager, VKMemoryManager& memory_manager, | 45 | VKMemoryManager& memory_manager, VKScheduler& scheduler, |
| 50 | VKScheduler& scheduler, VKStagingBufferPool& staging_pool, | 46 | VKStagingBufferPool& staging_pool, GPUVAddr gpu_addr, |
| 51 | GPUVAddr gpu_addr, const SurfaceParams& params); | 47 | const SurfaceParams& params); |
| 52 | ~CachedSurface(); | 48 | ~CachedSurface(); |
| 53 | 49 | ||
| 54 | void UploadTexture(const std::vector<u8>& staging_buffer) override; | 50 | void UploadTexture(const std::vector<u8>& staging_buffer) override; |
| @@ -101,7 +97,6 @@ private: | |||
| 101 | 97 | ||
| 102 | VkImageSubresourceRange GetImageSubresourceRange() const; | 98 | VkImageSubresourceRange GetImageSubresourceRange() const; |
| 103 | 99 | ||
| 104 | Core::System& system; | ||
| 105 | const VKDevice& device; | 100 | const VKDevice& device; |
| 106 | VKResourceManager& resource_manager; | 101 | VKResourceManager& resource_manager; |
| 107 | VKMemoryManager& memory_manager; | 102 | VKMemoryManager& memory_manager; |
| @@ -201,7 +196,8 @@ private: | |||
| 201 | 196 | ||
| 202 | class VKTextureCache final : public TextureCacheBase { | 197 | class VKTextureCache final : public TextureCacheBase { |
| 203 | public: | 198 | public: |
| 204 | explicit VKTextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 199 | explicit VKTextureCache(VideoCore::RasterizerInterface& rasterizer, |
| 200 | Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, | ||
| 205 | const VKDevice& device, VKResourceManager& resource_manager, | 201 | const VKDevice& device, VKResourceManager& resource_manager, |
| 206 | VKMemoryManager& memory_manager, VKScheduler& scheduler, | 202 | VKMemoryManager& memory_manager, VKScheduler& scheduler, |
| 207 | VKStagingBufferPool& staging_pool); | 203 | VKStagingBufferPool& staging_pool); |
diff --git a/src/video_core/shader/memory_util.cpp b/src/video_core/shader/memory_util.cpp index 5071c83ca..e18ccba8e 100644 --- a/src/video_core/shader/memory_util.cpp +++ b/src/video_core/shader/memory_util.cpp | |||
| @@ -16,11 +16,10 @@ | |||
| 16 | 16 | ||
| 17 | namespace VideoCommon::Shader { | 17 | namespace VideoCommon::Shader { |
| 18 | 18 | ||
| 19 | GPUVAddr GetShaderAddress(Core::System& system, | 19 | GPUVAddr GetShaderAddress(Tegra::Engines::Maxwell3D& maxwell3d, |
| 20 | Tegra::Engines::Maxwell3D::Regs::ShaderProgram program) { | 20 | Tegra::Engines::Maxwell3D::Regs::ShaderProgram program) { |
| 21 | const auto& gpu{system.GPU().Maxwell3D()}; | 21 | const auto& shader_config{maxwell3d.regs.shader_config[static_cast<std::size_t>(program)]}; |
| 22 | const auto& shader_config{gpu.regs.shader_config[static_cast<std::size_t>(program)]}; | 22 | return maxwell3d.regs.code_address.CodeAddress() + shader_config.offset; |
| 23 | return gpu.regs.code_address.CodeAddress() + shader_config.offset; | ||
| 24 | } | 23 | } |
| 25 | 24 | ||
| 26 | bool IsSchedInstruction(std::size_t offset, std::size_t main_offset) { | 25 | bool IsSchedInstruction(std::size_t offset, std::size_t main_offset) { |
diff --git a/src/video_core/shader/memory_util.h b/src/video_core/shader/memory_util.h index be90d24fd..4624d38e6 100644 --- a/src/video_core/shader/memory_util.h +++ b/src/video_core/shader/memory_util.h | |||
| @@ -11,10 +11,6 @@ | |||
| 11 | #include "video_core/engines/maxwell_3d.h" | 11 | #include "video_core/engines/maxwell_3d.h" |
| 12 | #include "video_core/engines/shader_type.h" | 12 | #include "video_core/engines/shader_type.h" |
| 13 | 13 | ||
| 14 | namespace Core { | ||
| 15 | class System; | ||
| 16 | } | ||
| 17 | |||
| 18 | namespace Tegra { | 14 | namespace Tegra { |
| 19 | class MemoryManager; | 15 | class MemoryManager; |
| 20 | } | 16 | } |
| @@ -27,7 +23,7 @@ constexpr u32 STAGE_MAIN_OFFSET = 10; | |||
| 27 | constexpr u32 KERNEL_MAIN_OFFSET = 0; | 23 | constexpr u32 KERNEL_MAIN_OFFSET = 0; |
| 28 | 24 | ||
| 29 | /// Gets the address for the specified shader stage program | 25 | /// Gets the address for the specified shader stage program |
| 30 | GPUVAddr GetShaderAddress(Core::System& system, | 26 | GPUVAddr GetShaderAddress(Tegra::Engines::Maxwell3D& maxwell3d, |
| 31 | Tegra::Engines::Maxwell3D::Regs::ShaderProgram program); | 27 | Tegra::Engines::Maxwell3D::Regs::ShaderProgram program); |
| 32 | 28 | ||
| 33 | /// Gets if the current instruction offset is a scheduler instruction | 29 | /// Gets if the current instruction offset is a scheduler instruction |
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index e614a92df..e8515321b 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp | |||
| @@ -163,13 +163,11 @@ SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_tabl | |||
| 163 | return params; | 163 | return params; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { | 166 | SurfaceParams SurfaceParams::CreateForDepthBuffer(Tegra::Engines::Maxwell3D& maxwell3d) { |
| 167 | const auto& regs = system.GPU().Maxwell3D().regs; | 167 | const auto& regs = maxwell3d.regs; |
| 168 | |||
| 169 | const auto block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U); | 168 | const auto block_depth = std::min(regs.zeta.memory_layout.block_depth.Value(), 5U); |
| 170 | const bool is_layered = regs.zeta_layers > 1 && block_depth == 0; | 169 | const bool is_layered = regs.zeta_layers > 1 && block_depth == 0; |
| 171 | const auto pixel_format = PixelFormatFromDepthFormat(regs.zeta.format); | 170 | const auto pixel_format = PixelFormatFromDepthFormat(regs.zeta.format); |
| 172 | |||
| 173 | return { | 171 | return { |
| 174 | .is_tiled = regs.zeta.memory_layout.type == | 172 | .is_tiled = regs.zeta.memory_layout.type == |
| 175 | Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear, | 173 | Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear, |
| @@ -191,8 +189,9 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer(Core::System& system) { | |||
| 191 | }; | 189 | }; |
| 192 | } | 190 | } |
| 193 | 191 | ||
| 194 | SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::size_t index) { | 192 | SurfaceParams SurfaceParams::CreateForFramebuffer(Tegra::Engines::Maxwell3D& maxwell3d, |
| 195 | const auto& config{system.GPU().Maxwell3D().regs.rt[index]}; | 193 | std::size_t index) { |
| 194 | const auto& config{maxwell3d.regs.rt[index]}; | ||
| 196 | SurfaceParams params; | 195 | SurfaceParams params; |
| 197 | params.is_tiled = | 196 | params.is_tiled = |
| 198 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; | 197 | config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; |
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h index 118aa689e..4466c3c34 100644 --- a/src/video_core/texture_cache/surface_params.h +++ b/src/video_core/texture_cache/surface_params.h | |||
| @@ -33,10 +33,11 @@ public: | |||
| 33 | const VideoCommon::Shader::Image& entry); | 33 | const VideoCommon::Shader::Image& entry); |
| 34 | 34 | ||
| 35 | /// Creates SurfaceCachedParams for a depth buffer configuration. | 35 | /// Creates SurfaceCachedParams for a depth buffer configuration. |
| 36 | static SurfaceParams CreateForDepthBuffer(Core::System& system); | 36 | static SurfaceParams CreateForDepthBuffer(Tegra::Engines::Maxwell3D& maxwell3d); |
| 37 | 37 | ||
| 38 | /// Creates SurfaceCachedParams from a framebuffer configuration. | 38 | /// Creates SurfaceCachedParams from a framebuffer configuration. |
| 39 | static SurfaceParams CreateForFramebuffer(Core::System& system, std::size_t index); | 39 | static SurfaceParams CreateForFramebuffer(Tegra::Engines::Maxwell3D& maxwell3d, |
| 40 | std::size_t index); | ||
| 40 | 41 | ||
| 41 | /// Creates SurfaceCachedParams from a Fermi2D surface configuration. | 42 | /// Creates SurfaceCachedParams from a Fermi2D surface configuration. |
| 42 | static SurfaceParams CreateForFermiCopySurface( | 43 | static SurfaceParams CreateForFermiCopySurface( |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 96c4e4cc2..ea835c59f 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -135,8 +135,7 @@ public: | |||
| 135 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); | 135 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | const std::optional<VAddr> cpu_addr = | 138 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 139 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 140 | if (!cpu_addr) { | 139 | if (!cpu_addr) { |
| 141 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); | 140 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); |
| 142 | } | 141 | } |
| @@ -160,8 +159,7 @@ public: | |||
| 160 | if (!gpu_addr) { | 159 | if (!gpu_addr) { |
| 161 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); | 160 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); |
| 162 | } | 161 | } |
| 163 | const std::optional<VAddr> cpu_addr = | 162 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 164 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 165 | if (!cpu_addr) { | 163 | if (!cpu_addr) { |
| 166 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); | 164 | return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); |
| 167 | } | 165 | } |
| @@ -183,11 +181,11 @@ public: | |||
| 183 | 181 | ||
| 184 | TView GetDepthBufferSurface(bool preserve_contents) { | 182 | TView GetDepthBufferSurface(bool preserve_contents) { |
| 185 | std::lock_guard lock{mutex}; | 183 | std::lock_guard lock{mutex}; |
| 186 | auto& maxwell3d = system.GPU().Maxwell3D(); | 184 | auto& dirty = maxwell3d.dirty; |
| 187 | if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer]) { | 185 | if (!dirty.flags[VideoCommon::Dirty::ZetaBuffer]) { |
| 188 | return depth_buffer.view; | 186 | return depth_buffer.view; |
| 189 | } | 187 | } |
| 190 | maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer] = false; | 188 | dirty.flags[VideoCommon::Dirty::ZetaBuffer] = false; |
| 191 | 189 | ||
| 192 | const auto& regs{maxwell3d.regs}; | 190 | const auto& regs{maxwell3d.regs}; |
| 193 | const auto gpu_addr{regs.zeta.Address()}; | 191 | const auto gpu_addr{regs.zeta.Address()}; |
| @@ -195,13 +193,12 @@ public: | |||
| 195 | SetEmptyDepthBuffer(); | 193 | SetEmptyDepthBuffer(); |
| 196 | return {}; | 194 | return {}; |
| 197 | } | 195 | } |
| 198 | const std::optional<VAddr> cpu_addr = | 196 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 199 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 200 | if (!cpu_addr) { | 197 | if (!cpu_addr) { |
| 201 | SetEmptyDepthBuffer(); | 198 | SetEmptyDepthBuffer(); |
| 202 | return {}; | 199 | return {}; |
| 203 | } | 200 | } |
| 204 | const auto depth_params{SurfaceParams::CreateForDepthBuffer(system)}; | 201 | const auto depth_params{SurfaceParams::CreateForDepthBuffer(maxwell3d)}; |
| 205 | auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, preserve_contents, true); | 202 | auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, preserve_contents, true); |
| 206 | if (depth_buffer.target) | 203 | if (depth_buffer.target) |
| 207 | depth_buffer.target->MarkAsRenderTarget(false, NO_RT); | 204 | depth_buffer.target->MarkAsRenderTarget(false, NO_RT); |
| @@ -215,7 +212,6 @@ public: | |||
| 215 | TView GetColorBufferSurface(std::size_t index, bool preserve_contents) { | 212 | TView GetColorBufferSurface(std::size_t index, bool preserve_contents) { |
| 216 | std::lock_guard lock{mutex}; | 213 | std::lock_guard lock{mutex}; |
| 217 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); | 214 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); |
| 218 | auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 219 | if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index]) { | 215 | if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index]) { |
| 220 | return render_targets[index].view; | 216 | return render_targets[index].view; |
| 221 | } | 217 | } |
| @@ -235,15 +231,14 @@ public: | |||
| 235 | return {}; | 231 | return {}; |
| 236 | } | 232 | } |
| 237 | 233 | ||
| 238 | const std::optional<VAddr> cpu_addr = | 234 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 239 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 240 | if (!cpu_addr) { | 235 | if (!cpu_addr) { |
| 241 | SetEmptyColorBuffer(index); | 236 | SetEmptyColorBuffer(index); |
| 242 | return {}; | 237 | return {}; |
| 243 | } | 238 | } |
| 244 | 239 | ||
| 245 | auto surface_view = | 240 | auto surface_view = |
| 246 | GetSurface(gpu_addr, *cpu_addr, SurfaceParams::CreateForFramebuffer(system, index), | 241 | GetSurface(gpu_addr, *cpu_addr, SurfaceParams::CreateForFramebuffer(maxwell3d, index), |
| 247 | preserve_contents, true); | 242 | preserve_contents, true); |
| 248 | if (render_targets[index].target) { | 243 | if (render_targets[index].target) { |
| 249 | auto& surface = render_targets[index].target; | 244 | auto& surface = render_targets[index].target; |
| @@ -300,9 +295,8 @@ public: | |||
| 300 | const GPUVAddr dst_gpu_addr = dst_config.Address(); | 295 | const GPUVAddr dst_gpu_addr = dst_config.Address(); |
| 301 | DeduceBestBlit(src_params, dst_params, src_gpu_addr, dst_gpu_addr); | 296 | DeduceBestBlit(src_params, dst_params, src_gpu_addr, dst_gpu_addr); |
| 302 | 297 | ||
| 303 | const auto& memory_manager = system.GPU().MemoryManager(); | 298 | const std::optional<VAddr> dst_cpu_addr = gpu_memory.GpuToCpuAddress(dst_gpu_addr); |
| 304 | const std::optional<VAddr> dst_cpu_addr = memory_manager.GpuToCpuAddress(dst_gpu_addr); | 299 | const std::optional<VAddr> src_cpu_addr = gpu_memory.GpuToCpuAddress(src_gpu_addr); |
| 305 | const std::optional<VAddr> src_cpu_addr = memory_manager.GpuToCpuAddress(src_gpu_addr); | ||
| 306 | std::pair dst_surface = GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, true, false); | 300 | std::pair dst_surface = GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, true, false); |
| 307 | TView src_surface = GetSurface(src_gpu_addr, *src_cpu_addr, src_params, true, false).second; | 301 | TView src_surface = GetSurface(src_gpu_addr, *src_cpu_addr, src_params, true, false).second; |
| 308 | ImageBlit(src_surface, dst_surface.second, copy_config); | 302 | ImageBlit(src_surface, dst_surface.second, copy_config); |
| @@ -358,9 +352,11 @@ public: | |||
| 358 | } | 352 | } |
| 359 | 353 | ||
| 360 | protected: | 354 | protected: |
| 361 | explicit TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | 355 | explicit TextureCache(VideoCore::RasterizerInterface& rasterizer_, |
| 362 | bool is_astc_supported) | 356 | Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, |
| 363 | : system{system}, is_astc_supported{is_astc_supported}, rasterizer{rasterizer} { | 357 | bool is_astc_supported_) |
| 358 | : is_astc_supported{is_astc_supported_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, | ||
| 359 | gpu_memory{gpu_memory_} { | ||
| 364 | for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { | 360 | for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { |
| 365 | SetEmptyColorBuffer(i); | 361 | SetEmptyColorBuffer(i); |
| 366 | } | 362 | } |
| @@ -395,7 +391,7 @@ protected: | |||
| 395 | virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0; | 391 | virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0; |
| 396 | 392 | ||
| 397 | void ManageRenderTargetUnregister(TSurface& surface) { | 393 | void ManageRenderTargetUnregister(TSurface& surface) { |
| 398 | auto& dirty = system.GPU().Maxwell3D().dirty; | 394 | auto& dirty = maxwell3d.dirty; |
| 399 | const u32 index = surface->GetRenderTarget(); | 395 | const u32 index = surface->GetRenderTarget(); |
| 400 | if (index == DEPTH_RT) { | 396 | if (index == DEPTH_RT) { |
| 401 | dirty.flags[VideoCommon::Dirty::ZetaBuffer] = true; | 397 | dirty.flags[VideoCommon::Dirty::ZetaBuffer] = true; |
| @@ -408,8 +404,7 @@ protected: | |||
| 408 | void Register(TSurface surface) { | 404 | void Register(TSurface surface) { |
| 409 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); | 405 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); |
| 410 | const std::size_t size = surface->GetSizeInBytes(); | 406 | const std::size_t size = surface->GetSizeInBytes(); |
| 411 | const std::optional<VAddr> cpu_addr = | 407 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 412 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 413 | if (!cpu_addr) { | 408 | if (!cpu_addr) { |
| 414 | LOG_CRITICAL(HW_GPU, "Failed to register surface with unmapped gpu_address 0x{:016x}", | 409 | LOG_CRITICAL(HW_GPU, "Failed to register surface with unmapped gpu_address 0x{:016x}", |
| 415 | gpu_addr); | 410 | gpu_addr); |
| @@ -459,7 +454,6 @@ protected: | |||
| 459 | return new_surface; | 454 | return new_surface; |
| 460 | } | 455 | } |
| 461 | 456 | ||
| 462 | Core::System& system; | ||
| 463 | const bool is_astc_supported; | 457 | const bool is_astc_supported; |
| 464 | 458 | ||
| 465 | private: | 459 | private: |
| @@ -954,8 +948,7 @@ private: | |||
| 954 | * @param params The parameters on the candidate surface. | 948 | * @param params The parameters on the candidate surface. |
| 955 | **/ | 949 | **/ |
| 956 | Deduction DeduceSurface(const GPUVAddr gpu_addr, const SurfaceParams& params) { | 950 | Deduction DeduceSurface(const GPUVAddr gpu_addr, const SurfaceParams& params) { |
| 957 | const std::optional<VAddr> cpu_addr = | 951 | const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr); |
| 958 | system.GPU().MemoryManager().GpuToCpuAddress(gpu_addr); | ||
| 959 | 952 | ||
| 960 | if (!cpu_addr) { | 953 | if (!cpu_addr) { |
| 961 | Deduction result{}; | 954 | Deduction result{}; |
| @@ -1112,7 +1105,7 @@ private: | |||
| 1112 | 1105 | ||
| 1113 | void LoadSurface(const TSurface& surface) { | 1106 | void LoadSurface(const TSurface& surface) { |
| 1114 | staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); | 1107 | staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); |
| 1115 | surface->LoadBuffer(system.GPU().MemoryManager(), staging_cache); | 1108 | surface->LoadBuffer(gpu_memory, staging_cache); |
| 1116 | surface->UploadTexture(staging_cache.GetBuffer(0)); | 1109 | surface->UploadTexture(staging_cache.GetBuffer(0)); |
| 1117 | surface->MarkAsModified(false, Tick()); | 1110 | surface->MarkAsModified(false, Tick()); |
| 1118 | } | 1111 | } |
| @@ -1123,7 +1116,7 @@ private: | |||
| 1123 | } | 1116 | } |
| 1124 | staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); | 1117 | staging_cache.GetBuffer(0).resize(surface->GetHostSizeInBytes()); |
| 1125 | surface->DownloadTexture(staging_cache.GetBuffer(0)); | 1118 | surface->DownloadTexture(staging_cache.GetBuffer(0)); |
| 1126 | surface->FlushBuffer(system.GPU().MemoryManager(), staging_cache); | 1119 | surface->FlushBuffer(gpu_memory, staging_cache); |
| 1127 | surface->MarkAsModified(false, Tick()); | 1120 | surface->MarkAsModified(false, Tick()); |
| 1128 | } | 1121 | } |
| 1129 | 1122 | ||
| @@ -1253,6 +1246,8 @@ private: | |||
| 1253 | } | 1246 | } |
| 1254 | 1247 | ||
| 1255 | VideoCore::RasterizerInterface& rasterizer; | 1248 | VideoCore::RasterizerInterface& rasterizer; |
| 1249 | Tegra::Engines::Maxwell3D& maxwell3d; | ||
| 1250 | Tegra::MemoryManager& gpu_memory; | ||
| 1256 | 1251 | ||
| 1257 | FormatLookupTable format_lookup_table; | 1252 | FormatLookupTable format_lookup_table; |
| 1258 | FormatCompatibility format_compatibility; | 1253 | FormatCompatibility format_compatibility; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 4e3a092c7..a14df06a3 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -21,14 +21,17 @@ namespace { | |||
| 21 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer( | 21 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer( |
| 22 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, | 22 | Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu, |
| 23 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { | 23 | std::unique_ptr<Core::Frontend::GraphicsContext> context) { |
| 24 | auto& telemetry_session = system.TelemetrySession(); | ||
| 25 | auto& cpu_memory = system.Memory(); | ||
| 26 | |||
| 24 | switch (Settings::values.renderer_backend.GetValue()) { | 27 | switch (Settings::values.renderer_backend.GetValue()) { |
| 25 | case Settings::RendererBackend::OpenGL: | 28 | case Settings::RendererBackend::OpenGL: |
| 26 | return std::make_unique<OpenGL::RendererOpenGL>(system, emu_window, gpu, | 29 | return std::make_unique<OpenGL::RendererOpenGL>(telemetry_session, emu_window, cpu_memory, |
| 27 | std::move(context)); | 30 | gpu, std::move(context)); |
| 28 | #ifdef HAS_VULKAN | 31 | #ifdef HAS_VULKAN |
| 29 | case Settings::RendererBackend::Vulkan: | 32 | case Settings::RendererBackend::Vulkan: |
| 30 | return std::make_unique<Vulkan::RendererVulkan>(system, emu_window, gpu, | 33 | return std::make_unique<Vulkan::RendererVulkan>(telemetry_session, emu_window, cpu_memory, |
| 31 | std::move(context)); | 34 | gpu, std::move(context)); |
| 32 | #endif | 35 | #endif |
| 33 | default: | 36 | default: |
| 34 | return nullptr; | 37 | return nullptr; |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 21707e451..caa2d06d3 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include "common/scope_exit.h" | 30 | #include "common/scope_exit.h" |
| 31 | #include "core/core.h" | 31 | #include "core/core.h" |
| 32 | #include "core/frontend/framebuffer_layout.h" | 32 | #include "core/frontend/framebuffer_layout.h" |
| 33 | #include "core/hle/kernel/process.h" | ||
| 33 | #include "core/settings.h" | 34 | #include "core/settings.h" |
| 34 | #include "input_common/keyboard.h" | 35 | #include "input_common/keyboard.h" |
| 35 | #include "input_common/main.h" | 36 | #include "input_common/main.h" |
| @@ -63,7 +64,8 @@ void EmuThread::run() { | |||
| 63 | emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); | 64 | emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); |
| 64 | 65 | ||
| 65 | system.Renderer().Rasterizer().LoadDiskResources( | 66 | system.Renderer().Rasterizer().LoadDiskResources( |
| 66 | stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { | 67 | system.CurrentProcess()->GetTitleID(), stop_run, |
| 68 | [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { | ||
| 67 | emit LoadProgress(stage, value, total); | 69 | emit LoadProgress(stage, value, total); |
| 68 | }); | 70 | }); |
| 69 | 71 | ||
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 4f00c804d..e960b5413 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "core/file_sys/registered_cache.h" | 26 | #include "core/file_sys/registered_cache.h" |
| 27 | #include "core/file_sys/vfs_real.h" | 27 | #include "core/file_sys/vfs_real.h" |
| 28 | #include "core/gdbstub/gdbstub.h" | 28 | #include "core/gdbstub/gdbstub.h" |
| 29 | #include "core/hle/kernel/process.h" | ||
| 29 | #include "core/hle/service/filesystem/filesystem.h" | 30 | #include "core/hle/service/filesystem/filesystem.h" |
| 30 | #include "core/loader/loader.h" | 31 | #include "core/loader/loader.h" |
| 31 | #include "core/settings.h" | 32 | #include "core/settings.h" |
| @@ -235,7 +236,9 @@ int main(int argc, char** argv) { | |||
| 235 | // Core is loaded, start the GPU (makes the GPU contexts current to this thread) | 236 | // Core is loaded, start the GPU (makes the GPU contexts current to this thread) |
| 236 | system.GPU().Start(); | 237 | system.GPU().Start(); |
| 237 | 238 | ||
| 238 | system.Renderer().Rasterizer().LoadDiskResources(); | 239 | system.Renderer().Rasterizer().LoadDiskResources( |
| 240 | system.CurrentProcess()->GetTitleID(), false, | ||
| 241 | [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); | ||
| 239 | 242 | ||
| 240 | std::thread render_thread([&emu_window] { emu_window->Present(); }); | 243 | std::thread render_thread([&emu_window] { emu_window->Present(); }); |
| 241 | system.Run(); | 244 | system.Run(); |
diff --git a/src/yuzu_tester/yuzu.cpp b/src/yuzu_tester/yuzu.cpp index 7acf0caad..5798ce43a 100644 --- a/src/yuzu_tester/yuzu.cpp +++ b/src/yuzu_tester/yuzu.cpp | |||
| @@ -255,7 +255,6 @@ int main(int argc, char** argv) { | |||
| 255 | "SDLHideTester"); | 255 | "SDLHideTester"); |
| 256 | 256 | ||
| 257 | system.GPU().Start(); | 257 | system.GPU().Start(); |
| 258 | system.Renderer().Rasterizer().LoadDiskResources(); | ||
| 259 | 258 | ||
| 260 | system.Run(); | 259 | system.Run(); |
| 261 | while (!finished) { | 260 | while (!finished) { |