Commonise maxwell3d interconnect common code for use by other engines

The compute engine will require most of this for basic functionality.
This commit is contained in:
Billy Laws 2022-11-18 20:54:03 +00:00
parent 281838fde1
commit 7f93ec3df6
3 changed files with 114 additions and 74 deletions

View File

@ -6,7 +6,7 @@
#include <soc/gm20b/gmmu.h>
#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<u8> dstBuffer, size_t srcOffset) {
ContextLock lock{executor.tag, view};
view.Read(lock.IsFirstUsage(), FlushHostCallback, dstBuffer, srcOffset);
}
}

View File

@ -0,0 +1,102 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <common/dirty_tracking.h>
#include <vulkan/vulkan_raii.hpp>
#include <gpu/buffer.h>
#include <soc/gm20b/engines/engine.h>
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<u8> 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<u8> binary;
u64 hash;
u32 baseOffset;
};
struct ConstantBuffer {
BufferView view;
void Read(CommandExecutor &executor, span <u8> dstBuffer, size_t srcOffset);
template<typename T>
T Read(CommandExecutor &executor, size_t srcOffset) {
T object;
Read(executor, span<T>{object}.template cast<u8>(), srcOffset);
return object;
}
};
using DynamicBufferBinding = std::variant<BufferBinding, BufferView>;
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
class StateUpdateBuilder;
struct DescriptorUpdateInfo {
span<vk::CopyDescriptorSet> copies; //!< These will be performed before writes
span<vk::WriteDescriptorSet> writes;
span<vk::DescriptorBufferInfo> bufferDescs;
span<DynamicBufferBinding> bufferDescDynamicBindings;
vk::PipelineLayout pipelineLayout;
vk::DescriptorSetLayout descriptorSetLayout;
vk::PipelineBindPoint bindPoint;
u32 descriptorSetIndex;
};
}

View File

@ -3,81 +3,9 @@
#pragma once
#include <common/dirty_tracking.h>
#include <vulkan/vulkan_raii.hpp>
#include <soc/gm20b/engines/maxwell/types.h>
#include <gpu/buffer.h>
namespace skyline::kernel {
class MemoryManager;
}
namespace skyline::soc::gm20b {
struct ChannelContext;
}
namespace skyline::gpu::interconnect {
class CommandExecutor;
}
#include <gpu/interconnect/common/common.h>
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<u8> 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<BufferBinding, BufferView>;
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
class StateUpdateBuilder;
struct DescriptorUpdateInfo {
span<vk::CopyDescriptorSet> copies; //!< These will be performed before writes
span<vk::WriteDescriptorSet> writes;
span<vk::DescriptorBufferInfo> bufferDescs;
span<DynamicBufferBinding> bufferDescDynamicBindings;
vk::PipelineLayout pipelineLayout;
vk::DescriptorSetLayout descriptorSetLayout;
vk::PipelineBindPoint bindPoint;
u32 descriptorSetIndex;
};
}