diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 7 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 8 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_query_cache.cpp | 5 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_query_cache.h | 4 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 41 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 28 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 11 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 11 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 4 |
10 files changed, 66 insertions, 63 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index 517ac14dd..ade72e1f9 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -47,11 +47,10 @@ constexpr std::array PROGRAM_LUT{ } // Anonymous namespace Buffer::Buffer(BufferCacheRuntime&, VideoCommon::NullBufferParams null_params) - : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(null_params) {} + : VideoCommon::BufferBase(null_params) {} -Buffer::Buffer(BufferCacheRuntime& runtime, VideoCore::RasterizerInterface& rasterizer_, - VAddr cpu_addr_, u64 size_bytes_) - : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(rasterizer_, cpu_addr_, size_bytes_) { +Buffer::Buffer(BufferCacheRuntime& runtime, DAddr cpu_addr_, u64 size_bytes_) + : VideoCommon::BufferBase(cpu_addr_, size_bytes_) { buffer.Create(); if (runtime.device.HasDebuggingToolAttached()) { const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr()); diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 2c18de166..af34c272b 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -10,7 +10,6 @@ #include "common/common_types.h" #include "video_core/buffer_cache/buffer_cache_base.h" #include "video_core/buffer_cache/memory_tracker_base.h" -#include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_device.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_staging_buffer_pool.h" @@ -19,10 +18,9 @@ namespace OpenGL { class BufferCacheRuntime; -class Buffer : public VideoCommon::BufferBase<VideoCore::RasterizerInterface> { +class Buffer : public VideoCommon::BufferBase { public: - explicit Buffer(BufferCacheRuntime&, VideoCore::RasterizerInterface& rasterizer, VAddr cpu_addr, - u64 size_bytes); + explicit Buffer(BufferCacheRuntime&, DAddr cpu_addr, u64 size_bytes); explicit Buffer(BufferCacheRuntime&, VideoCommon::NullBufferParams); void ImmediateUpload(size_t offset, std::span<const u8> data) noexcept; @@ -244,7 +242,7 @@ struct BufferCacheParams { using Runtime = OpenGL::BufferCacheRuntime; using Buffer = OpenGL::Buffer; using Async_Buffer = OpenGL::StagingBufferMap; - using MemoryTracker = VideoCommon::MemoryTrackerBase<VideoCore::RasterizerInterface>; + using MemoryTracker = VideoCommon::MemoryTrackerBase<Tegra::MaxwellDeviceMemoryManager>; static constexpr bool IS_OPENGL = true; static constexpr bool HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS = true; diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp index fef7360ed..2147d587f 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.cpp +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp @@ -35,8 +35,9 @@ constexpr GLenum GetTarget(VideoCore::QueryType type) { } // Anonymous namespace -QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_) - : QueryCacheLegacy(rasterizer_, cpu_memory_), gl_rasterizer{rasterizer_} { +QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, + Tegra::MaxwellDeviceMemoryManager& device_memory_) + : QueryCacheLegacy(rasterizer_, device_memory_), gl_rasterizer{rasterizer_} { EnableCounters(); } diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h index 0721e0b3d..38118f355 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.h +++ b/src/video_core/renderer_opengl/gl_query_cache.h @@ -8,6 +8,7 @@ #include <vector> #include "common/common_types.h" +#include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/query_cache.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_resource_manager.h" @@ -28,7 +29,8 @@ using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>; class QueryCache final : public VideoCommon::QueryCacheLegacy<QueryCache, CachedQuery, CounterStream, HostCounter> { public: - explicit QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_); + explicit QueryCache(RasterizerOpenGL& rasterizer_, + Tegra::MaxwellDeviceMemoryManager& device_memory_); ~QueryCache(); 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 7a5fad735..d5354ef2d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -70,18 +70,18 @@ std::optional<VideoCore::QueryType> MaxwellToVideoCoreQuery(VideoCommon::QueryTy } // Anonymous namespace RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, - Core::Memory::Memory& cpu_memory_, const Device& device_, - ScreenInfo& screen_info_, ProgramManager& program_manager_, - StateTracker& state_tracker_) - : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_), + Tegra::MaxwellDeviceMemoryManager& device_memory_, + const Device& device_, ScreenInfo& screen_info_, + ProgramManager& program_manager_, StateTracker& state_tracker_) + : gpu(gpu_), device_memory(device_memory_), device(device_), screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_), texture_cache_runtime(device, program_manager, state_tracker, staging_buffer_pool), - texture_cache(texture_cache_runtime, *this), + texture_cache(texture_cache_runtime, device_memory_), buffer_cache_runtime(device, staging_buffer_pool), - buffer_cache(*this, cpu_memory_, buffer_cache_runtime), - shader_cache(*this, emu_window_, device, texture_cache, buffer_cache, program_manager, - state_tracker, gpu.ShaderNotify()), - query_cache(*this, cpu_memory_), accelerate_dma(buffer_cache, texture_cache), + buffer_cache(device_memory_, buffer_cache_runtime), + shader_cache(device_memory_, emu_window_, device, texture_cache, buffer_cache, + program_manager, state_tracker, gpu.ShaderNotify()), + query_cache(*this, device_memory_), accelerate_dma(buffer_cache, texture_cache), fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache), blit_image(program_manager_) {} @@ -475,7 +475,7 @@ void RasterizerOpenGL::DisableGraphicsUniformBuffer(size_t stage, u32 index) { void RasterizerOpenGL::FlushAll() {} -void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { +void RasterizerOpenGL::FlushRegion(DAddr addr, u64 size, VideoCommon::CacheType which) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); if (addr == 0 || size == 0) { return; @@ -493,7 +493,7 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType } } -bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { +bool RasterizerOpenGL::MustFlushRegion(DAddr addr, u64 size, VideoCommon::CacheType which) { if ((True(which & VideoCommon::CacheType::BufferCache))) { std::scoped_lock lock{buffer_cache.mutex}; if (buffer_cache.IsRegionGpuModified(addr, size)) { @@ -510,7 +510,7 @@ bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheT return false; } -VideoCore::RasterizerDownloadArea RasterizerOpenGL::GetFlushArea(VAddr addr, u64 size) { +VideoCore::RasterizerDownloadArea RasterizerOpenGL::GetFlushArea(DAddr addr, u64 size) { { std::scoped_lock lock{texture_cache.mutex}; auto area = texture_cache.GetFlushArea(addr, size); @@ -526,14 +526,14 @@ VideoCore::RasterizerDownloadArea RasterizerOpenGL::GetFlushArea(VAddr addr, u64 } } VideoCore::RasterizerDownloadArea new_area{ - .start_address = Common::AlignDown(addr, Core::Memory::YUZU_PAGESIZE), - .end_address = Common::AlignUp(addr + size, Core::Memory::YUZU_PAGESIZE), + .start_address = Common::AlignDown(addr, Core::DEVICE_PAGESIZE), + .end_address = Common::AlignUp(addr + size, Core::DEVICE_PAGESIZE), .preemtive = true, }; return new_area; } -void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { +void RasterizerOpenGL::InvalidateRegion(DAddr addr, u64 size, VideoCommon::CacheType which) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); if (addr == 0 || size == 0) { return; @@ -554,7 +554,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size, VideoCommon::Cache } } -bool RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { +bool RasterizerOpenGL::OnCPUWrite(DAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); if (addr == 0 || size == 0) { return false; @@ -576,8 +576,9 @@ bool RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { return false; } -void RasterizerOpenGL::OnCacheInvalidation(VAddr addr, u64 size) { +void RasterizerOpenGL::OnCacheInvalidation(DAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); + if (addr == 0 || size == 0) { return; } @@ -596,7 +597,7 @@ void RasterizerOpenGL::InvalidateGPUCache() { gpu.InvalidateGPUCache(); } -void RasterizerOpenGL::UnmapMemory(VAddr addr, u64 size) { +void RasterizerOpenGL::UnmapMemory(DAddr addr, u64 size) { { std::scoped_lock lock{texture_cache.mutex}; texture_cache.UnmapMemory(addr, size); @@ -635,7 +636,7 @@ void RasterizerOpenGL::ReleaseFences(bool force) { fence_manager.WaitPendingFences(force); } -void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size, +void RasterizerOpenGL::FlushAndInvalidateRegion(DAddr addr, u64 size, VideoCommon::CacheType which) { if (Settings::IsGPULevelExtreme()) { FlushRegion(addr, size, which); @@ -739,7 +740,7 @@ void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_si } bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, - VAddr framebuffer_addr, u32 pixel_stride) { + DAddr framebuffer_addr, u32 pixel_stride) { if (framebuffer_addr == 0) { return false; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index ce3460938..34aa73526 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -14,7 +14,6 @@ #include "common/common_types.h" #include "video_core/control/channel_state_cache.h" #include "video_core/engines/maxwell_dma.h" -#include "video_core/rasterizer_accelerated.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/blit_image.h" #include "video_core/renderer_opengl/gl_buffer_cache.h" @@ -72,13 +71,13 @@ private: TextureCache& texture_cache; }; -class RasterizerOpenGL : public VideoCore::RasterizerAccelerated, +class RasterizerOpenGL : public VideoCore::RasterizerInterface, protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> { public: explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, - Core::Memory::Memory& cpu_memory_, const Device& device_, - ScreenInfo& screen_info_, ProgramManager& program_manager_, - StateTracker& state_tracker_); + Tegra::MaxwellDeviceMemoryManager& device_memory_, + const Device& device_, ScreenInfo& screen_info_, + ProgramManager& program_manager_, StateTracker& state_tracker_); ~RasterizerOpenGL() override; void Draw(bool is_indexed, u32 instance_count) override; @@ -92,17 +91,17 @@ public: void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override; void DisableGraphicsUniformBuffer(size_t stage, u32 index) override; void FlushAll() override; - void FlushRegion(VAddr addr, u64 size, + void FlushRegion(DAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; - bool MustFlushRegion(VAddr addr, u64 size, + bool MustFlushRegion(DAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; - VideoCore::RasterizerDownloadArea GetFlushArea(VAddr addr, u64 size) override; - void InvalidateRegion(VAddr addr, u64 size, + VideoCore::RasterizerDownloadArea GetFlushArea(PAddr addr, u64 size) override; + void InvalidateRegion(DAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; - void OnCacheInvalidation(VAddr addr, u64 size) override; - bool OnCPUWrite(VAddr addr, u64 size) override; + void OnCacheInvalidation(PAddr addr, u64 size) override; + bool OnCPUWrite(PAddr addr, u64 size) override; void InvalidateGPUCache() override; - void UnmapMemory(VAddr addr, u64 size) override; + void UnmapMemory(DAddr addr, u64 size) override; void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override; void SignalFence(std::function<void()>&& func) override; void SyncOperation(std::function<void()>&& func) override; @@ -110,7 +109,7 @@ public: void SignalReference() override; void ReleaseFences(bool force = true) override; void FlushAndInvalidateRegion( - VAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; + DAddr addr, u64 size, VideoCommon::CacheType which = VideoCommon::CacheType::All) override; void WaitForIdle() override; void FragmentBarrier() override; void TiledCacheBarrier() override; @@ -123,7 +122,7 @@ public: Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, std::span<const u8> memory) override; - bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, + bool AccelerateDisplay(const Tegra::FramebufferConfig& config, DAddr framebuffer_addr, u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, const VideoCore::DiskResourceLoadCallback& callback) override; @@ -235,6 +234,7 @@ private: VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport); Tegra::GPU& gpu; + Tegra::MaxwellDeviceMemoryManager& device_memory; const Device& device; ScreenInfo& screen_info; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 30df41b7d..50462cdde 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -168,11 +168,12 @@ void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs } } // Anonymous namespace -ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, - const Device& device_, TextureCache& texture_cache_, - BufferCache& buffer_cache_, ProgramManager& program_manager_, - StateTracker& state_tracker_, VideoCore::ShaderNotify& shader_notify_) - : VideoCommon::ShaderCache{rasterizer_}, emu_window{emu_window_}, device{device_}, +ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, + Core::Frontend::EmuWindow& emu_window_, const Device& device_, + TextureCache& texture_cache_, BufferCache& buffer_cache_, + ProgramManager& program_manager_, StateTracker& state_tracker_, + VideoCore::ShaderNotify& shader_notify_) + : VideoCommon::ShaderCache{device_memory_}, emu_window{emu_window_}, device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{state_tracker_}, shader_notify{shader_notify_}, use_asynchronous_shaders{device.UseAsynchronousShaders()}, diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 6b9732fca..5ac413529 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -17,7 +17,7 @@ namespace Tegra { class MemoryManager; -} +} // namespace Tegra namespace OpenGL { @@ -28,10 +28,11 @@ using ShaderWorker = Common::StatefulThreadWorker<ShaderContext::Context>; class ShaderCache : public VideoCommon::ShaderCache { public: - explicit ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_, - const Device& device_, TextureCache& texture_cache_, - BufferCache& buffer_cache_, ProgramManager& program_manager_, - StateTracker& state_tracker_, VideoCore::ShaderNotify& shader_notify_); + explicit ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, + Core::Frontend::EmuWindow& emu_window_, const Device& device_, + TextureCache& texture_cache_, BufferCache& buffer_cache_, + ProgramManager& program_manager_, StateTracker& state_tracker_, + VideoCore::ShaderNotify& shader_notify_); ~ShaderCache(); void LoadDiskResources(u64 title_id, std::stop_token stop_loading, diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 2933718b6..b75376fdb 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -15,7 +15,6 @@ #include "common/telemetry.h" #include "core/core_timing.h" #include "core/frontend/emu_window.h" -#include "core/memory.h" #include "core/telemetry_session.h" #include "video_core/host_shaders/ffx_a_h.h" #include "video_core/host_shaders/ffx_fsr1_h.h" @@ -144,12 +143,13 @@ void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severit RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_, Core::Frontend::EmuWindow& emu_window_, - Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, + Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_, std::unique_ptr<Core::Frontend::GraphicsContext> context_) : RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_}, - emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, device{emu_window_}, + emu_window{emu_window_}, device_memory{device_memory_}, gpu{gpu_}, device{emu_window_}, state_tracker{}, program_manager{device}, - rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) { + rasterizer(emu_window, gpu, device_memory, device, screen_info, program_manager, + state_tracker) { if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) { glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); @@ -242,7 +242,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf const u32 bytes_per_pixel{VideoCore::Surface::BytesPerBlock(pixel_format)}; const u64 size_in_bytes{Tegra::Texture::CalculateSize( true, bytes_per_pixel, framebuffer.stride, framebuffer.height, 1, block_height_log2, 0)}; - const u8* const host_ptr{cpu_memory.GetPointer(framebuffer_addr)}; + const u8* const host_ptr{device_memory.GetPointer<u8>(framebuffer_addr)}; const std::span<const u8> input_data(host_ptr, size_in_bytes); Tegra::Texture::UnswizzleTexture(gl_framebuffer_data, input_data, bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index b70607635..18699610a 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -61,7 +61,7 @@ class RendererOpenGL final : public VideoCore::RendererBase { public: explicit RendererOpenGL(Core::TelemetrySession& telemetry_session_, Core::Frontend::EmuWindow& emu_window_, - Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, + Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_, std::unique_ptr<Core::Frontend::GraphicsContext> context_); ~RendererOpenGL() override; @@ -101,7 +101,7 @@ private: Core::TelemetrySession& telemetry_session; Core::Frontend::EmuWindow& emu_window; - Core::Memory::Memory& cpu_memory; + Tegra::MaxwellDeviceMemoryManager& device_memory; Tegra::GPU& gpu; Device device; |