From 7f93ec3df6ab0d296c5759bb90efedde65513e61 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Fri, 18 Nov 2022 20:54:03 +0000 Subject: [PATCH] Commonise maxwell3d interconnect common code for use by other engines The compute engine will require most of this for basic functionality. --- .../{maxwell_3d => common}/common.cpp | 12 ++- .../skyline/gpu/interconnect/common/common.h | 102 ++++++++++++++++++ .../gpu/interconnect/maxwell_3d/common.h | 74 +------------ 3 files changed, 114 insertions(+), 74 deletions(-) rename app/src/main/cpp/skyline/gpu/interconnect/{maxwell_3d => common}/common.cpp (80%) create mode 100644 app/src/main/cpp/skyline/gpu/interconnect/common/common.h diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.cpp b/app/src/main/cpp/skyline/gpu/interconnect/common/common.cpp similarity index 80% rename from app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.cpp rename to app/src/main/cpp/skyline/gpu/interconnect/common/common.cpp index 4c65cd97..b76c8fb7 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/common/common.cpp @@ -6,7 +6,7 @@ #include #include "common.h" -namespace skyline::gpu::interconnect::maxwell3d { +namespace skyline::gpu::interconnect { void CachedMappedBufferView::Update(InterconnectContext &ctx, u64 address, u64 size, bool splitMappingWarn) { // Ignore size for the mapping end check here as we don't support buffers split across multiple mappings so only the first one would be used anyway. It's also impossible for the mapping to have been remapped with a larger one since the original lookup because the we force the mapping to be reset after semaphores if (address < blockMappingStartAddr || address >= blockMappingEndAddr) { @@ -46,4 +46,14 @@ namespace skyline::gpu::interconnect::maxwell3d { view = {}; blockMappingEndAddr = 0; // Will force a retranslate of `blockMapping` on the next `Update()` call } + + static void FlushHostCallback() { + // TODO: here we should trigger `Execute()`, however that doesn't currently work due to Read being called mid-draw and attached objects not handling this case + Logger::Warn("GPU dirty buffer reads for attached buffers are unimplemented"); + } + + void ConstantBuffer::Read(CommandExecutor &executor, span dstBuffer, size_t srcOffset) { + ContextLock lock{executor.tag, view}; + view.Read(lock.IsFirstUsage(), FlushHostCallback, dstBuffer, srcOffset); + } } diff --git a/app/src/main/cpp/skyline/gpu/interconnect/common/common.h b/app/src/main/cpp/skyline/gpu/interconnect/common/common.h new file mode 100644 index 00000000..542b374e --- /dev/null +++ b/app/src/main/cpp/skyline/gpu/interconnect/common/common.h @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#pragma once + +#include +#include +#include +#include + +namespace skyline::kernel { + class MemoryManager; +} + +namespace skyline::soc::gm20b { + struct ChannelContext; +} + +namespace skyline::gpu::interconnect { + class CommandExecutor; +} + +namespace skyline::gpu::interconnect { + namespace engine_common = skyline::soc::gm20b::engine; + + /** + * @brief Holds GPU context for an interconnect instance + */ + struct InterconnectContext { + soc::gm20b::ChannelContext &channelCtx; + CommandExecutor &executor; + GPU &gpu; + nce::NCE &nce; + kernel::MemoryManager &memory; + }; + + /** + * @brief Helper around a buffer view that performs caching based on the underlying GPU mappings + */ + class CachedMappedBufferView { + private: + span blockMapping; //!< The underlying mapping that `view` is a part of + u64 blockMappingStartAddr; //!< The start GPU address of `blockMapping` + u64 blockMappingEndAddr; //!< The end GPU address of `blockMapping` + + public: + BufferView view; //!< The buffer view created as a result of a call to `Update()` + + /** + * @brief Updates `view` based on the supplied GPU mapping + */ + void Update(InterconnectContext &ctx, u64 address, u64 size, bool splitMappingWarn = true); + + /** + * @brief Purges the cached block mapping so the next `Update()` call will perform a full lookup + */ + void PurgeCaches(); + + BufferView &operator*() { + return view; + } + + BufferView *operator->() { + return &view; + } + }; + + struct ShaderBinary { + span binary; + u64 hash; + u32 baseOffset; + }; + + struct ConstantBuffer { + BufferView view; + + void Read(CommandExecutor &executor, span dstBuffer, size_t srcOffset); + + template + T Read(CommandExecutor &executor, size_t srcOffset) { + T object; + Read(executor, span{object}.template cast(), srcOffset); + return object; + } + }; + + using DynamicBufferBinding = std::variant; + using DirtyManager = dirty::Manager; + + class StateUpdateBuilder; + + struct DescriptorUpdateInfo { + span copies; //!< These will be performed before writes + span writes; + span bufferDescs; + span bufferDescDynamicBindings; + vk::PipelineLayout pipelineLayout; + vk::DescriptorSetLayout descriptorSetLayout; + vk::PipelineBindPoint bindPoint; + u32 descriptorSetIndex; + }; +} diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h index af9edd8c..36c95fb1 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h @@ -3,81 +3,9 @@ #pragma once -#include -#include #include -#include - -namespace skyline::kernel { - class MemoryManager; -} - -namespace skyline::soc::gm20b { - struct ChannelContext; -} - -namespace skyline::gpu::interconnect { - class CommandExecutor; -} +#include namespace skyline::gpu::interconnect::maxwell3d { namespace engine = skyline::soc::gm20b::engine::maxwell3d::type; - - /** - * @brief Holds GPU context for an interconnect instance - */ - struct InterconnectContext { - soc::gm20b::ChannelContext &channelCtx; - CommandExecutor &executor; - GPU &gpu; - nce::NCE &nce; - kernel::MemoryManager &memory; - }; - - /** - * @brief Helper around a buffer view that performs caching based on the underlying GPU mappings - */ - class CachedMappedBufferView { - private: - span blockMapping; //!< The underlying mapping that `view` is a part of - u64 blockMappingStartAddr; //!< The start GPU address of `blockMapping` - u64 blockMappingEndAddr; //!< The end GPU address of `blockMapping` - - public: - BufferView view; //!< The buffer view created as a result of a call to `Update()` - - /** - * @brief Updates `view` based on the supplied GPU mapping - */ - void Update(InterconnectContext &ctx, u64 address, u64 size, bool splitMappingWarn = true); - - /** - * @brief Purges the cached block mapping so the next `Update()` call will perform a full lookup - */ - void PurgeCaches(); - - BufferView &operator*() { - return view; - } - - BufferView *operator->() { - return &view; - } - }; - - using DynamicBufferBinding = std::variant; - using DirtyManager = dirty::Manager; - - class StateUpdateBuilder; - - struct DescriptorUpdateInfo { - span copies; //!< These will be performed before writes - span writes; - span bufferDescs; - span bufferDescDynamicBindings; - vk::PipelineLayout pipelineLayout; - vk::DescriptorSetLayout descriptorSetLayout; - vk::PipelineBindPoint bindPoint; - u32 descriptorSetIndex; - }; }